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
44enum 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
62extern 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 __attribute__((visibility("hidden"))) void *__dso_handle = &__dso_handle;
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 PLUGIN_DYNAMIC_DSO_HANDLE \
119 extern "C" { \
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
144public:
145 virtual ~PluginObject() {}
146
148 virtual const char *getName() const = 0;
149};
150
157class Plugin {
158protected:
159 PluginObject *_pluginObject;
160 PluginType _type;
161
162public:
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
197class StaticPlugin : public Plugin {
198public:
199 StaticPlugin(PluginObject *pluginobject, PluginType type);
201 bool loadPlugin() override;
202 void unloadPlugin() override;
203};
204
205
208
216public:
217 virtual ~PluginProvider() {}
218
227 virtual PluginList getPlugins() = 0;
228
232 virtual bool isFilePluginProvider() { return false; }
233};
234
235#ifdef DYNAMIC_MODULES
236
242class FilePluginProvider : public PluginProvider {
243public:
253 virtual PluginList getPlugins();
254
258 bool isFilePluginProvider() { return true; }
259
260protected:
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
299protected:
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;
311
312 void unloadAllPlugins();
313public:
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
353protected:
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
364public:
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: fs.h:57
Definition: fs.h:69
Definition: path.h:52
Definition: str.h:59
Definition: plugins.h:157
PluginType getType() const
virtual Common::Path getFileName() const
Definition: plugins.h:194
Definition: plugins.h:298
const Plugin * findEnginePlugin(const Common::String &engineId)
Definition: plugins.h:352
Definition: plugins.h:143
virtual const char * getName() const =0
Definition: plugins.h:215
virtual bool isFilePluginProvider()
Definition: plugins.h:232
virtual PluginList getPlugins()=0
Definition: plugins.h:197
void NORETURN_PRE error(MSVC_PRINTF const char *s,...) GCC_PRINTF(1