factory.hpp

Go to the documentation of this file.
00001 /* $Id: factory.hpp 14540 2008-10-28 14:42:31Z rubidium $ */
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 /* defined(WITH_COCOA) */
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     /* Don't register nameless Blitters */
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     /* Some people reported lack of fullscreen support in 8 bpp mode.
00086      * While we prefer 8 bpp since it's faster, we will still have to test for support. */
00087     if (!QZ_CanDisplay8bpp()) {
00088       /* The main display can't go to 8 bpp fullscreen mode.
00089        * We will have to switch to 32 bpp by default. */
00090       default_blitter = "32bpp-anim";
00091     }
00092 #endif /* defined(WITH_COCOA) */
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 /* BLITTER_FACTORY_HPP */

Generated on Fri Nov 21 19:01:31 2008 for openttd by  doxygen 1.5.6