Added support to load plugins from different directories and the ability to specify the default directory from configure.

svn-id: r31816
This commit is contained in:
Jordi Vilalta Prat 2008-05-02 14:30:06 +00:00
parent 6a98108eac
commit 3f44977885
14 changed files with 132 additions and 172 deletions

View file

@ -15,6 +15,7 @@ all: $(EXECUTABLE) plugins
# Module settings
######################################################################
PLUGINS :=
MODULES := test tools base $(MODULES)
-include $(srcdir)/engines/engines.mk
@ -177,7 +178,7 @@ dist-src: \
# Themes files
DIST_FILES_THEMES:=$(addprefix $(srcdir)/gui/themes/,modern.ini modern.zip)
DIST_FILES_THEMES:=$(addprefix $(srcdir)/gui/themes/,modern.ini modern.zip classic080.ini)
# Engine data files
DIST_FILES_ENGINEDATA=
@ -201,4 +202,7 @@ DIST_FILES_ENGINEDATA+=sky.cpt
endif
DIST_FILES_ENGINEDATA:=$(addprefix $(srcdir)/dists/engine-data/,$(DIST_FILES_ENGINEDATA))
# Plugin files
DIST_FILES_PLUGINS:=$(addprefix $(srcdir)/,$(PLUGINS))
.PHONY: all clean distclean plugins dist-src

View file

