Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef BASE_PLUGINS_H
00024 #define BASE_PLUGINS_H
00025
00026 #include "common/array.h"
00027 #include "common/fs.h"
00028 #include "common/str.h"
00029
00030
00031
00053
00054
00056 #define PLUGIN_VERSION 1
00057
00058 enum PluginType {
00059 PLUGIN_TYPE_ENGINE = 0,
00060 PLUGIN_TYPE_MUSIC,
00061
00062
00063 PLUGIN_TYPE_MAX
00064 };
00065
00066
00067
00068 #define PLUGIN_TYPE_ENGINE_VERSION 1
00069 #define PLUGIN_TYPE_MUSIC_VERSION 1
00070
00071 extern int pluginTypeVersions[PLUGIN_TYPE_MAX];
00072
00073
00074
00075
00076 #define STATIC_PLUGIN 1
00077 #define DYNAMIC_PLUGIN 2
00078
00079 #define PLUGIN_ENABLED_STATIC(ID) \
00080 (ENABLE_##ID && !PLUGIN_ENABLED_DYNAMIC(ID))
00081
00082 #ifdef DYNAMIC_MODULES
00083 #define PLUGIN_ENABLED_DYNAMIC(ID) \
00084 (ENABLE_##ID && (ENABLE_##ID == DYNAMIC_PLUGIN))
00085 #else
00086 #define PLUGIN_ENABLED_DYNAMIC(ID) 0
00087 #endif
00088
00089
00090 #if defined(USE_ELF_LOADER) && defined(ELF_LOADER_CXA_ATEXIT)
00091 #define PLUGIN_DYNAMIC_DSO_HANDLE \
00092 uint32 __dso_handle __attribute__((visibility("hidden"))) = 0;
00093 #else
00094 #define PLUGIN_DYNAMIC_DSO_HANDLE
00095 #endif
00096
00097 #ifdef USE_ELF_LOADER
00098 #define PLUGIN_DYNAMIC_BUILD_DATE \
00099 PLUGIN_EXPORT const char *PLUGIN_getBuildDate() { return gScummVMPluginBuildDate; }
00100 #else
00101 #define PLUGIN_DYNAMIC_BUILD_DATE
00102 #endif
00103
00113 #define REGISTER_PLUGIN_STATIC(ID,TYPE,PLUGINCLASS) \
00114 PluginType g_##ID##_type = TYPE; \
00115 PluginObject *g_##ID##_getObject() { \
00116 return new PLUGINCLASS(); \
00117 } \
00118 void dummyFuncToAllowTrailingSemicolon()
00119
00120 #ifdef DYNAMIC_MODULES
00121
00131 #define REGISTER_PLUGIN_DYNAMIC(ID,TYPE,PLUGINCLASS) \
00132 extern "C" { \
00133 PLUGIN_DYNAMIC_DSO_HANDLE \
00134 PLUGIN_DYNAMIC_BUILD_DATE \
00135 PLUGIN_EXPORT int32 PLUGIN_getVersion() { return PLUGIN_VERSION; } \
00136 PLUGIN_EXPORT int32 PLUGIN_getType() { return TYPE; } \
00137 PLUGIN_EXPORT int32 PLUGIN_getTypeVersion() { return TYPE##_VERSION; } \
00138 PLUGIN_EXPORT PluginObject *PLUGIN_getObject() { \
00139 return new PLUGINCLASS(); \
00140 } \
00141 } \
00142 void dummyFuncToAllowTrailingSemicolon()
00143
00144 #endif // DYNAMIC_MODULES
00145
00146
00147
00148
00156 class PluginObject {
00157 public:
00158 virtual ~PluginObject() {}
00159
00161 virtual const char *getName() const = 0;
00162 };
00163
00170 class Plugin {
00171 protected:
00172 PluginObject *_pluginObject;
00173 PluginType _type;
00174
00175 public:
00176 Plugin() : _pluginObject(0), _type(PLUGIN_TYPE_MAX) {}
00177 virtual ~Plugin() {
00178
00179
00180 }
00181
00182
00183 virtual bool loadPlugin() = 0;
00184 virtual void unloadPlugin() = 0;
00185
00190 PluginType getType() const;
00191 const char *getName() const;
00192
00193 template <class T>
00194 T &get() const {
00195 T *pluginObject = dynamic_cast<T *>(_pluginObject);
00196 if (!pluginObject) {
00197 error("Invalid cast of plugin %s", getName());
00198 }
00199 return *pluginObject;
00200 }
00201
00207 virtual const char *getFileName() const { return 0; }
00208 };
00209
00211 typedef Common::Array<Plugin *> PluginList;
00212
00219 class PluginProvider {
00220 public:
00221 virtual ~PluginProvider() {}
00222
00231 virtual PluginList getPlugins() = 0;
00232
00236 virtual bool isFilePluginProvider() { return false; }
00237 };
00238
00239 #ifdef DYNAMIC_MODULES
00240
00246 class FilePluginProvider : public PluginProvider {
00247 public:
00257 virtual PluginList getPlugins();
00258
00262 bool isFilePluginProvider() { return true; }
00263
00264 protected:
00273 virtual Plugin *createPlugin(const Common::FSNode &node) const = 0;
00274
00282 virtual bool isPluginFilename(const Common::FSNode &node) const;
00283
00291 virtual void addCustomDirectories(Common::FSList &dirs) const;
00292 };
00293
00294 #endif // DYNAMIC_MODULES
00295
00296 #define PluginMan PluginManager::instance()
00297
00302 class PluginManager {
00303 protected:
00304 typedef Common::Array<PluginProvider *> ProviderList;
00305
00306 PluginList _pluginsInMem[PLUGIN_TYPE_MAX];
00307 ProviderList _providers;
00308
00309 bool tryLoadPlugin(Plugin *plugin);
00310 void addToPluginsInMemList(Plugin *plugin);
00311
00312 static PluginManager *_instance;
00313 PluginManager();
00314
00315 public:
00316 virtual ~PluginManager();
00317
00318 static void destroy() { delete _instance; _instance = 0; }
00319 static PluginManager &instance();
00320
00321 void addPluginProvider(PluginProvider *pp);
00322
00323
00324 virtual void init() {}
00325 virtual void loadFirstPlugin() {}
00326 virtual bool loadNextPlugin() { return false; }
00327 virtual bool loadPluginFromGameId(const Common::String &gameId) { return false; }
00328 virtual void updateConfigWithFileName(const Common::String &gameId) {}
00329
00330
00331 virtual void loadAllPlugins();
00332 void unloadAllPlugins();
00333
00334 void unloadPluginsExcept(PluginType type, const Plugin *plugin, bool deletePlugin = true);
00335
00336 const PluginList &getPlugins(PluginType t) { return _pluginsInMem[t]; }
00337 };
00338
00343 class PluginManagerUncached : public PluginManager {
00344 protected:
00345 friend class PluginManager;
00346 PluginList _allEnginePlugins;
00347 PluginList::iterator _currentPlugin;
00348
00349 PluginManagerUncached() {}
00350 bool loadPluginByFileName(const Common::String &filename);
00351
00352 public:
00353 virtual void init();
00354 virtual void loadFirstPlugin();
00355 virtual bool loadNextPlugin();
00356 virtual bool loadPluginFromGameId(const Common::String &gameId);
00357 virtual void updateConfigWithFileName(const Common::String &gameId);
00358
00359 virtual void loadAllPlugins() {}
00360 };
00361
00362 #endif