From 2c9968fe80c4ba78f895c9bac757dd6b1604ccce Mon Sep 17 00:00:00 2001 From: Jordi Vilalta Prat Date: Mon, 12 May 2008 00:26:29 +0000 Subject: - Added an engine plugin manager and moved engine specific functionality into it - base/plugins.* reorganization svn-id: r32045 --- backends/platform/dc/selector.cpp | 4 +- backends/platform/wince/CELauncherDialog.cpp | 2 +- base/commandLine.cpp | 14 +-- base/game.cpp | 26 ------ base/game.h | 11 --- base/main.cpp | 12 +-- base/plugins.cpp | 95 +++++++++++++------- base/plugins.h | 124 ++++++++++++++++----------- gui/about.cpp | 4 +- gui/launcher.cpp | 7 +- gui/massadd.cpp | 3 +- 11 files changed, 160 insertions(+), 142 deletions(-) diff --git a/backends/platform/dc/selector.cpp b/backends/platform/dc/selector.cpp index 4bca47afb2..880fbc400f 100644 --- a/backends/platform/dc/selector.cpp +++ b/backends/platform/dc/selector.cpp @@ -151,8 +151,8 @@ static Game the_game; static void detectGames(FSList &files, GameList &candidates) { - const PluginList &plugins = PluginManager::instance().getPlugins(); - PluginList::const_iterator iter = plugins.begin(); + const EnginePluginList &plugins = EngineMan.getPlugins(); + EnginePluginList::const_iterator iter = plugins.begin(); for (iter = plugins.begin(); iter != plugins.end(); ++iter) { candidates.push_back((*iter)->detectGames(files)); } diff --git a/backends/platform/wince/CELauncherDialog.cpp b/backends/platform/wince/CELauncherDialog.cpp index 45e41e5e93..d474110f26 100644 --- a/backends/platform/wince/CELauncherDialog.cpp +++ b/backends/platform/wince/CELauncherDialog.cpp @@ -77,7 +77,7 @@ void CELauncherDialog::automaticScanDirectory(const FilesystemNode &node) { FSList files; node.getChildren(files, FilesystemNode::kListFilesOnly); // detect - GameList candidates(PluginManager::instance().detectGames(files)); + GameList candidates(EngineMan.detectGames(files)); // insert if (candidates.size() >= 1) { GameDescriptor result = candidates[0]; diff --git a/base/commandLine.cpp b/base/commandLine.cpp index a4c867edee..5b919a495c 100644 --- a/base/commandLine.cpp +++ b/base/commandLine.cpp @@ -559,8 +559,8 @@ static void listGames() { printf("Game ID Full Title \n" "-------------------- ------------------------------------------------------\n"); - const PluginList &plugins = PluginManager::instance().getPlugins(); - PluginList::const_iterator iter = plugins.begin(); + const EnginePluginList &plugins = EngineMan.getPlugins(); + EnginePluginList::const_iterator iter = plugins.begin(); for (iter = plugins.begin(); iter != plugins.end(); ++iter) { GameList list = (*iter)->getSupportedGames(); for (GameList::iterator v = list.begin(); v != list.end(); ++v) { @@ -586,7 +586,7 @@ static void listTargets() { // to find the proper desc. In fact, the platform probably should // be taken into account, too. Common::String gameid(name); - GameDescriptor g = Base::findGame(gameid); + GameDescriptor g = EngineMan.findGame(gameid); if (g.description().size() > 0) description = g.description(); } @@ -613,8 +613,8 @@ static void listSaves(const char *target) { gameid.toLowercase(); // Normalize it to lower case // Find the plugin that will handle the specified gameid - const Plugin *plugin = 0; - GameDescriptor game = Base::findGame(gameid, &plugin); + const EnginePlugin *plugin = 0; + GameDescriptor game = EngineMan.findGame(gameid, &plugin); if (!plugin) { error("Could not find any plugin to handle gameid '%s' (target '%s')", gameid.c_str(), target); @@ -667,7 +667,7 @@ static void runDetectorTest() { continue; } - GameList candidates(PluginManager::instance().detectGames(files)); + GameList candidates(EngineMan.detectGames(files)); bool gameidDiffers = false; GameList::iterator x; for (x = candidates.begin(); x != candidates.end(); ++x) { @@ -740,7 +740,7 @@ bool processSettings(Common::String &command, Common::StringMap &settings) { // domain (i.e. a target) matching this argument, or alternatively // whether there is a gameid matching that name. if (!command.empty()) { - GameDescriptor gd = Base::findGame(command); + GameDescriptor gd = EngineMan.findGame(command); if (ConfMan.hasGameDomain(command) || !gd.gameid().empty()) { bool idCameFromCommandLine = false; diff --git a/base/game.cpp b/base/game.cpp index a79cfddec9..9628543672 100644 --- a/base/game.cpp +++ b/base/game.cpp @@ -75,29 +75,3 @@ void SaveStateDescriptor::setThumbnail(Graphics::Surface *t) { } _thumbnail = t; } - - -namespace Base { - -// TODO: Find a better name & place for this function. -GameDescriptor findGame(const Common::String &gameName, const Plugin **plugin) { - // Find the GameDescriptor for this target - const PluginList &plugins = PluginManager::instance().getPlugins(); - GameDescriptor result; - - if (plugin) - *plugin = 0; - - PluginList::const_iterator iter = plugins.begin(); - for (iter = plugins.begin(); iter != plugins.end(); ++iter) { - result = (*iter)->findGame(gameName.c_str()); - if (!result.gameid().empty()) { - if (plugin) - *plugin = *iter; - break; - } - } - return result; -} - -} // End of namespace Base diff --git a/base/game.h b/base/game.h index 08d18247ef..18d7967388 100644 --- a/base/game.h +++ b/base/game.h @@ -179,15 +179,4 @@ public: /** List of savestates. */ typedef Common::Array SaveStateList; - -class Plugin; - -namespace Base { - -// TODO: Find a better name & place for this function. -GameDescriptor findGame(const Common::String &gameName, const Plugin **plugin = NULL); - -} // End of namespace Base - - #endif diff --git a/base/main.cpp b/base/main.cpp index 9129fcc7e1..80f77f89ab 100644 --- a/base/main.cpp +++ b/base/main.cpp @@ -77,8 +77,8 @@ static bool launcherDialog(OSystem &system) { return (dlg.runModal() != -1); } -static const Plugin *detectPlugin() { - const Plugin *plugin = 0; +static const EnginePlugin *detectPlugin() { + const EnginePlugin *plugin = 0; // Make sure the gameid is set in the config manager, and that it is lowercase. Common::String gameid(ConfMan.getActiveDomainName()); @@ -90,7 +90,7 @@ static const Plugin *detectPlugin() { // Query the plugins and find one that will handle the specified gameid printf("Looking for %s\n", gameid.c_str()); - GameDescriptor game = Base::findGame(gameid, &plugin); + GameDescriptor game = EngineMan.findGame(gameid, &plugin); if (plugin == 0) { printf("Failed game detection\n"); @@ -105,7 +105,7 @@ static const Plugin *detectPlugin() { } // TODO: specify the possible return values here -static int runGame(const Plugin *plugin, OSystem &system, const Common::String &edebuglevels) { +static int runGame(const EnginePlugin *plugin, OSystem &system, const Common::String &edebuglevels) { Common::String gameDataPath(ConfMan.get("path")); if (gameDataPath.empty()) { } else if (gameDataPath.lastChar() != '/' @@ -168,7 +168,7 @@ static int runGame(const Plugin *plugin, OSystem &system, const Common::String & // Set the window caption to the game name Common::String caption(ConfMan.get("description")); - Common::String desc = Base::findGame(ConfMan.get("gameid")).description(); + Common::String desc = EngineMan.findGame(ConfMan.get("gameid")).description(); if (caption.empty() && !desc.empty()) caption = desc; if (caption.empty()) @@ -298,7 +298,7 @@ extern "C" int scummvm_main(int argc, char *argv[]) { // cleanly, so this is now enabled to encourage people to fix bits :) while (0 != ConfMan.getActiveDomain()) { // Try to find a plugin which feels responsible for the specified game. - const Plugin *plugin = detectPlugin(); + const EnginePlugin *plugin = detectPlugin(); if (plugin) { // Unload all plugins not needed for this game, // to save memory diff --git a/base/plugins.cpp b/base/plugins.cpp index aa813297fc..5eca8f394d 100644 --- a/base/plugins.cpp +++ b/base/plugins.cpp @@ -24,16 +24,21 @@ */ #include "base/plugins.h" -#include "common/util.h" #ifdef DYNAMIC_MODULES #include "common/config-manager.h" +#include "common/fs.h" #endif +// Plugin versioning + int pluginTypeVersions[PLUGIN_TYPE_MAX] = { PLUGIN_TYPE_ENGINE_VERSION, }; + +// Abstract plugins + PluginType Plugin::getType() const { return _type; } @@ -42,31 +47,6 @@ const char *Plugin::getName() const { return _pluginObject->getName(); } -const char *Plugin::getCopyright() const { - return ((MetaEngine*)_pluginObject)->getCopyright(); -} - -PluginError Plugin::createInstance(OSystem *syst, Engine **engine) const { - return ((MetaEngine*)_pluginObject)->createInstance(syst, engine); -} - -GameList Plugin::getSupportedGames() const { - return ((MetaEngine*)_pluginObject)->getSupportedGames(); -} - -GameDescriptor Plugin::findGame(const char *gameid) const { - return ((MetaEngine*)_pluginObject)->findGame(gameid); -} - -GameList Plugin::detectGames(const FSList &fslist) const { - return ((MetaEngine*)_pluginObject)->detectGames(fslist); -} - -SaveStateList Plugin::listSaves(const char *target) const { - return ((MetaEngine*)_pluginObject)->listSaves(target); -} - - class StaticPlugin : public Plugin { public: StaticPlugin(PluginObject *pluginobject, PluginType type) { @@ -315,15 +295,72 @@ bool PluginManager::tryLoadPlugin(Plugin *plugin) { } } -GameList PluginManager::detectGames(const FSList &fslist) const { + +// Engine plugins + +#include "engines/metaengine.h" + +const char *EnginePlugin::getCopyright() const { + return ((MetaEngine*)_pluginObject)->getCopyright(); +} + +PluginError EnginePlugin::createInstance(OSystem *syst, Engine **engine) const { + return ((MetaEngine*)_pluginObject)->createInstance(syst, engine); +} + +GameList EnginePlugin::getSupportedGames() const { + return ((MetaEngine*)_pluginObject)->getSupportedGames(); +} + +GameDescriptor EnginePlugin::findGame(const char *gameid) const { + return ((MetaEngine*)_pluginObject)->findGame(gameid); +} + +GameList EnginePlugin::detectGames(const FSList &fslist) const { + return ((MetaEngine*)_pluginObject)->detectGames(fslist); +} + +SaveStateList EnginePlugin::listSaves(const char *target) const { + return ((MetaEngine*)_pluginObject)->listSaves(target); +} + +DECLARE_SINGLETON(EngineManager); + +GameDescriptor EngineManager::findGame(const Common::String &gameName, const EnginePlugin **plugin) const { + // Find the GameDescriptor for this target + const EnginePluginList &plugins = getPlugins(); + GameDescriptor result; + + if (plugin) + *plugin = 0; + + EnginePluginList::const_iterator iter = plugins.begin(); + for (iter = plugins.begin(); iter != plugins.end(); ++iter) { + result = (*iter)->findGame(gameName.c_str()); + if (!result.gameid().empty()) { + if (plugin) + *plugin = *iter; + break; + } + } + return result; +} + +GameList EngineManager::detectGames(const FSList &fslist) const { GameList candidates; + const EnginePluginList &plugins = getPlugins(); + // Iterate over all known games and for each check if it might be // the game in the presented directory. - PluginList::const_iterator iter; - for (iter = _plugins.begin(); iter != _plugins.end(); ++iter) { + EnginePluginList::const_iterator iter; + for (iter = plugins.begin(); iter != plugins.end(); ++iter) { candidates.push_back((*iter)->detectGames(fslist)); } return candidates; } + +const EnginePluginList &EngineManager::getPlugins() const { + return (const EnginePluginList&)PluginManager::instance().getPlugins(); +} diff --git a/base/plugins.h b/base/plugins.h index ec947ee6ad..14ce2a3aa4 100644 --- a/base/plugins.h +++ b/base/plugins.h @@ -26,27 +26,12 @@ #ifndef BASE_PLUGINS_H #define BASE_PLUGINS_H -#include "common/array.h" #include "common/error.h" #include "common/list.h" #include "common/singleton.h" -#include "common/util.h" #include "base/game.h" -/** - * Abstract base class for the plugin objects which handle plugins - * instantiation. Subclasses for this may be used for engine plugins - * and other types of plugins. - */ -class PluginObject { -public: - virtual ~PluginObject() {} - - /** Returns the name of the plugin. */ - virtual const char *getName() const = 0; -}; - -#include "engines/metaengine.h" +// Plugin versioning // Global Plugin API version #define PLUGIN_VERSION 1 @@ -63,42 +48,8 @@ enum PluginType { extern int pluginTypeVersions[PLUGIN_TYPE_MAX]; -class Engine; -class FSList; -class OSystem; - -/** - * Abstract base class for the plugin system. - * Subclasses for this can be used to wrap both static and dynamic - * plugins. - */ -class Plugin { -protected: - PluginObject *_pluginObject; - PluginType _type; - -public: - Plugin() : _pluginObject(0) {} - virtual ~Plugin() { - //if (isLoaded()) - //unloadPlugin(); - } - -// virtual bool isLoaded() const = 0; // TODO - virtual bool loadPlugin() = 0; // TODO: Rename to load() ? - virtual void unloadPlugin() = 0; // TODO: Rename to unload() ? - - PluginType getType() const; - const char *getName() const; - const char *getCopyright() const; - - PluginError createInstance(OSystem *syst, Engine **engine) const; - GameList getSupportedGames() const; - GameDescriptor findGame(const char *gameid) const; - GameList detectGames(const FSList &fslist) const; - SaveStateList listSaves(const char *target) const; -}; +// Plugin linking #define STATIC_PLUGIN 1 #define DYNAMIC_PLUGIN 2 @@ -147,10 +98,49 @@ public: #endif // DYNAMIC_MODULES +// Abstract plugins + +/** + * Abstract base class for the plugin objects which handle plugins + * instantiation. Subclasses for this may be used for engine plugins + * and other types of plugins. + */ +class PluginObject { +public: + virtual ~PluginObject() {} + + /** Returns the name of the plugin. */ + virtual const char *getName() const = 0; +}; + +/** + * Abstract base class for the plugin system. + * Subclasses for this can be used to wrap both static and dynamic + * plugins. + */ +class Plugin { +protected: + PluginObject *_pluginObject; + PluginType _type; + +public: + Plugin() : _pluginObject(0) {} + virtual ~Plugin() { + //if (isLoaded()) + //unloadPlugin(); + } + +// virtual bool isLoaded() const = 0; // TODO + virtual bool loadPlugin() = 0; // TODO: Rename to load() ? + virtual void unloadPlugin() = 0; // TODO: Rename to unload() ? + + PluginType getType() const; + const char *getName() const; +}; + /** List of plugins. */ typedef Common::Array PluginList; - class PluginProvider { public: virtual ~PluginProvider() {} @@ -202,8 +192,38 @@ public: void unloadPluginsExcept(const Plugin *plugin); const PluginList &getPlugins() { return _plugins; } +}; + +// Engine plugins + +class Engine; +class FSList; +class OSystem; + +class EnginePlugin : public Plugin { +public: + const char *getCopyright() const; + PluginError createInstance(OSystem *syst, Engine **engine) const; + GameList getSupportedGames() const; + GameDescriptor findGame(const char *gameid) const; GameList detectGames(const FSList &fslist) const; + SaveStateList listSaves(const char *target) const; }; +typedef Common::Array EnginePluginList; + +class EngineManager : public Common::Singleton { +private: + friend class Common::Singleton; + +public: + GameDescriptor findGame(const Common::String &gameName, const EnginePlugin **plugin = NULL) const; + GameList detectGames(const FSList &fslist) const; + const EnginePluginList &getPlugins() const; +}; + +/** Shortcut for accessing the engine manager. */ +#define EngineMan EngineManager::instance() + #endif diff --git a/gui/about.cpp b/gui/about.cpp index c346d5ad87..b4d8cb0bf2 100644 --- a/gui/about.cpp +++ b/gui/about.cpp @@ -128,8 +128,8 @@ AboutDialog::AboutDialog() _lines.push_back(""); addLine("\\C\\c1""Available engines:"); - const PluginList &plugins = PluginManager::instance().getPlugins(); - PluginList::const_iterator iter = plugins.begin(); + const EnginePluginList &plugins = EngineMan.getPlugins(); + EnginePluginList::const_iterator iter = plugins.begin(); for (; iter != plugins.end(); ++iter) { Common::String str; str = "\\C"; diff --git a/gui/launcher.cpp b/gui/launcher.cpp index 2be703a405..505ecf842b 100644 --- a/gui/launcher.cpp +++ b/gui/launcher.cpp @@ -23,7 +23,6 @@ */ #include "engines/engine.h" -#include "base/game.h" #include "base/plugins.h" #include "base/version.h" @@ -582,7 +581,7 @@ void LauncherDialog::updateListing() { if (gameid.empty()) gameid = iter->_key; if (description.empty()) { - GameDescriptor g = Base::findGame(gameid); + GameDescriptor g = EngineMan.findGame(gameid); if (g.contains("description")) description = g.description(); } @@ -659,7 +658,7 @@ void LauncherDialog::addGame() { // ...so let's determine a list of candidates, games that // could be contained in the specified directory. - GameList candidates(PluginManager::instance().detectGames(files)); + GameList candidates(EngineMan.detectGames(files)); int idx; if (candidates.empty()) { @@ -783,7 +782,7 @@ void LauncherDialog::editGame(int item) { String gameId(ConfMan.get("gameid", _domains[item])); if (gameId.empty()) gameId = _domains[item]; - EditGameDialog editDialog(_domains[item], Base::findGame(gameId).description()); + EditGameDialog editDialog(_domains[item], EngineMan.findGame(gameId).description()); if (editDialog.runModal() > 0) { // User pressed OK, so make changes permanent diff --git a/gui/massadd.cpp b/gui/massadd.cpp index 934957e80b..446285af2d 100644 --- a/gui/massadd.cpp +++ b/gui/massadd.cpp @@ -23,7 +23,6 @@ */ #include "engines/engine.h" -#include "base/game.h" #include "base/plugins.h" #include "common/events.h" @@ -132,7 +131,7 @@ void MassAddDialog::handleTickle() { } // Run the detector on the dir - GameList candidates(PluginManager::instance().detectGames(files)); + GameList candidates(EngineMan.detectGames(files)); // Just add all detected games / game variants. If we get more than one, // that either means the directory contains multiple games, or the detector -- cgit v1.2.3