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 "../core/string_compare_type.hpp"
00012 #include <map>
00013
00014 #if defined(WITH_COCOA)
00015 bool QZ_CanDisplay8bpp();
00016 #endif
00017
00021 class BlitterFactoryBase {
00022 private:
00023 const char *name;
00024
00025 typedef std::map<const char *, BlitterFactoryBase *, StringCompare> Blitters;
00026
00027 static Blitters &GetBlitters()
00028 {
00029 static Blitters &s_blitters = *new Blitters();
00030 return s_blitters;
00031 }
00032
00033 static Blitter **GetActiveBlitter()
00034 {
00035 static Blitter *s_blitter = NULL;
00036 return &s_blitter;
00037 }
00038
00039 protected:
00045 void RegisterBlitter(const char *name)
00046 {
00047
00048 if (name == NULL) return;
00049
00050 this->name = strdup(name);
00051
00052 std::pair<Blitters::iterator, bool> P = GetBlitters().insert(Blitters::value_type(name, this));
00053 assert(P.second);
00054 }
00055
00056 public:
00057 BlitterFactoryBase() :
00058 name(NULL)
00059 {}
00060
00061 virtual ~BlitterFactoryBase()
00062 {
00063 if (this->name == NULL) return;
00064 GetBlitters().erase(this->name);
00065 if (GetBlitters().empty()) delete &GetBlitters();
00066 free((void *)this->name);
00067 }
00068
00074 static Blitter *SelectBlitter(const char *name)
00075 {
00076 #if defined(DEDICATED)
00077 const char *default_blitter = "null";
00078 #else
00079 const char *default_blitter = "8bpp-optimized";
00080
00081 #if defined(WITH_COCOA)
00082
00083
00084 if (!QZ_CanDisplay8bpp()) {
00085
00086
00087 default_blitter = "32bpp-anim";
00088 }
00089 #endif
00090 #endif
00091 if (GetBlitters().size() == 0) return NULL;
00092 const char *bname = (StrEmpty(name)) ? default_blitter : name;
00093
00094 Blitters::iterator it = GetBlitters().begin();
00095 for (; it != GetBlitters().end(); it++) {
00096 BlitterFactoryBase *b = (*it).second;
00097 if (strcasecmp(bname, b->name) == 0) {
00098 Blitter *newb = b->CreateInstance();
00099 delete *GetActiveBlitter();
00100 *GetActiveBlitter() = newb;
00101
00102 DEBUG(driver, 1, "Successfully %s blitter '%s'",StrEmpty(name) ? "probed" : "loaded", bname);
00103 return newb;
00104 }
00105 }
00106 return NULL;
00107 }
00108
00112 static Blitter *GetCurrentBlitter()
00113 {
00114 return *GetActiveBlitter();
00115 }
00116
00117
00118 static char *GetBlittersInfo(char *p, const char *last)
00119 {
00120 p += seprintf(p, last, "List of blitters:\n");
00121 Blitters::iterator it = GetBlitters().begin();
00122 for (; it != GetBlitters().end(); it++) {
00123 BlitterFactoryBase *b = (*it).second;
00124 p += seprintf(p, last, "%18s: %s\n", b->name, b->GetDescription());
00125 }
00126 p += seprintf(p, last, "\n");
00127
00128 return p;
00129 }
00130
00134 virtual const char *GetDescription() = 0;
00135
00139 virtual Blitter *CreateInstance() = 0;
00140 };
00141
00145 template <class T>
00146 class BlitterFactory: public BlitterFactoryBase {
00147 public:
00148 BlitterFactory() { this->RegisterBlitter(((T *)this)->GetName()); }
00149
00153 const char *GetName();
00154 };
00155
00156 extern char *_ini_blitter;
00157
00158 #endif