OpenTTD
factory.hpp
Go to the documentation of this file.
1 /* $Id: factory.hpp 26509 2014-04-25 15:40:32Z rubidium $ */
2 
3 /*
4  * This file is part of OpenTTD.
5  * 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.
6  * 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.
7  * 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/>.
8  */
9 
12 #ifndef BLITTER_FACTORY_HPP
13 #define BLITTER_FACTORY_HPP
14 
15 #include "base.hpp"
16 #include "../debug.h"
17 #include "../string_func.h"
18 #include "../core/string_compare_type.hpp"
19 #include <map>
20 
21 #if defined(WITH_COCOA)
22 bool QZ_CanDisplay8bpp();
23 #endif /* defined(WITH_COCOA) */
24 
29 private:
30  const char *name;
31  const char *description;
32 
33  typedef std::map<const char *, BlitterFactory *, StringCompare> Blitters;
34 
39  static Blitters &GetBlitters()
40  {
41  static Blitters &s_blitters = *new Blitters();
42  return s_blitters;
43  }
44 
50  {
51  static Blitter *s_blitter = NULL;
52  return &s_blitter;
53  }
54 
55 protected:
65  BlitterFactory(const char *name, const char *description, bool usable = true) :
66  name(stredup(name)), description(stredup(description))
67  {
68  if (usable) {
69  /*
70  * Only add when the blitter is usable. Do not bail out or
71  * do more special things since the blitters are always
72  * instantiated upon start anyhow and freed upon shutdown.
73  */
74  std::pair<Blitters::iterator, bool> P = GetBlitters().insert(Blitters::value_type(this->name, this));
75  assert(P.second);
76  } else {
77  DEBUG(driver, 1, "Not registering blitter %s as it is not usable", name);
78  }
79  }
80 
81 public:
82  virtual ~BlitterFactory()
83  {
84  GetBlitters().erase(this->name);
85  if (GetBlitters().empty()) delete &GetBlitters();
86 
87  free(this->name);
88  free(this->description);
89  }
90 
96  static Blitter *SelectBlitter(const char *name)
97  {
99  if (b == NULL) return NULL;
100 
101  Blitter *newb = b->CreateInstance();
102  delete *GetActiveBlitter();
103  *GetActiveBlitter() = newb;
104 
105  DEBUG(driver, 1, "Successfully %s blitter '%s'", StrEmpty(name) ? "probed" : "loaded", newb->GetName());
106  return newb;
107  }
108 
114  static BlitterFactory *GetBlitterFactory(const char *name)
115  {
116 #if defined(DEDICATED)
117  const char *default_blitter = "null";
118 #else
119  const char *default_blitter = "8bpp-optimized";
120 
121 #if defined(WITH_COCOA)
122  /* Some people reported lack of fullscreen support in 8 bpp mode.
123  * While we prefer 8 bpp since it's faster, we will still have to test for support. */
124  if (!QZ_CanDisplay8bpp()) {
125  /* The main display can't go to 8 bpp fullscreen mode.
126  * We will have to switch to 32 bpp by default. */
127  default_blitter = "32bpp-anim";
128  }
129 #endif /* defined(WITH_COCOA) */
130 #endif /* defined(DEDICATED) */
131  if (GetBlitters().size() == 0) return NULL;
132  const char *bname = (StrEmpty(name)) ? default_blitter : name;
133 
134  Blitters::iterator it = GetBlitters().begin();
135  for (; it != GetBlitters().end(); it++) {
136  BlitterFactory *b = (*it).second;
137  if (strcasecmp(bname, b->name) == 0) {
138  return b;
139  }
140  }
141  return NULL;
142  }
143 
148  {
149  return *GetActiveBlitter();
150  }
151 
158  static char *GetBlittersInfo(char *p, const char *last)
159  {
160  p += seprintf(p, last, "List of blitters:\n");
161  Blitters::iterator it = GetBlitters().begin();
162  for (; it != GetBlitters().end(); it++) {
163  BlitterFactory *b = (*it).second;
164  p += seprintf(p, last, "%18s: %s\n", b->name, b->GetDescription());
165  }
166  p += seprintf(p, last, "\n");
167 
168  return p;
169  }
170 
174  const char *GetName() const
175  {
176  return this->name;
177  }
178 
182  const char *GetDescription() const
183  {
184  return this->description;
185  }
186 
190  virtual Blitter *CreateInstance() = 0;
191 };
192 
193 extern char *_ini_blitter;
194 extern bool _blitter_autodetected;
195 
196 #endif /* BLITTER_FACTORY_HPP */
bool _blitter_autodetected
Was the blitter autodetected or specified by the user?
Definition: driver.cpp:32
int CDECL seprintf(char *str, const char *last, const char *format,...)
Safer implementation of snprintf; same as snprintf except:
Definition: string.cpp:398
const char * GetName() const
Get the long, human readable, name for the Blitter-class.
Definition: factory.hpp:174
virtual Blitter * CreateInstance()=0
Create an instance of this Blitter-class.
How all blitters should look like.
Definition: base.hpp:30
const char * GetDescription() const
Get a nice description of the blitter-class.
Definition: factory.hpp:182
virtual const char * GetName()=0
Get the name of the blitter, the same as the Factory-instance returns.
static char * GetBlittersInfo(char *p, const char *last)
Fill a buffer with information about the blitters.
Definition: factory.hpp:158
char * _ini_blitter
The blitter as stored in the configuration file.
Definition: driver.cpp:31
BlitterFactory(const char *name, const char *description, bool usable=true)
Construct the blitter, and register it.
Definition: factory.hpp:65
static Blitter * SelectBlitter(const char *name)
Find the requested blitter and return his class.
Definition: factory.hpp:96
char * stredup(const char *s, const char *last)
Create a duplicate of the given string.
Definition: string.cpp:126
Base for all blitters.
std::map< const char *, BlitterFactory *, StringCompare > Blitters
Map of blitter factories.
Definition: factory.hpp:33
static Blitter * GetCurrentBlitter()
Get the current active blitter (always set by calling SelectBlitter).
Definition: factory.hpp:147
const char * description
The description of the blitter.
Definition: factory.hpp:31
#define DEBUG(name, level,...)
Output a line of debugging information.
Definition: debug.h:39
static bool StrEmpty(const char *s)
Check if a string buffer is empty.
Definition: string_func.h:59
static Blitter ** GetActiveBlitter()
Get the currently active blitter.
Definition: factory.hpp:49
static void free(const void *ptr)
Version of the standard free that accepts const pointers.
Definition: depend.cpp:114
static BlitterFactory * GetBlitterFactory(const char *name)
Get the blitter factory with the given name.
Definition: factory.hpp:114
The base factory, keeping track of all blitters.
Definition: factory.hpp:28
const char * name
The name of the blitter factory.
Definition: factory.hpp:30
static Blitters & GetBlitters()
Get the map with currently known blitters.
Definition: factory.hpp:39