# 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 */