# factory.hpp

Go to the documentation of this file.

    00001 /* $Id: factory.hpp 26215 2014-01-03 08:29:07Z rubidium $ */
    00002
    00003 /*
    00004  * This file is part of OpenTTD.
    00005  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
    00006  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    00007  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
    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 /* defined(WITH_COCOA) */
    00024
    00028 class BlitterFactory {
    00029 private:
    00030   const char *name;
    00031   const char *description;
    00032
    00033   typedef std::map<const char *, BlitterFactory *, StringCompare> Blitters;
    00034
    00039   static Blitters &GetBlitters()
    00040   {
    00041     static Blitters &s_blitters = *new Blitters();
    00042     return s_blitters;
    00043   }
    00044
    00049   static Blitter **GetActiveBlitter()
    00050   {
    00051     static Blitter *s_blitter = NULL;
    00052     return &s_blitter;
    00053   }
    00054
    00055 protected:
    00065   BlitterFactory(const char *name, const char *description, bool usable = true) :
    00066       name(strdup(name)), description(strdup(description))
    00067   {
    00068     if (usable) {
    00069       /*
    00070        * Only add when the blitter is usable. Do not bail out or
    00071        * do more special things since the blitters are always
    00072        * instantiated upon start anyhow and freed upon shutdown.
    00073        */
    00074       std::pair<Blitters::iterator, bool> P = GetBlitters().insert(Blitters::value_type(this->name, this));
    00075       assert(P.second);
    00076     } else {
    00077       DEBUG(driver, 1, "Not registering blitter %s as it is not usable", name);
    00078     }
    00079   }
    00080
    00081 public:
    00082   virtual ~BlitterFactory()
    00083   {
    00084     GetBlitters().erase(this->name);
    00085     if (GetBlitters().empty()) delete &GetBlitters();
    00086
    00087     free(this->name);
    00088     free(this->description);
    00089   }
    00090
    00096   static Blitter *SelectBlitter(const char *name)
    00097   {
    00098     BlitterFactory *b = GetBlitterFactory(name);
    00099     if (b == NULL) return NULL;
    00100
    00101     Blitter *newb = b->CreateInstance();
    00102     delete *GetActiveBlitter();
    00103     *GetActiveBlitter() = newb;
    00104
    00105     DEBUG(driver, 1, "Successfully %s blitter '%s'", StrEmpty(name) ? "probed" : "loaded", newb->GetName());
    00106     return newb;
    00107   }
    00108
    00114   static BlitterFactory *GetBlitterFactory(const char *name)
    00115   {
    00116 #if defined(DEDICATED)
    00117     const char *default_blitter = "null";
    00118 #else
    00119     const char *default_blitter = "8bpp-optimized";
    00120
    00121 #if defined(WITH_COCOA)
    00122     /* Some people reported lack of fullscreen support in 8 bpp mode.
    00123      * While we prefer 8 bpp since it's faster, we will still have to test for support. */
    00124     if (!QZ_CanDisplay8bpp()) {
    00125       /* The main display can't go to 8 bpp fullscreen mode.
    00126        * We will have to switch to 32 bpp by default. */
    00127       default_blitter = "32bpp-anim";
    00128     }
    00129 #endif /* defined(WITH_COCOA) */
    00130 #endif /* defined(DEDICATED) */
    00131     if (GetBlitters().size() == 0) return NULL;
    00132     const char *bname = (StrEmpty(name)) ? default_blitter : name;
    00133
    00134     Blitters::iterator it = GetBlitters().begin();
    00135     for (; it != GetBlitters().end(); it++) {
    00136       BlitterFactory *b = (*it).second;
    00137       if (strcasecmp(bname, b->name) == 0) {
    00138         return b;
    00139       }
    00140     }
    00141     return NULL;
    00142   }
    00143
    00147   static Blitter *GetCurrentBlitter()
    00148   {
    00149     return *GetActiveBlitter();
    00150   }
    00151
    00158   static char *GetBlittersInfo(char *p, const char *last)
    00159   {
    00160     p += seprintf(p, last, "List of blitters:\n");
    00161     Blitters::iterator it = GetBlitters().begin();
    00162     for (; it != GetBlitters().end(); it++) {
    00163       BlitterFactory *b = (*it).second;
    00164       p += seprintf(p, last, "%18s: %s\n", b->name, b->GetDescription());
    00165     }
    00166     p += seprintf(p, last, "\n");
    00167
    00168     return p;
    00169   }
    00170
    00174   const char *GetName() const
    00175   {
    00176     return this->name;
    00177   }
    00178
    00182   const char *GetDescription() const
    00183   {
    00184     return this->description;
    00185   }
    00186
    00190   virtual Blitter *CreateInstance() = 0;
    00191 };
    00192
    00193 extern char *_ini_blitter;
    00194 extern bool _blitter_autodetected;
    00195
    00196 #endif /* BLITTER_FACTORY_HPP */