aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYotam Barnoy2010-12-23 13:38:37 +0000
committerYotam Barnoy2010-12-23 13:38:37 +0000
commitee2b1092ab35be717c728ea641d18baa7f817536 (patch)
treeb74d04f75701e2d28bdae48f05d5d97854902062
parent401a8c355d1b8af353db0df6dab6117cb725f756 (diff)
downloadscummvm-rg350-ee2b1092ab35be717c728ea641d18baa7f817536.tar.gz
scummvm-rg350-ee2b1092ab35be717c728ea641d18baa7f817536.tar.bz2
scummvm-rg350-ee2b1092ab35be717c728ea641d18baa7f817536.zip
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
-rw-r--r--base/main.cpp22
-rw-r--r--base/plugins.cpp42
-rw-r--r--base/plugins.h49
-rw-r--r--engines/metaengine.h2
-rw-r--r--gui/launcher.cpp4
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<PluginManager> {
+class PluginManager {
+protected:
typedef Common::Array<PluginProvider *> 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<SingletonBaseType>;
- 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<SingletonBaseType>;
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();