- Added an engine plugin manager and moved engine specific functionality into it

- base/plugins.* reorganization

svn-id: r32045
This commit is contained in:
Jordi Vilalta Prat 2008-05-12 00:26:29 +00:00
parent bb03596744
commit 2c9968fe80
11 changed files with 162 additions and 144 deletions

View file

@ -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));
}

View file

@ -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];

View file

@ -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;

View file

@ -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

View file

@ -179,15 +179,4 @@ public:
/** List of savestates. */
typedef Common::Array<SaveStateDescriptor> 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

View file

@ -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

View file

@ -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();
}

View file

@ -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<Plugin *> PluginList;
class PluginProvider {
public:
virtual ~PluginProvider() {}
@ -202,8 +192,38 @@ public:
void unloadPluginsExcept(const Plugin *plugin);
const PluginList &getPlugins() { return _plugins; }
GameList detectGames(const FSList &fslist) const;
};
// 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<EnginePlugin *> EnginePluginList;
class EngineManager : public Common::Singleton<EngineManager> {
private:
friend class Common::Singleton<SingletonBaseType>;
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

View file

@ -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";

View file

@ -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

View file

@ -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