factory.hpp
00001
00002
00003 #ifndef BLITTER_FACTORY_HPP
00004 #define BLITTER_FACTORY_HPP
00005
00006 #include "base.hpp"
00007 #include "../debug.h"
00008 #include "../string_func.h"
00009 #include <string>
00010 #include <map>
00011
00012 #if defined(WITH_COCOA)
00013 bool QZ_CanDisplay8bpp();
00014 #endif
00015
00019 class BlitterFactoryBase {
00020 private:
00021 char *name;
00022 typedef std::map<std::string, BlitterFactoryBase *> Blitters;
00023
00024 static Blitters &GetBlitters()
00025 {
00026 static Blitters &s_blitters = *new Blitters();
00027 return s_blitters;
00028 }
00029
00030 static Blitter **GetActiveBlitter()
00031 {
00032 static Blitter *s_blitter = NULL;
00033 return &s_blitter;
00034 }
00035
00036 protected:
00042 void RegisterBlitter(const char *name)
00043 {
00044
00045 if (name == NULL) return;
00046
00047 this->name = strdup(name);
00048 #if !defined(NDEBUG) || defined(WITH_ASSERT)
00049
00050 std::pair<Blitters::iterator, bool> P =
00051 #endif
00052 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() { if (this->name != NULL) GetBlitters().erase(this->name); free(this->name); }
00062
00068 static Blitter *SelectBlitter(const char *name)
00069 {
00070 const char *default_blitter = "8bpp-optimized";
00071
00072 #if defined(WITH_COCOA)
00073
00074
00075 if (!QZ_CanDisplay8bpp()) {
00076
00077
00078 default_blitter = "32bpp-anim";
00079 }
00080 #endif
00081 if (GetBlitters().size() == 0) return NULL;
00082 const char *bname = (StrEmpty(name)) ? default_blitter : name;
00083
00084 Blitters::iterator it = GetBlitters().begin();
00085 for (; it != GetBlitters().end(); it++) {
00086 BlitterFactoryBase *b = (*it).second;
00087 if (strcasecmp(bname, b->name) == 0) {
00088 Blitter *newb = b->CreateInstance();
00089 delete *GetActiveBlitter();
00090 *GetActiveBlitter() = newb;
00091
00092 DEBUG(driver, 1, "Successfully %s blitter '%s'",StrEmpty(name) ? "probed" : "loaded", bname);
00093 return newb;
00094 }
00095 }
00096 return NULL;
00097 }
00098
00102 static Blitter *GetCurrentBlitter()
00103 {
00104 return *GetActiveBlitter();
00105 }
00106
00107
00108 static char *GetBlittersInfo(char *p, const char *last)
00109 {
00110 p += snprintf(p, last - p, "List of blitters:\n");
00111 Blitters::iterator it = GetBlitters().begin();
00112 for (; it != GetBlitters().end(); it++) {
00113 BlitterFactoryBase *b = (*it).second;
00114 p += snprintf(p, last - p, "%18s: %s\n", b->name, b->GetDescription());
00115 }
00116 p += snprintf(p, last - p, "\n");
00117
00118 return p;
00119 }
00120
00124 virtual const char *GetDescription() = 0;
00125
00129 virtual Blitter *CreateInstance() = 0;
00130 };
00131
00135 template <class T>
00136 class BlitterFactory: public BlitterFactoryBase {
00137 public:
00138 BlitterFactory() { this->RegisterBlitter(((T *)this)->GetName()); }
00139
00143 const char *GetName();
00144 };
00145
00146 extern char _ini_blitter[32];
00147
00148 #endif