factory.hpp
Go to the documentation of this file.00001
00002
00005 #ifndef BLITTER_FACTORY_HPP
00006 #define BLITTER_FACTORY_HPP
00007
00008 #include "base.hpp"
00009 #include "../debug.h"
00010 #include "../string_func.h"
00011 #include <map>
00012
00013 #if defined(WITH_COCOA)
00014 bool QZ_CanDisplay8bpp();
00015 #endif
00016
00020 class BlitterFactoryBase {
00021 private:
00022 const char *name;
00023
00024 struct StringCompare {
00025 bool operator () (const char *a, const char *b) const
00026 {
00027 return strcmp(a, b) < 0;
00028 }
00029 };
00030
00031 typedef std::map<const char *, BlitterFactoryBase *, StringCompare> Blitters;
00032
00033 static Blitters &GetBlitters()
00034 {
00035 static Blitters &s_blitters = *new Blitters();
00036 return s_blitters;
00037 }
00038
00039 static Blitter **GetActiveBlitter()
00040 {
00041 static Blitter *s_blitter = NULL;
00042 return &s_blitter;
00043 }
00044
00045 protected:
00051 void RegisterBlitter(const char *name)
00052 {
00053
00054 if (name == NULL) return;
00055
00056 this->name = strdup(name);
00057
00058 std::pair<Blitters::iterator, bool> P = GetBlitters().insert(Blitters::value_type(name, this));
00059 assert(P.second);
00060 }
00061
00062 public:
00063 BlitterFactoryBase() :
00064 name(NULL)
00065 {}
00066
00067 virtual ~BlitterFactoryBase()
00068 {
00069 if (this->name == NULL) return;
00070 GetBlitters().erase(this->name);
00071 if (GetBlitters().empty()) delete &GetBlitters();
00072 free((void *)this->name);
00073 }
00074
00080 static Blitter *SelectBlitter(const char *name)
00081 {
00082 const char *default_blitter = "8bpp-optimized";
00083
00084 #if defined(WITH_COCOA)
00085
00086
00087 if (!QZ_CanDisplay8bpp()) {
00088
00089
00090 default_blitter = "32bpp-anim";
00091 }
00092 #endif
00093 if (GetBlitters().size() == 0) return NULL;
00094 const char *bname = (StrEmpty(name)) ? default_blitter : name;
00095
00096 Blitters::iterator it = GetBlitters().begin();
00097 for (; it != GetBlitters().end(); it++) {
00098 BlitterFactoryBase *b = (*it).second;
00099 if (strcasecmp(bname, b->name) == 0) {
00100 Blitter *newb = b->CreateInstance();
00101 delete *GetActiveBlitter();
00102 *GetActiveBlitter() = newb;
00103
00104 DEBUG(driver, 1, "Successfully %s blitter '%s'",StrEmpty(name) ? "probed" : "loaded", bname);
00105 return newb;
00106 }
00107 }
00108 return NULL;
00109 }
00110
00114 static Blitter *GetCurrentBlitter()
00115 {
00116 return *GetActiveBlitter();
00117 }
00118
00119
00120 static char *GetBlittersInfo(char *p, const char *last)
00121 {
00122 p += seprintf(p, last, "List of blitters:\n");
00123 Blitters::iterator it = GetBlitters().begin();
00124 for (; it != GetBlitters().end(); it++) {
00125 BlitterFactoryBase *b = (*it).second;
00126 p += seprintf(p, last, "%18s: %s\n", b->name, b->GetDescription());
00127 }
00128 p += seprintf(p, last, "\n");
00129
00130 return p;
00131 }
00132
00136 virtual const char *GetDescription() = 0;
00137
00141 virtual Blitter *CreateInstance() = 0;
00142 };
00143
00147 template <class T>
00148 class BlitterFactory: public BlitterFactoryBase {
00149 public:
00150 BlitterFactory() { this->RegisterBlitter(((T *)this)->GetName()); }
00151
00155 const char *GetName();
00156 };
00157
00158 extern char _ini_blitter[32];
00159
00160 #endif