factory.hpp

Go to the documentation of this file.
00001 /* $Id: factory.hpp 15324 2009-02-03 18:08:07Z smatz $ */
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 /* defined(WITH_COCOA) */
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     /* Don't register nameless Blitters */
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     /* Some people reported lack of fullscreen support in 8 bpp mode.
00083      * While we prefer 8 bpp since it's faster, we will still have to test for support. */
00084     if (!QZ_CanDisplay8bpp()) {
00085       /* The main display can't go to 8 bpp fullscreen mode.
00086        * We will have to switch to 32 bpp by default. */
00087       default_blitter = "32bpp-anim";
00088     }
00089 #endif /* defined(WITH_COCOA) */
00090 #endif /* defined(DEDICATED) */
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 /* BLITTER_FACTORY_HPP */

Generated on Sun Nov 15 15:40:10 2009 for OpenTTD by  doxygen 1.5.6