OpenTTD Source  20240917-master-g9ab0a47812
factory.hpp
Go to the documentation of this file.
1 /*
2  * This file is part of OpenTTD.
3  * 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.
4  * 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.
5  * 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/>.
6  */
7 
10 #ifndef BLITTER_FACTORY_HPP
11 #define BLITTER_FACTORY_HPP
12 
13 #include "base.hpp"
14 #include "../debug.h"
15 #include "../string_func.h"
16 
17 
22 private:
23  const std::string name;
24  const std::string description;
25 
26  typedef std::map<std::string, BlitterFactory *> Blitters;
27 
33  {
34  static Blitters &s_blitters = *new Blitters();
35  return s_blitters;
36  }
37 
43  {
44  static Blitter *s_blitter = nullptr;
45  return &s_blitter;
46  }
47 
48 protected:
58  BlitterFactory(const char *name, const char *description, bool usable = true) :
60  {
61  if (usable) {
62  Blitters &blitters = GetBlitters();
63  assert(blitters.find(this->name) == blitters.end());
64  /*
65  * Only add when the blitter is usable. Do not bail out or
66  * do more special things since the blitters are always
67  * instantiated upon start anyhow and freed upon shutdown.
68  */
69  blitters.insert(Blitters::value_type(this->name, this));
70  } else {
71  Debug(driver, 1, "Not registering blitter {} as it is not usable", name);
72  }
73  }
74 
79  virtual bool IsUsable() const
80  {
81  return true;
82  }
83 
84 public:
85  virtual ~BlitterFactory()
86  {
87  GetBlitters().erase(this->name);
88  if (GetBlitters().empty()) delete &GetBlitters();
89  }
90 
96  static Blitter *SelectBlitter(const std::string_view name)
97  {
99  if (b == nullptr) return nullptr;
100 
101  Blitter *newb = b->CreateInstance();
102  delete *GetActiveBlitter();
103  *GetActiveBlitter() = newb;
104 
105  Debug(driver, 1, "Successfully {} blitter '{}'", name.empty() ? "probed" : "loaded", newb->GetName());
106  return newb;
107  }
108 
114  static BlitterFactory *GetBlitterFactory(const std::string_view name)
115  {
116 #if defined(DEDICATED)
117  const std::string_view default_blitter = "null";
118 #elif defined(WITH_COCOA)
119  const std::string_view default_blitter = "32bpp-anim";
120 #else
121  const std::string_view default_blitter = "8bpp-optimized";
122 #endif
123  if (GetBlitters().empty()) return nullptr;
124  const std::string_view bname = name.empty() ? default_blitter : name;
125 
126  for (auto &it : GetBlitters()) {
127  BlitterFactory *b = it.second;
128  if (StrEqualsIgnoreCase(bname, b->name)) {
129  return b->IsUsable() ? b : nullptr;
130  }
131  }
132  return nullptr;
133  }
134 
139  {
140  return *GetActiveBlitter();
141  }
142 
149  static void GetBlittersInfo(std::back_insert_iterator<std::string> &output_iterator)
150  {
151  fmt::format_to(output_iterator, "List of blitters:\n");
152  for (auto &it : GetBlitters()) {
153  BlitterFactory *b = it.second;
154  fmt::format_to(output_iterator, "{:>18}: {}\n", b->name, b->GetDescription());
155  }
156  fmt::format_to(output_iterator, "\n");
157  }
158 
162  std::string_view GetName() const
163  {
164  return this->name;
165  }
166 
170  std::string_view GetDescription() const
171  {
172  return this->description;
173  }
174 
178  virtual Blitter *CreateInstance() = 0;
179 };
180 
181 extern std::string _ini_blitter;
182 extern bool _blitter_autodetected;
183 
184 #endif /* BLITTER_FACTORY_HPP */
BlitterFactory::CreateInstance
virtual Blitter * CreateInstance()=0
Create an instance of this Blitter-class.
BlitterFactory::GetBlitters
static Blitters & GetBlitters()
Get the map with currently known blitters.
Definition: factory.hpp:32
Blitter
How all blitters should look like.
Definition: base.hpp:29
BlitterFactory
The base factory, keeping track of all blitters.
Definition: factory.hpp:21
Debug
#define Debug(category, level, format_string,...)
Ouptut a line of debugging information.
Definition: debug.h:37
BlitterFactory::GetName
std::string_view GetName() const
Get the long, human readable, name for the Blitter-class.
Definition: factory.hpp:162
BlitterFactory::GetActiveBlitter
static Blitter ** GetActiveBlitter()
Get the currently active blitter.
Definition: factory.hpp:42
BlitterFactory::Blitters
std::map< std::string, BlitterFactory * > Blitters
Map of blitter factories.
Definition: factory.hpp:26
BlitterFactory::GetCurrentBlitter
static Blitter * GetCurrentBlitter()
Get the current active blitter (always set by calling SelectBlitter).
Definition: factory.hpp:138
BlitterFactory::GetDescription
std::string_view GetDescription() const
Get a nice description of the blitter-class.
Definition: factory.hpp:170
Blitter::GetName
virtual std::string_view GetName()=0
Get the name of the blitter, the same as the Factory-instance returns.
BlitterFactory::BlitterFactory
BlitterFactory(const char *name, const char *description, bool usable=true)
Construct the blitter, and register it.
Definition: factory.hpp:58
BlitterFactory::SelectBlitter
static Blitter * SelectBlitter(const std::string_view name)
Find the requested blitter and return its class.
Definition: factory.hpp:96
_blitter_autodetected
bool _blitter_autodetected
Was the blitter autodetected or specified by the user?
Definition: driver.cpp:34
_ini_blitter
std::string _ini_blitter
The blitter as stored in the configuration file.
Definition: driver.cpp:33
BlitterFactory::description
const std::string description
The description of the blitter.
Definition: factory.hpp:24
base.hpp
BlitterFactory::IsUsable
virtual bool IsUsable() const
Is the blitter usable with the current drivers and hardware config?
Definition: factory.hpp:79
StrEqualsIgnoreCase
bool StrEqualsIgnoreCase(const std::string_view str1, const std::string_view str2)
Compares two string( view)s for equality, while ignoring the case of the characters.
Definition: string.cpp:347
BlitterFactory::GetBlittersInfo
static void GetBlittersInfo(std::back_insert_iterator< std::string > &output_iterator)
Fill a buffer with information about the blitters.
Definition: factory.hpp:149
BlitterFactory::name
const std::string name
The name of the blitter factory.
Definition: factory.hpp:23
BlitterFactory::GetBlitterFactory
static BlitterFactory * GetBlitterFactory(const std::string_view name)
Get the blitter factory with the given name.
Definition: factory.hpp:114