ScummVM API documentation
plugins.h
1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program. If not, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 #ifndef BASE_PLUGINS_H
23 #define BASE_PLUGINS_H
24 
25 #include "common/array.h"
26 #include "common/fs.h"
27 #include "common/str.h"
28 #include "backends/plugins/elf/version.h"
29 
30 #define INCLUDED_FROM_BASE_PLUGINS_H
31 #include "base/internal_plugins.h"
32 #undef INCLUDED_FROM_BASE_PLUGINS_H
33 
34 
35 // Plugin versioning
36 
38 #define PLUGIN_VERSION 1
39 
40 enum PluginType {
41  PLUGIN_TYPE_ENGINE_DETECTION = 0,
42  PLUGIN_TYPE_ENGINE,
43  PLUGIN_TYPE_MUSIC,
44  PLUGIN_TYPE_DETECTION,
45  PLUGIN_TYPE_SCALER,
46 
47  PLUGIN_TYPE_MAX
48 };
49 
50 // TODO: Make the engine API version depend on ScummVM's version
51 // because of the back linking (possibly from the checkout revision)
52 #define PLUGIN_TYPE_ENGINE_DETECTION_VERSION 1
53 #define PLUGIN_TYPE_ENGINE_VERSION 2
54 #define PLUGIN_TYPE_MUSIC_VERSION 1
55 #define PLUGIN_TYPE_DETECTION_VERSION 1
56 #define PLUGIN_TYPE_SCALER_VERSION 1
57 
58 extern const int pluginTypeVersions[PLUGIN_TYPE_MAX];
59 
60 
61 // Plugin linking
62 
63 // see comments in backends/plugins/elf/elf-provider.cpp
64 #if defined(USE_ELF_LOADER) && defined(ELF_LOADER_CXA_ATEXIT)
65 #define PLUGIN_DYNAMIC_DSO_HANDLE \
66  uint32 __dso_handle __attribute__((visibility("hidden"))) = 0;
67 #else
68 #define PLUGIN_DYNAMIC_DSO_HANDLE
69 #endif
70 
71 #ifdef USE_ELF_LOADER
72 #define PLUGIN_DYNAMIC_BUILD_DATE \
73  PLUGIN_EXPORT const char *PLUGIN_getBuildDate() { return gScummVMPluginBuildDate; }
74 #else
75 #define PLUGIN_DYNAMIC_BUILD_DATE
76 #endif
77 
87 #define REGISTER_PLUGIN_STATIC(ID,TYPE,PLUGINCLASS) \
88  extern const PluginType g_##ID##_type; \
89  const PluginType g_##ID##_type = TYPE; \
90  PluginObject *g_##ID##_getObject() { \
91  return new PLUGINCLASS(); \
92  } \
93  void dummyFuncToAllowTrailingSemicolon_##ID##_()
94 
95 #ifdef DYNAMIC_MODULES
96 
106 #define REGISTER_PLUGIN_DYNAMIC(ID,TYPE,PLUGINCLASS) \
107  extern "C" { \
108  PLUGIN_DYNAMIC_DSO_HANDLE \
109  PLUGIN_DYNAMIC_BUILD_DATE \
110  PLUGIN_EXPORT int32 PLUGIN_getVersion() { return PLUGIN_VERSION; } \
111  PLUGIN_EXPORT int32 PLUGIN_getType() { return TYPE; } \
112  PLUGIN_EXPORT int32 PLUGIN_getTypeVersion() { return TYPE##_VERSION; } \
113  PLUGIN_EXPORT PluginObject *PLUGIN_getObject() { \
114  return new PLUGINCLASS(); \
115  } \
116  } \
117  void dummyFuncToAllowTrailingSemicolon_##ID##_()
118 
119 #endif // DYNAMIC_MODULES
120 
121 
122 // Abstract plugins
123 
132 public:
133  virtual ~PluginObject() {}
134 
136  virtual const char *getName() const = 0;
137 };
138 
145 class Plugin {
146 protected:
147  PluginObject *_pluginObject;
148  PluginType _type;
149 
150 public:
151  Plugin() : _pluginObject(0), _type(PLUGIN_TYPE_MAX) {}
152  virtual ~Plugin() {
153  //if (isLoaded())
154  //unloadPlugin();
155  }
156 
157 // virtual bool isLoaded() const = 0; // TODO
158  virtual bool loadPlugin() = 0; // TODO: Rename to load() ?
159  virtual void unloadPlugin() = 0; // TODO: Rename to unload() ?
160 
165  PluginType getType() const;
166  const char *getName() const;
167 
168  template <class T>
169  T &get() const {
170  T *pluginObject = dynamic_cast<T *>(_pluginObject);
171  if (!pluginObject) {
172  error("Invalid cast of plugin %s", getName());
173  }
174  return *pluginObject;
175  }
176 
182  virtual Common::Path getFileName() const { return Common::Path(); }
183 };
184 
185 class StaticPlugin : public Plugin {
186 public:
187  StaticPlugin(PluginObject *pluginobject, PluginType type);
188  ~StaticPlugin();
189  virtual bool loadPlugin();
190  virtual void unloadPlugin();
191 };
192 
193 
196 
204 public:
205  virtual ~PluginProvider() {}
206 
215  virtual PluginList getPlugins() = 0;
216 
220  virtual bool isFilePluginProvider() { return false; }
221 };
222 
223 #ifdef DYNAMIC_MODULES
224 
230 class FilePluginProvider : public PluginProvider {
231 public:
241  virtual PluginList getPlugins();
242 
246  bool isFilePluginProvider() { return true; }
247 
248 protected:
257  virtual Plugin *createPlugin(const Common::FSNode &node) const = 0;
258 
266  virtual bool isPluginFilename(const Common::FSNode &node) const;
267 
275  virtual void addCustomDirectories(Common::FSList &dirs) const;
276 };
277 
278 #endif // DYNAMIC_MODULES
279 
280 #define PluginMan PluginManager::instance()
281 
287 protected:
289 
290  PluginList _pluginsInMem[PLUGIN_TYPE_MAX];
291  ProviderList _providers;
292 
293  bool tryLoadPlugin(Plugin *plugin);
294  void addToPluginsInMemList(Plugin *plugin);
295  const Plugin *findLoadedPlugin(const Common::String &engineId);
296 
297  static PluginManager *_instance;
298  PluginManager();
299 
300  void unloadAllPlugins();
301 public:
302  virtual ~PluginManager();
303 
304  static void destroy() { delete _instance; _instance = 0; }
305  static PluginManager &instance();
306 
307  void addPluginProvider(PluginProvider *pp);
308 
316  const Plugin *findEnginePlugin(const Common::String &engineId);
317 
318  // Functions used by the uncached PluginManager
319  virtual void init() {}
320  virtual void loadFirstPlugin() {}
321  virtual bool loadNextPlugin() { return false; }
322  virtual bool loadPluginFromEngineId(const Common::String &engineId) { return false; }
323  virtual void updateConfigWithFileName(const Common::String &engineId) {}
324  virtual void loadDetectionPlugin() {}
325  virtual void unloadDetectionPlugin() {}
326 
327  // Functions used only by the cached PluginManager
328  virtual void loadAllPlugins();
329  virtual void loadAllPluginsOfType(PluginType type);
330 
331  void unloadPluginsExcept(PluginType type, const Plugin *plugin, bool deletePlugin = true);
332 
333  const PluginList &getPlugins(PluginType t) { return _pluginsInMem[t]; }
334 };
335 
341 protected:
342  friend class PluginManager;
343  PluginList _allEnginePlugins;
344  Plugin *_detectionPlugin;
345  PluginList::iterator _currentPlugin;
346 
347  bool _isDetectionLoaded;
348 
349  PluginManagerUncached() : _detectionPlugin(nullptr), _currentPlugin(nullptr), _isDetectionLoaded(false) {}
350  bool loadPluginByFileName(const Common::Path &filename);
351 
352 public:
353  virtual ~PluginManagerUncached();
354  void init() override;
355  void loadFirstPlugin() override;
356  bool loadNextPlugin() override;
357  bool loadPluginFromEngineId(const Common::String &engineId) override;
358  void updateConfigWithFileName(const Common::String &engineId) override;
359 #ifndef DETECTION_STATIC
360  void loadDetectionPlugin() override;
361  void unloadDetectionPlugin() override;
362 #endif
363 
364  void loadAllPlugins() override {} // we don't allow these
365  void loadAllPluginsOfType(PluginType type) override {}
366 };
367 
368 #endif
Definition: plugins.h:185
Definition: str.h:59
T * iterator
Definition: array.h:54
Definition: path.h:52
Definition: plugins.h:340
virtual const char * getName() const =0
Definition: plugins.h:145
virtual bool isFilePluginProvider()
Definition: plugins.h:220
Definition: fs.h:69
Definition: plugins.h:131
Definition: fs.h:57
Definition: plugins.h:286
void NORETURN_PRE error(MSVC_PRINTF const char *s,...) GCC_PRINTF(1
virtual Common::Path getFileName() const
Definition: plugins.h:182
Definition: plugins.h:203