@ -27,12 +27,8 @@
#include "backends/plugins/dc/dc-provider.h"
#include "backends/plugins/dynamic-plugin.h"
#include "common/fs.h"
#include "dcloader.h"
#define PLUGIN_DIRECTORY "/"
#define PLUGIN_PREFIX ""
#define PLUGIN_SUFFIX ".PLG"
class DCPlugin : public DynamicPlugin {
@ -75,6 +71,7 @@ public:
return ret;
}
void unloadPlugin() {
DynamicPlugin::unloadPlugin();
if (_dlHandle) {
@ -86,42 +83,8 @@ public:
};
PluginList DCPluginProvider::getPlugins() {
PluginList pl;
// Load dynamic plugins
// TODO... this is right now just a nasty hack.
// This should search one or multiple directories for all plugins it can
// find (to this end, we maybe should use a special prefix/suffix; e.g.
// instead of libscumm.so, use scumm.engine or scumm.plugin etc.).
//
// The list of directories to search could be e.g.:
// User specified (via config file), ".", "./plugins", "$(prefix)/lib".
//
// We also need to add code which ensures what we are looking at is
// a) a ScummVM engine and b) matches the version of the executable.
// Hence one more symbol should be exported by plugins which returns
// the "ABI" version the plugin was built for, and we can compare that
// to the ABI version of the executable.
// Load all plugins.
// Scan for all plugins in this directory
FilesystemNode dir(PLUGIN_DIRECTORY);
FSList files;
if (!dir.getChildren(files, FilesystemNode::kListFilesOnly)) {
error("Couldn't open plugin directory '%s'", PLUGIN_DIRECTORY);
}
for (FSList::const_iterator i = files.begin(); i != files.end(); ++i) {
Common::String name(i->getName());
if (name.hasPrefix(PLUGIN_PREFIX) && name.hasSuffix(PLUGIN_SUFFIX)) {
pl.push_back(new DCPlugin(i->getPath()));
}
}
return pl;
Plugin* SDLPluginProvider::createPlugin(const Common::String &filename) const {
return new DCPlugin(filename);
}

View file

@ -30,9 +30,16 @@
#if defined(DYNAMIC_MODULES) && defined(__DC__)
class DCPluginProvider : public PluginProvider {
public:
virtual PluginList getPlugins();
class DCPluginProvider : public FilePluginProvider {
protected:
Plugin* createPlugin(const Common::String &filename) const;
virtual const char* getPrefix() const { return ""; }
virtual const char* getSuffix() const { return ".PLG"; }
virtual void addCustomDirectories(Common::StringList &dirs) const {
dirs.push_back("/");
}
};
#endif // defined(DYNAMIC_MODULES) && defined(__DC__)

View file

@ -27,10 +27,8 @@
#include "backends/plugins/posix/posix-provider.h"
#include "backends/plugins/dynamic-plugin.h"
#include "common/fs.h"
#include <dlfcn.h>
#define PLUGIN_DIRECTORY "plugins/"
class POSIXPlugin : public DynamicPlugin {
@ -68,6 +66,7 @@ public:
return DynamicPlugin::loadPlugin();
}
void unloadPlugin() {
DynamicPlugin::unloadPlugin();
if (_dlHandle) {
@ -79,42 +78,8 @@ public:
};
PluginList POSIXPluginProvider::getPlugins() {
PluginList pl;
// Load dynamic plugins
// TODO... this is right now just a nasty hack.
// This should search one or multiple directories for all plugins it can
// find (to this end, we maybe should use a special prefix/suffix; e.g.
// instead of libscumm.so, use scumm.engine or scumm.plugin etc.).
//
// The list of directories to search could be e.g.:
// User specified (via config file), ".", "./plugins", "$(prefix)/lib".
//
// We also need to add code which ensures what we are looking at is
// a) a ScummVM engine and b) matches the version of the executable.
// Hence one more symbol should be exported by plugins which returns
// the "ABI" version the plugin was built for, and we can compare that
// to the ABI version of the executable.
// Load all plugins.
// Scan for all plugins in this directory
FilesystemNode dir(PLUGIN_DIRECTORY);
FSList files;
if (!dir.getChildren(files, FilesystemNode::kListFilesOnly)) {
error("Couldn't open plugin directory '%s'", PLUGIN_DIRECTORY);
}
for (FSList::const_iterator i = files.begin(); i != files.end(); ++i) {
Common::String name(i->getName());
if (name.hasPrefix(PLUGIN_PREFIX) && name.hasSuffix(PLUGIN_SUFFIX)) {
pl.push_back(new POSIXPlugin(i->getPath()));
}
}
return pl;
Plugin* POSIXPluginProvider::createPlugin(const Common::String &filename) const {
return new POSIXPlugin(filename);
}

View file

@ -30,9 +30,9 @@
#if defined(DYNAMIC_MODULES) && defined(UNIX)
class POSIXPluginProvider : public PluginProvider {
public:
virtual PluginList getPlugins();
class POSIXPluginProvider : public FilePluginProvider {
protected:
Plugin* createPlugin(const Common::String &filename) const;
};
#endif // defined(DYNAMIC_MODULES) && defined(UNIX)

View file

@ -27,11 +27,9 @@
#include "backends/plugins/sdl/sdl-provider.h"
#include "backends/plugins/dynamic-plugin.h"
#include "common/fs.h"
#include "SDL.h"
#include "SDL_loadso.h"
#define PLUGIN_DIRECTORY "plugins/"
class SDLPlugin : public DynamicPlugin {
@ -69,6 +67,7 @@ public:
return DynamicPlugin::loadPlugin();
}
void unloadPlugin() {
DynamicPlugin::unloadPlugin();
if (_dlHandle) {
@ -79,43 +78,9 @@ public:
};
PluginList SDLPluginProvider::getPlugins() {
PluginList pl;
// Load dynamic plugins
// TODO... this is right now just a nasty hack.
// This should search one or multiple directories for all plugins it can
// find (to this end, we maybe should use a special prefix/suffix; e.g.
// instead of libscumm.so, use scumm.engine or scumm.plugin etc.).
//
// The list of directories to search could be e.g.:
// User specified (via config file), ".", "./plugins", "$(prefix)/lib".
//
// We also need to add code which ensures what we are looking at is
// a) a ScummVM engine and b) matches the version of the executable.
// Hence one more symbol should be exported by plugins which returns
// the "ABI" version the plugin was built for, and we can compare that
// to the ABI version of the executable.
// Load all plugins.
// Scan for all plugins in this directory
FilesystemNode dir(PLUGIN_DIRECTORY);
FSList files;
if (!dir.getChildren(files, FilesystemNode::kListFilesOnly)) {
error("Couldn't open plugin directory '%s'", PLUGIN_DIRECTORY);
}
for (FSList::const_iterator i = files.begin(); i != files.end(); ++i) {
Common::String name(i->getName());
if (name.hasPrefix(PLUGIN_PREFIX) && name.hasSuffix(PLUGIN_SUFFIX)) {
pl.push_back(new SDLPlugin(i->getPath()));
}
}
return pl;
Plugin* SDLPluginProvider::createPlugin(const Common::String &filename) const {
return new SDLPlugin(filename);
}
#endif // defined(DYNAMIC_MODULES) && defined(UNIX)
#endif // defined(DYNAMIC_MODULES) && defined(SDL_BACKEND)

View file

@ -30,9 +30,9 @@
#if defined(DYNAMIC_MODULES) && defined(SDL_BACKEND)
class SDLPluginProvider : public PluginProvider {
public:
virtual PluginList getPlugins();
class SDLPluginProvider : public FilePluginProvider {
protected:
Plugin* createPlugin(const Common::String &filename) const;
};
#endif // defined(DYNAMIC_MODULES) && defined(UNIX)

View file

@ -27,14 +27,9 @@
#include "backends/plugins/win32/win32-provider.h"
#include "backends/plugins/dynamic-plugin.h"
#include "common/fs.h"
#include <windows.h>
#define PLUGIN_DIRECTORY ""
#define PLUGIN_PREFIX ""
#define PLUGIN_SUFFIX ".dll"
class Win32Plugin : public DynamicPlugin {
private:
@ -94,6 +89,7 @@ public:
return DynamicPlugin::loadPlugin();
}
void unloadPlugin() {
DynamicPlugin::unloadPlugin();
if (_dlHandle) {
@ -107,42 +103,8 @@ public:
};
PluginList Win32PluginProvider::getPlugins() {
PluginList pl;
// Load dynamic plugins
// TODO... this is right now just a nasty hack.
// This should search one or multiple directories for all plugins it can
// find (to this end, we maybe should use a special prefix/suffix; e.g.
// instead of libscumm.so, use scumm.engine or scumm.plugin etc.).
//
// The list of directories to search could be e.g.:
// User specified (via config file), ".", "./plugins", "$(prefix)/lib".
//
// We also need to add code which ensures what we are looking at is
// a) a ScummVM engine and b) matches the version of the executable.
// Hence one more symbol should be exported by plugins which returns
// the "ABI" version the plugin was built for, and we can compare that
// to the ABI version of the executable.
// Load all plugins.
// Scan for all plugins in this directory
FilesystemNode dir(PLUGIN_DIRECTORY);
FSList files;
if (!dir.getChildren(files, FilesystemNode::kListFilesOnly)) {
error("Couldn't open plugin directory '%s'", PLUGIN_DIRECTORY);
}
for (FSList::const_iterator i = files.begin(); i != files.end(); ++i) {
Common::String name(i->getName());
if (name.hasPrefix(PLUGIN_PREFIX) && name.hasSuffix(PLUGIN_SUFFIX)) {
pl.push_back(new Win32Plugin(i->getPath()));
}
}
return pl;
Plugin* Win32PluginProvider::createPlugin(const Common::String &filename) const {
return new Win32Plugin(filename);
}

View file

@ -30,9 +30,14 @@
#if defined(DYNAMIC_MODULES) && defined(_WIN32)
class Win32PluginProvider : public PluginProvider {
public:
virtual PluginList getPlugins();
class Win32PluginProvider : public FilePluginProvider {
protected:
Plugin* createPlugin(const Common::String &filename) const;
virtual const char* getPrefix() const { return ""; }
virtual const char* getSuffix() const { return ".dll"; }
virtual void addCustomDirectories(Common::StringList &dirs) const {}
};
#endif // defined(DYNAMIC_MODULES) && defined(_WIN32)

View file

@ -162,6 +162,65 @@ public:
}
};
#else
PluginList FilePluginProvider::getPlugins() {
PluginList pl;
// Prepare the list of directories to search
Common::StringList pluginDirs;
// TODO: Add the user specified directory (via config file)
pluginDirs.push_back(".");
pluginDirs.push_back("plugins");
// Add the provider's custom directories
addCustomDirectories(pluginDirs);
Common::StringList::const_iterator d;
for (d = pluginDirs.begin(); d != pluginDirs.end(); d++) {
// Load all plugins.
// Scan for all plugins in this directory
FilesystemNode dir(*d);
FSList files;
if (!dir.getChildren(files, FilesystemNode::kListFilesOnly)) {
debug(1, "Couldn't open plugin directory '%s'", d->c_str());
continue;
} else {
debug(1, "Reading plugins from plugin directory '%s'", d->c_str());
}
for (FSList::const_iterator i = files.begin(); i != files.end(); ++i) {
Common::String name(i->getName());
if (name.hasPrefix(getPrefix()) && name.hasSuffix(getSuffix())) {
pl.push_back(createPlugin(i->getPath()));
}
}
}
return pl;
}
const char* FilePluginProvider::getPrefix() const {
#ifdef PLUGIN_PREFIX
return PLUGIN_PREFIX;
#else
return "";
#endif
}
const char* FilePluginProvider::getSuffix() const {
#ifdef PLUGIN_SUFFIX
return PLUGIN_SUFFIX;
#else
return "";
#endif
}
void FilePluginProvider::addCustomDirectories(Common::StringList &dirs) const {
#ifdef PLUGIN_DIRECTORY
dirs.push_back(PLUGIN_DIRECTORY);
#endif
}
#endif

View file

@ -147,6 +147,19 @@ public:
virtual PluginList getPlugins() = 0;
};
class FilePluginProvider : public PluginProvider {
public:
virtual PluginList getPlugins();
protected:
virtual Plugin* createPlugin(const Common::String &filename) const = 0;
virtual const char* getPrefix() const;
virtual const char* getSuffix() const;
virtual void addCustomDirectories(Common::StringList &dirs) const;
};
/**
* Instances of this class manage all plugins, including loading them,
* making wrapper objects of class Plugin available, and unloading them.

7
configure vendored
View file

@ -541,6 +541,7 @@ Installation directories:
--bindir=DIR directory to install the scummvm binary in [PREFIX/bin]
--mandir=DIR directory to install the manpage in [PREFIX/share/man]
--datadir=DIR directory to install the data files in [PREFIX/share]
--libdir=DIR directory to install the plugins in [PREFIX/lib]
Special configuration feature:
--host=HOST cross-compile to target HOST (arm-linux, ...)
@ -714,6 +715,9 @@ for ac_option in $@; do
--datadir=*)
_datadir=`echo $ac_option | cut -d '=' -f 2`
;;
--libdir=*)
_libdir=`echo $ac_option | cut -d '=' -f 2`
;;
--enable-*)
engine_enable `echo $ac_option | cut -d '-' -f 4-`
;;
@ -1521,8 +1525,10 @@ add_to_config_mk_if_yes $_nasm 'HAVE_NASM = 1'
test -z "$_bindir" && _bindir="$_prefix/bin"
test -z "$_mandir" && _mandir="$_prefix/share/man"
test -z "$_datadir" && _datadir="$_prefix/share"
test -z "$_libdir" && _libdir="$_prefix/lib"
DEFINES="$DEFINES -DDATA_PATH=\\\"$_datadir/scummvm\\\""
DEFINES="$DEFINES -DPLUGIN_DIRECTORY=\\\"$_libdir/scummvm\\\""
#
@ -1673,6 +1679,7 @@ PREFIX := $_prefix
BINDIR := $_bindir
MANDIR := $_mandir
DATADIR := $_datadir
LIBDIR := $_libdir
$_config_mk_data

View file

@ -18,7 +18,11 @@ install: all
$(INSTALL) -d "$(DESTDIR)$(PREFIX)/share/doc/scummvm/"
$(INSTALL) -c -m 644 "$(srcdir)/AUTHORS" "$(srcdir)/COPYING" "$(srcdir)/COPYRIGHT" "$(srcdir)/NEWS" "$(srcdir)/README" "$(DESTDIR)$(PREFIX)/share/doc/scummvm/"
$(INSTALL) -d "$(DESTDIR)$(DATADIR)/scummvm/"
$(INSTALL) -c -m 644 "$(srcdir)/gui/themes/modern.ini" "$(srcdir)/gui/themes/modern.zip" "$(srcdir)/gui/themes/classic080.ini" "$(DESTDIR)$(DATADIR)/scummvm/"
$(INSTALL) -c -m 644 $(DIST_FILES_THEMES) $(DIST_FILES_ENGINEDATA) "$(DESTDIR)$(DATADIR)/scummvm/"
ifdef BUILD_PLUGINS
$(INSTALL) -d "$(DESTDIR)$(LIBDIR)/scummvm/"
$(INSTALL) -c -s -m 644 $(DIST_FILES_PLUGINS) "$(DESTDIR)$(LIBDIR)/scummvm/"
endif
uninstall:
rm -f "$(DESTDIR)$(BINDIR)/scummvm$(EXEEXT)"
@ -26,6 +30,9 @@ uninstall:
rm -f "$(DESTDIR)$(PREFIX)/share/pixmaps/scummvm.xpm"
rm -rf "$(DESTDIR)$(PREFIX)/share/doc/scummvm/"
rm -rf "$(DESTDIR)$(DATADIR)/scummvm/"
ifdef BUILD_PLUGINS
rm -rf "$(DESTDIR)$(LIBDIR)/scummvm/"
endif
deb:
ln -sf dists/debian;

View file

@ -51,6 +51,9 @@ PLUGIN:=
# Add to "plugins" target
plugins: $(PLUGIN-$(MODULE))
# Add to the PLUGINS variable
PLUGINS += $(PLUGIN-$(MODULE))
# Pseudo target for comfort, allows for "make common", "make gui" etc.
$(MODULE): $(PLUGIN-$(MODULE))
clean-plugins: clean-$(MODULE)