From ee2b1092ab35be717c728ea641d18baa7f817536 Mon Sep 17 00:00:00 2001 From: Yotam Barnoy Date: Thu, 23 Dec 2010 13:38:37 +0000 Subject: PLUGINS: switched plugin manager to inheritance rather than #defines The reason for this was that I found issues where the wrong functions were called in EngineManager for single plugin operation. Rather than inserting more messy #defines, I preferred to change the PluginManager to use virtual functions, which also makes EngineManager simpler. svn-id: r55024 --- base/main.cpp | 22 +++++----------------- base/plugins.cpp | 42 +++++++++++++++++++++++++++--------------- base/plugins.h | 49 ++++++++++++++++++++++++++++++++++++------------- engines/metaengine.h | 2 +- gui/launcher.cpp | 4 ---- 5 files changed, 69 insertions(+), 50 deletions(-) diff --git a/base/main.cpp b/base/main.cpp index 2437e85897..5024ec183c 100644 --- a/base/main.cpp +++ b/base/main.cpp @@ -107,11 +107,7 @@ static const EnginePlugin *detectPlugin() { printf("User picked target '%s' (gameid '%s')...\n", ConfMan.getActiveDomainName().c_str(), gameid.c_str()); printf("%s", " Looking for a plugin supporting this gameid... "); -#if defined(ONE_PLUGIN_AT_A_TIME) && defined(DYNAMIC_MODULES) - GameDescriptor game = EngineMan.findGameOnePluginAtATime(gameid, &plugin); -#else GameDescriptor game = EngineMan.findGame(gameid, &plugin); -#endif if (plugin == 0) { printf("failed\n"); @@ -342,14 +338,9 @@ extern "C" int scummvm_main(int argc, const char * const argv[]) { settings.erase("debugflags"); } -#if defined(ONE_PLUGIN_AT_A_TIME) && defined(DYNAMIC_MODULES) - // Only load non-engine plugins and first engine plugin initially in this case. - PluginManager::instance().loadNonEnginePluginsAndEnumerate(); -#else - // Load the plugins. - PluginManager::instance().loadPlugins(); -#endif - + PluginManager::instance().init(); + PluginManager::instance().loadAllPlugins(); // load plugins for cached plugin manager + // If we received an invalid music parameter via command line we check this here. // We can't check this before loading the music plugins. // On the other hand we cannot load the plugins before we know the file paths (in case of external plugins). @@ -463,11 +454,8 @@ extern "C" int scummvm_main(int argc, const char * const argv[]) { // Clear the active config domain ConfMan.setActiveDomain(""); - // PluginManager::instance().unloadPlugins(); + PluginManager::instance().loadAllPlugins(); // only for cached manager -#if !defined(ONE_PLUGIN_AT_A_TIME) - PluginManager::instance().loadPlugins(); -#endif } else { GUI::displayErrorDialog(_("Could not find any engine capable of running the selected game")); } @@ -476,7 +464,7 @@ extern "C" int scummvm_main(int argc, const char * const argv[]) { setupGraphics(system); launcherDialog(); } - PluginManager::instance().unloadPlugins(); + PluginManager::instance().unloadAllPlugins(); PluginManager::destroy(); GUI::GuiManager::destroy(); Common::ConfigManager::destroy(); diff --git a/base/plugins.cpp b/base/plugins.cpp index ab09b26027..62ff15bf81 100644 --- a/base/plugins.cpp +++ b/base/plugins.cpp @@ -300,7 +300,19 @@ void FilePluginProvider::addCustomDirectories(Common::FSList &dirs) const { #pragma mark - -DECLARE_SINGLETON(PluginManager); +PluginManager *PluginManager::_instance = NULL; + +PluginManager &PluginManager::instance() { + if (_instance) + return *_instance; + +#if defined(ONE_PLUGIN_AT_A_TIME) && defined(DYNAMIC_MODULES) + _instance = new PluginManagerUncached(); +#else + _instance = new PluginManager(); +#endif + return *_instance; +} PluginManager::PluginManager() { // Always add the static plugin provider. @@ -309,7 +321,7 @@ PluginManager::PluginManager() { PluginManager::~PluginManager() { // Explicitly unload all loaded plugins - unloadPlugins(); + unloadAllPlugins(); // Delete the plugin providers for (ProviderList::iterator pp = _providers.begin(); @@ -325,8 +337,8 @@ void PluginManager::addPluginProvider(PluginProvider *pp) { // // This should only be run once -void PluginManager::loadNonEnginePluginsAndEnumerate() { - unloadPlugins(); +void PluginManagerUncached::init() { + unloadAllPlugins(); _allEnginePlugins.clear(); // We need to resize our pluginsInMem list to prevent fragmentation @@ -359,7 +371,7 @@ void PluginManager::loadNonEnginePluginsAndEnumerate() { } } -void PluginManager::loadFirstPlugin() { +void PluginManagerUncached::loadFirstPlugin() { unloadPluginsExcept(PLUGIN_TYPE_ENGINE, NULL, false); // let's try to find one we can load @@ -371,7 +383,7 @@ void PluginManager::loadFirstPlugin() { } } -bool PluginManager::loadNextPlugin() { +bool PluginManagerUncached::loadNextPlugin() { unloadPluginsExcept(PLUGIN_TYPE_ENGINE, NULL, false); for (++_currentPlugin; _currentPlugin != _allEnginePlugins.end(); ++_currentPlugin) { @@ -383,7 +395,7 @@ bool PluginManager::loadNextPlugin() { return false; // no more in list } -void PluginManager::loadPlugins() { +void PluginManager::loadAllPlugins() { for (ProviderList::iterator pp = _providers.begin(); pp != _providers.end(); ++pp) { @@ -392,7 +404,7 @@ void PluginManager::loadPlugins() { } } -void PluginManager::unloadPlugins() { +void PluginManager::unloadAllPlugins() { for (int i = 0; i < PLUGIN_TYPE_MAX; i++) unloadPluginsExcept((PluginType)i, NULL); } @@ -456,11 +468,12 @@ void PluginManager::addToPluginsInMemList(Plugin *plugin) { DECLARE_SINGLETON(EngineManager); -GameDescriptor EngineManager::findGameOnePluginAtATime(const Common::String &gameName, const EnginePlugin **plugin) const { +GameDescriptor EngineManager::findGame(const Common::String &gameName, const EnginePlugin **plugin) const { GameDescriptor result; + PluginManager::instance().loadFirstPlugin(); do { - result = findGame(gameName, plugin); + result = findGameInLoadedPlugins(gameName, plugin); if (!result.gameid().empty()) { break; } @@ -468,7 +481,10 @@ GameDescriptor EngineManager::findGameOnePluginAtATime(const Common::String &gam return result; } -GameDescriptor EngineManager::findGame(const Common::String &gameName, const EnginePlugin **plugin) const { +/** + * Find the game within the plugins loaded in memory + **/ +GameDescriptor EngineManager::findGameInLoadedPlugins(const Common::String &gameName, const EnginePlugin **plugin) const { // Find the GameDescriptor for this target const EnginePlugin::List &plugins = getPlugins(); GameDescriptor result; @@ -493,19 +509,15 @@ GameList EngineManager::detectGames(const Common::FSList &fslist) const { GameList candidates; EnginePlugin::List plugins; EnginePlugin::List::const_iterator iter; -#if defined(ONE_PLUGIN_AT_A_TIME) && defined(DYNAMIC_MODULES) PluginManager::instance().loadFirstPlugin(); do { -#endif plugins = getPlugins(); // Iterate over all known games and for each check if it might be // the game in the presented directory. for (iter = plugins.begin(); iter != plugins.end(); ++iter) { candidates.push_back((**iter)->detectGames(fslist)); } -#if defined(ONE_PLUGIN_AT_A_TIME) && defined(DYNAMIC_MODULES) } while (PluginManager::instance().loadNextPlugin()); -#endif return candidates; } diff --git a/base/plugins.h b/base/plugins.h index fc8adbf0d4..f78db5cd88 100644 --- a/base/plugins.h +++ b/base/plugins.h @@ -298,35 +298,58 @@ protected: * Singleton class which manages all plugins, including loading them, * managing all Plugin class instances, and unloading them. */ -class PluginManager : public Common::Singleton { +class PluginManager { +protected: typedef Common::Array ProviderList; -private: + PluginList _pluginsInMem[PLUGIN_TYPE_MAX]; ProviderList _providers; - PluginList _allEnginePlugins; - PluginList::iterator _currentPlugin; - bool tryLoadPlugin(Plugin *plugin); void addToPluginsInMemList(Plugin *plugin); - friend class Common::Singleton; - PluginManager(); + static PluginManager *_instance; + PluginManager(); public: - ~PluginManager(); + virtual ~PluginManager(); + + static void createInstance(bool cached); + static void destroy() { delete _instance; } + static PluginManager &instance(); void addPluginProvider(PluginProvider *pp); - void loadNonEnginePluginsAndEnumerate(); - void loadFirstPlugin(); - bool loadNextPlugin(); + virtual void init() {} + virtual void loadFirstPlugin() {} + virtual bool loadNextPlugin() { return false; } - void loadPlugins(); - void unloadPlugins(); + virtual void loadAllPlugins(); + void unloadAllPlugins(); + void unloadPluginsExcept(PluginType type, const Plugin *plugin, bool deletePlugin = true); const PluginList &getPlugins(PluginType t) { return _pluginsInMem[t]; } }; +/** + * Uncached version of plugin manager + * Keeps only one dynamic plugin in memory at a time + **/ +class PluginManagerUncached : public PluginManager { +protected: + friend class PluginManager; + PluginList _allEnginePlugins; + PluginList::iterator _currentPlugin; + + PluginManagerUncached() {} + +public: + virtual void init(); + virtual void loadFirstPlugin(); + virtual bool loadNextPlugin(); + + virtual void loadAllPlugins() {} // we don't allow this +}; + #endif diff --git a/engines/metaengine.h b/engines/metaengine.h index 7b69a3fe43..2afed0703b 100644 --- a/engines/metaengine.h +++ b/engines/metaengine.h @@ -231,7 +231,7 @@ private: friend class Common::Singleton; public: - GameDescriptor findGameOnePluginAtATime(const Common::String &gameName, const EnginePlugin **plugin = NULL) const; + GameDescriptor findGameInLoadedPlugins(const Common::String &gameName, const EnginePlugin **plugin = NULL) const; GameDescriptor findGame(const Common::String &gameName, const EnginePlugin **plugin = NULL) const; GameList detectGames(const Common::FSList &fslist) const; const EnginePlugin::List &getPlugins() const; diff --git a/gui/launcher.cpp b/gui/launcher.cpp index fb9f882090..0d331a598c 100644 --- a/gui/launcher.cpp +++ b/gui/launcher.cpp @@ -924,11 +924,7 @@ void LauncherDialog::loadGame(int item) { const EnginePlugin *plugin = 0; -#if defined(ONE_PLUGIN_AT_A_TIME) && defined(DYNAMIC_MODULES) - EngineMan.findGameOnePluginAtATime(gameId, &plugin); -#else EngineMan.findGame(gameId, &plugin); -#endif String target = _domains[item]; target.toLowercase(); -- cgit v1.2.3