Refined first refinement of new plugin design. Tested successfully adding/removing/running games on Linux with only one engine plugin loaded at a time

svn-id: r52026
This commit is contained in:
Tony Puccinelli 2010-08-12 06:00:19 +00:00
parent 2cfb67432a
commit 89d76fe5a5
3 changed files with 50 additions and 16 deletions

View file

@ -345,7 +345,8 @@ extern "C" int scummvm_main(int argc, const char * const argv[]) {
} }
#if defined(NEW_PLUGIN_DESIGN_FIRST_REFINEMENT) && defined(DYNAMIC_MODULES) //note: I'm going to refactor this name later :P #if defined(NEW_PLUGIN_DESIGN_FIRST_REFINEMENT) && defined(DYNAMIC_MODULES) //note: I'm going to refactor this name later :P
// Don't load the plugins initially in this case. // Only load non-engine plugins and first engine plugin initially in this case.
PluginManager::instance().loadFirstPlugin(); //This should be the only call to loadFirstPlugin external to the PluginManager class.
#else #else
// Load the plugins. // Load the plugins.
PluginManager::instance().loadPlugins(); PluginManager::instance().loadPlugins();

View file

@ -284,6 +284,7 @@ DECLARE_SINGLETON(PluginManager)
PluginManager::PluginManager() { PluginManager::PluginManager() {
// Always add the static plugin provider. // Always add the static plugin provider.
addPluginProvider(new StaticPluginProvider()); addPluginProvider(new StaticPluginProvider());
nonEnginePlugs = -1;
} }
PluginManager::~PluginManager() { PluginManager::~PluginManager() {
@ -302,29 +303,59 @@ void PluginManager::addPluginProvider(PluginProvider *pp) {
_providers.push_back(pp); _providers.push_back(pp);
} }
bool PluginManager::loadFirstPlugin() { //TODO: only deal with engine plugins here, and have a separate "loadNonEnginePlugins" function. void PluginManager::loadFirstPlugin() { //TODO: rename? It's not quite clear that this loads all non-engine plugins and first engine plugin.
unloadPluginsExcept(PLUGIN_TYPE_ENGINE, NULL); _allPlugs.clear();
PluginList plugs;
for (ProviderList::iterator pp = _providers.begin(); for (ProviderList::iterator pp = _providers.begin();
pp != _providers.end(); pp != _providers.end();
++pp) { ++pp) {
PluginList pl((*pp)->getPlugins()); PluginList pl((*pp)->getPlugins());
for (PluginList::iterator p = pl.begin(); p != pl.end(); ++p) { for (PluginList::iterator p = pl.begin(); p != pl.end(); ++p) {
plugs.push_back(*p); _allPlugs.push_back(*p);
} }
} }
_pluginsEnd = plugs.end();
_currentPlugin = plugs.begin(); _currentPlugin = _allPlugs.begin();
if (plugs.empty()) return false; //return false if there are no plugins to load.
return tryLoadPlugin(*_currentPlugin); bool updateNonEnginePlugs;
if (nonEnginePlugs == -1) { //TODO: All of this assumes engine plugins will always be last in "plugs". Is this the case?
nonEnginePlugs = 0;
updateNonEnginePlugs = true;
} else {
for (int i=0; i<nonEnginePlugs; i++) {
++_currentPlugin;
}
updateNonEnginePlugs = false;
}
if (_allPlugs.empty()) { //TODO: this case is untested.
return; //return here if somehow there are no plugins to load.
}
//this loop is for loading all non-engine plugins and the first engine plugin.
while (true) {
assert(tryLoadPlugin(*_currentPlugin));
if ((*_currentPlugin)->getType() == PLUGIN_TYPE_ENGINE) {
break;
}
if (updateNonEnginePlugs) nonEnginePlugs++;
++_currentPlugin;
if (_currentPlugin == _allPlugs.end()) {
break; //break if there were no engine plugins to load.
}
}
return;
} }
bool PluginManager::loadNextPlugin() { bool PluginManager::loadNextPlugin() {
// To ensure only one engine plugin is loaded at a time, we unload all engine plugins before loading a new one. //To ensure only one engine plugin is loaded at a time, we unload all engine plugins before trying to load a new one.
unloadPluginsExcept(PLUGIN_TYPE_ENGINE, NULL); unloadPluginsExcept(PLUGIN_TYPE_ENGINE, NULL);
++_currentPlugin; ++_currentPlugin;
if (_currentPlugin == _pluginsEnd) return false; //return false if already reached the end of list of plugins. if (_currentPlugin == _allPlugs.end()) {
return tryLoadPlugin(*_currentPlugin); loadFirstPlugin(); //load first engine plugin again at this point.
return false;
}
assert(tryLoadPlugin(*_currentPlugin));
return true;
} }
void PluginManager::loadPlugins() { void PluginManager::loadPlugins() {
@ -398,7 +429,7 @@ DECLARE_SINGLETON(EngineManager)
GameDescriptor EngineManager::findGameOnePlugAtATime(const Common::String &gameName, const EnginePlugin **plugin) const { GameDescriptor EngineManager::findGameOnePlugAtATime(const Common::String &gameName, const EnginePlugin **plugin) const {
GameDescriptor result; GameDescriptor result;
PluginManager::instance().loadFirstPlugin(); //PluginManager::instance().loadFirstPlugin();
do { do {
result = findGame(gameName, plugin); result = findGame(gameName, plugin);
if (!result.gameid().empty()) { if (!result.gameid().empty()) {
@ -434,7 +465,6 @@ GameList EngineManager::detectGames(const Common::FSList &fslist) const {
EnginePlugin::List plugins; EnginePlugin::List plugins;
EnginePlugin::List::const_iterator iter; EnginePlugin::List::const_iterator iter;
#if defined(NEW_PLUGIN_DESIGN_FIRST_REFINEMENT) && defined(DYNAMIC_MODULES) #if defined(NEW_PLUGIN_DESIGN_FIRST_REFINEMENT) && defined(DYNAMIC_MODULES)
PluginManager::instance().loadFirstPlugin();
do { do {
#endif #endif
plugins = getPlugins(); plugins = getPlugins();

View file

@ -275,8 +275,11 @@ class PluginManager : public Common::Singleton<PluginManager> {
private: private:
PluginList _plugins[PLUGIN_TYPE_MAX]; PluginList _plugins[PLUGIN_TYPE_MAX];
ProviderList _providers; ProviderList _providers;
PluginList _allPlugs;
PluginList::iterator _currentPlugin; PluginList::iterator _currentPlugin;
PluginList::iterator _pluginsEnd;
int nonEnginePlugs;
bool tryLoadPlugin(Plugin *plugin); bool tryLoadPlugin(Plugin *plugin);
@ -288,7 +291,7 @@ public:
void addPluginProvider(PluginProvider *pp); void addPluginProvider(PluginProvider *pp);
bool loadFirstPlugin(); void loadFirstPlugin();
bool loadNextPlugin(); bool loadNextPlugin();
void loadPlugins(); void loadPlugins();