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