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 #if defined(USE_ELF_LOADER) && defined(ELF_LOADER_CXA_ATEXIT)
31 #include <cxxabi.h>
32 #endif
33 
34 #define INCLUDED_FROM_BASE_PLUGINS_H
35 #include "base/internal_plugins.h"
36 #undef INCLUDED_FROM_BASE_PLUGINS_H
37 
38 
39 // Plugin versioning
40 
42 #define PLUGIN_VERSION 1
43 
44 enum PluginType {
45  PLUGIN_TYPE_ENGINE_DETECTION = 0,
46  PLUGIN_TYPE_ENGINE,
47  PLUGIN_TYPE_MUSIC,
48  PLUGIN_TYPE_DETECTION,
49  PLUGIN_TYPE_SCALER,
50 
51  PLUGIN_TYPE_MAX
52 };
53 
54 // TODO: Make the engine API version depend on ScummVM's version
55 // because of the back linking (possibly from the checkout revision)
56 #define PLUGIN_TYPE_ENGINE_DETECTION_VERSION 1
57 #define PLUGIN_TYPE_ENGINE_VERSION 2
58 #define PLUGIN_TYPE_MUSIC_VERSION 1
59 #define PLUGIN_TYPE_DETECTION_VERSION 1
60 #define PLUGIN_TYPE_SCALER_VERSION 1
61 
62 extern const int pluginTypeVersions[PLUGIN_TYPE_MAX];
63 
64 
65 // Plugin linking
66 
67 // see comments in backends/plugins/elf/elf-provider.cpp
68 #if defined(USE_ELF_LOADER) && defined(ELF_LOADER_CXA_ATEXIT)
69 #define PLUGIN_DYNAMIC_DSO_HANDLE \
70  uint32 __dso_handle __attribute__((visibility("hidden"))) = 0;
71 // Exported helper that runs __cxa_finalize from inside the plugin, so the
72 // &__dso_handle argument is the plugin's own resolved address -- the same one
73 // GCC embedded in its __cxa_atexit calls. Calling __cxa_finalize from the host
74 // with a findSymbol() lookup is fragile (see elf-provider.cpp).
75 #define PLUGIN_DYNAMIC_FINALIZE \
76  PLUGIN_EXPORT void PLUGIN_finalize() { __cxxabiv1::__cxa_finalize(&__dso_handle); }
77 #else
78 #define PLUGIN_DYNAMIC_DSO_HANDLE
79 #define PLUGIN_DYNAMIC_FINALIZE
80 #endif
81 
82 #ifdef USE_ELF_LOADER
83 #define PLUGIN_DYNAMIC_BUILD_DATE \
84  PLUGIN_EXPORT const char *PLUGIN_getBuildDate() { return gScummVMPluginBuildDate; }
85 #else
86 #define PLUGIN_DYNAMIC_BUILD_DATE
87 #endif
88 
98 #define REGISTER_PLUGIN_STATIC(ID,TYPE,PLUGINCLASS) \
99  extern const PluginType g_##ID##_type; \
100  const PluginType g_##ID##_type = TYPE; \
101  PluginObject *g_##ID##_getObject() { \
102  return new PLUGINCLASS(); \
103  } \
104  void dummyFuncToAllowTrailingSemicolon_##ID##_()
105 
106 #ifdef DYNAMIC_MODULES
107 
117 #define REGISTER_PLUGIN_DYNAMIC(ID,TYPE,PLUGINCLASS) \
118  extern "C" { \
119  PLUGIN_DYNAMIC_DSO_HANDLE \
120  PLUGIN_DYNAMIC_FINALIZE \
121  PLUGIN_DYNAMIC_BUILD_DATE \
122  PLUGIN_EXPORT int32 PLUGIN_getVersion() { return PLUGIN_VERSION; } \
123  PLUGIN_EXPORT int32 PLUGIN_getType() { return TYPE; } \
124  PLUGIN_EXPORT int32 PLUGIN_getTypeVersion() { return TYPE##_VERSION; } \
125  PLUGIN_EXPORT PluginObject *PLUGIN_getObject() { \
126  return new PLUGINCLASS(); \
127  } \
128  } \
129  void dummyFuncToAllowTrailingSemicolon_##ID##_()
130 
131 #endif // DYNAMIC_MODULES
132 
133 
134 // Abstract plugins
135 
144 public:
145  virtual ~PluginObject() {}
146 
148  virtual const char *getName() const = 0;
149 };
150 
157 class Plugin {
158 protected:
159  PluginObject *_pluginObject;
160  PluginType _type;
161 
162 public:
163  Plugin() : _pluginObject(0), _type(PLUGIN_TYPE_MAX) {}
164  virtual ~Plugin() {
165  //if (isLoaded())
166  //unloadPlugin();
167  }
168 
169 // virtual bool isLoaded() const = 0; // TODO
170  virtual bool loadPlugin() = 0; // TODO: Rename to load() ?
171  virtual void unloadPlugin() = 0; // TODO: Rename to unload() ?
172 
177  PluginType getType() const;
178  const char *getName() const;
179 
180  template <class T>
181  T &get() const {
182  T *pluginObject = dynamic_cast<T *>(_pluginObject);
183  if (!pluginObject) {
184  error("Invalid cast of plugin %s", getName());
185  }
186  return *pluginObject;
187  }
188 
194  virtual Common::Path getFileName() const { return Common::Path(); }
195 };
196 
197 class StaticPlugin : public Plugin {
198 public:
199  StaticPlugin(PluginObject *pluginobject, PluginType type);
200  ~StaticPlugin();
201  virtual bool loadPlugin();
202  virtual void unloadPlugin();
203 };
204 
205 
208 
216 public:
217  virtual ~PluginProvider() {}
218 
227  virtual PluginList getPlugins() = 0;
228 
232  virtual bool isFilePluginProvider() { return false; }
233 };
234 
235 #ifdef DYNAMIC_MODULES
236 
242 class FilePluginProvider : public PluginProvider {
243 public:
253  virtual PluginList getPlugins();
254 
258  bool isFilePluginProvider() { return true; }
259 
260 protected:
269  virtual Plugin *createPlugin(const Common::FSNode &node) const = 0;
270 
278  virtual bool isPluginFilename(const Common::FSNode &node) const;
279 
287  virtual void addCustomDirectories(Common::FSList &dirs) const;
288 };
289 
290 #endif // DYNAMIC_MODULES
291 
292 #define PluginMan PluginManager::instance()
293 
299 protected:
301 
302  PluginList _pluginsInMem[PLUGIN_TYPE_MAX];
303  ProviderList _providers;
304 
305  bool tryLoadPlugin(Plugin *plugin);
306  void addToPluginsInMemList(Plugin *plugin);
307  const Plugin *findLoadedPlugin(const Common::String &engineId);
308 
309  static PluginManager *_instance;
310  PluginManager();
311 
312  void unloadAllPlugins();
313 public:
314  virtual ~PluginManager();
315 
316  static void destroy() { delete _instance; _instance = 0; }
317  static PluginManager &instance();
318 
319  void addPluginProvider(PluginProvider *pp);
320 
328  const Plugin *findEnginePlugin(const Common::String &engineId);
329 
330  // Functions used by the uncached PluginManager
331  virtual void init() {}
332  virtual void loadFirstPlugin() {}
333  virtual bool loadNextPlugin() { return false; }
334  virtual bool loadPluginFromEngineId(const Common::String &engineId) { return false; }
335  virtual void updateConfigWithFileName(const Common::String &engineId) {}
336  virtual void loadDetectionPlugin() {}
337  virtual void unloadDetectionPlugin() {}
338 
339  // Functions used only by the cached PluginManager
340  virtual void loadAllPlugins();
341  virtual void loadAllPluginsOfType(PluginType type);
342 
343  void unloadPluginsExcept(PluginType type, const Plugin *plugin, bool deletePlugin = true);
344 
345  const PluginList &getPlugins(PluginType t) { return _pluginsInMem[t]; }
346 };
347 
353 protected:
354  friend class PluginManager;
355  PluginList _allEnginePlugins;
356  Plugin *_detectionPlugin;
357  PluginList::iterator _currentPlugin;
358 
359  bool _isDetectionLoaded;
360 
361  PluginManagerUncached() : _detectionPlugin(nullptr), _currentPlugin(nullptr), _isDetectionLoaded(false) {}
362  bool loadPluginByFileName(const Common::Path &filename);
363 
364 public:
365  virtual ~PluginManagerUncached();
366  void init() override;
367  void loadFirstPlugin() override;
368  bool loadNextPlugin() override;
369  bool loadPluginFromEngineId(const Common::String &engineId) override;
370  void updateConfigWithFileName(const Common::String &engineId) override;
371 #ifndef DETECTION_STATIC
372  void loadDetectionPlugin() override;
373  void unloadDetectionPlugin() override;
374 #endif
375 
376  void loadAllPlugins() override {} // we don't allow these
377  void loadAllPluginsOfType(PluginType type) override {}
378 };
379 
380 #endif
Definition: plugins.h:197
Definition: str.h:59
T * iterator
Definition: array.h:54
Definition: path.h:52
Definition: plugins.h:352
virtual const char * getName() const =0
Definition: plugins.h:157
virtual bool isFilePluginProvider()
Definition: plugins.h:232
Definition: fs.h:69
Definition: plugins.h:143
Definition: fs.h:57
Definition: plugins.h:298
void NORETURN_PRE error(MSVC_PRINTF const char *s,...) GCC_PRINTF(1
virtual Common::Path getFileName() const
Definition: plugins.h:194
Definition: plugins.h:215