Ticket #8397: plugin2.patch

File plugin2.patch, 7.4 KB (added by fingolfin, 19 years ago)

Cleaned up patch

  • common.rules

    RCS file: /cvsroot/scummvm/scummvm/common.rules,v
    retrieving revision 1.16
    diff -u -d -r1.16 common.rules
     
    1010# TODO: Right now, for Mac OS X only. We either will have to generate this
    1111# via the configure script, or put in some 'if' statements to choose from
    1212# one of several build rules
    13 PLUGIN-$(MODULE) := $(MODULE)/$(PLUGIN_PREFIX)$(MODULE)$(PLUGIN_SUFFIX)
     13PLUGIN-$(MODULE) := plugins/$(PLUGIN_PREFIX)$(MODULE)$(PLUGIN_SUFFIX)
    1414$(PLUGIN-$(MODULE)): $(MODULE_OBJS) $(PLUGIN_EXTRA_DEPS)
     15        $(MKDIR) plugins
    1516        $(CXX) $(PLUGIN_LDFLAGS) $(filter-out $(PLUGIN_EXTRA_DEPS),$+) -o $@
    1617PLUGIN:=
    1718plugins: $(PLUGIN-$(MODULE))
  • base/plugins.cpp

    RCS file: /cvsroot/scummvm/scummvm/base/plugins.cpp,v
    retrieving revision 1.38
    diff -u -d -r1.38 plugins.cpp
     
    3939
    4040#ifdef UNIX
    4141#include <dlfcn.h>
    42 #define DYNAMIC_PLUGIN_PATH(name) (name "/" PLUGIN_PREFIX name PLUGIN_SUFFIX)
     42#define PLUGIN_DIRECTORY        "plugins/"
    4343#else
    4444#ifdef __DC__
    4545#include "dcloader.h"
    46 #define DYNAMIC_PLUGIN_PATH(name) (name ".plg")
     46#define PLUGIN_DIRECTORY        ""
     47#define PLUGIN_PREFIX           ""
     48#define PLUGIN_SUFFIX           ".plg"
    4749#else
    4850#error No support for loading plugins on non-unix systems at this point!
    4951#endif
    5052#endif
    5153
     54
     55#else
     56
     57PluginRegistrator *PluginRegistrator::_head = 0;
     58
     59PluginRegistrator::PluginRegistrator(const char *name, GameList games, EngineFactory ef, DetectFunc df)
     60        : _name(name), _ef(ef), _df(df), _games(games) {
     61        printf("Automatically registered plugin '%s'\n", name);
     62        _next = _head;
     63        _head = this;
     64}
     65
    5266#endif
    5367
    5468
     
    108122        void *findSymbol(const char *symbol);
    109123
    110124public:
    111         DynamicPlugin(const char *filename)
     125        DynamicPlugin(const Common::String &filename)
    112126                : _dlHandle(0), _filename(filename), _ef(0), _df(0), _games() {}
    113127
    114128        const char *getName() const                                     { return _name.c_str(); }
     
    222236        // Hence one more symbol should be exported by plugins which returns
    223237        // the "ABI" version the plugin was built for, and we can compare that
    224238        // to the ABI version of the executable.
    225         #define LOAD_MODULE(name, NAME) \
    226                 tryLoadPlugin(new DynamicPlugin(DYNAMIC_PLUGIN_PATH(name)));
    227 #else
    228         // "Loader" for the static plugins
    229         #define LOAD_MODULE(name, NAME) \
    230                 tryLoadPlugin(new StaticPlugin(name, Engine_##NAME##_gameList(), Engine_##NAME##_create, Engine_##NAME##_detectGames));
    231 #endif
    232239
    233240        // Load all plugins.
    234         // Right now the list is hardcoded. On the long run, of course it should
    235         // automatically be determined.
    236 #ifndef DISABLE_SCUMM
    237         LOAD_MODULE("scumm", SCUMM);
    238 #endif
    239 
    240 #ifndef DISABLE_SIMON
    241         LOAD_MODULE("simon", SIMON);
    242 #endif
    243 
    244 #ifndef DISABLE_SKY
    245         LOAD_MODULE("sky", SKY);
    246 #endif
    247 
    248 #ifndef DISABLE_SWORD1
    249         LOAD_MODULE("sword1", SWORD1);
    250 #endif
    251 
    252 #ifndef DISABLE_SWORD2
    253         LOAD_MODULE("sword2", SWORD2);
    254 #endif
    255 
    256 #ifndef DISABLE_QUEEN
    257         LOAD_MODULE("queen", QUEEN);
    258 #endif
     241        // Scan for all plugins in this directory
     242        FilesystemNode dir(PLUGIN_DIRECTORY);
     243        FSList files(dir.listDir(FilesystemNode::kListFilesOnly));
     244       
     245        for (FSList::const_iterator i = files.begin(); i != files.end(); ++i) {
     246                Common::String name(i->displayName());
     247                if (name.hasPrefix(PLUGIN_PREFIX) && name.hasSuffix(PLUGIN_SUFFIX)) {
     248                        tryLoadPlugin(new DynamicPlugin(i->path()));
     249                }
     250        }
    259251
    260 #ifndef DISABLE_KYRA
    261         LOAD_MODULE("kyra", KYRA);
     252#else
     253        // "Loader" for the static plugins.
     254        // Iterate over all registered (static) plugins and load them.
     255        PluginRegistrator *plugin = PluginRegistrator::_head;
     256        for (; plugin != 0; plugin = plugin->_next) {
     257                tryLoadPlugin(new StaticPlugin(plugin->_name, plugin->_games, plugin->_ef, plugin->_df));
     258        }
    262259#endif
    263260
    264 #ifndef DISABLE_SAGA
    265         LOAD_MODULE("saga", SAGA);
    266 #endif
    267261}
    268262
    269263void PluginManager::unloadPlugins() {
  • base/plugins.h

    RCS file: /cvsroot/scummvm/scummvm/base/plugins.h,v
    retrieving revision 1.25
    diff -u -d -r1.25 plugins.h
     
    7878
    7979
    8080/**
    81  * The REGISTER_PLUGIN is a convenience macro meant to ease writing
     81 * REGISTER_PLUGIN is a convenience macro meant to ease writing
    8282 * the plugin interface for our modules. In particular, using it
    8383 * makes it possible to compile the very same code in a module
    8484 * both as a static and a dynamic plugin.
     
    8787 * @todo        on Windows, we might need __declspec(dllexport) ?
    8888 */
    8989#ifndef DYNAMIC_MODULES
    90 #define REGISTER_PLUGIN(name,gameListFactory,engineFactory,detectGames)
     90#define REGISTER_PLUGIN(name,gameListFactory,engineFactory,detectGames) \
     91        static PluginRegistrator pluginReg(name, gameListFactory(), engineFactory, detectGames);
    9192#else
    9293#define REGISTER_PLUGIN(name,gameListFactory,engineFactory,detectGames) \
    9394        extern "C" { \
     
    9899        }
    99100#endif
    100101
     102#ifndef DYNAMIC_MODULES
     103/**
     104 * The PluginRegistrator class is used by the static version of REGISTER_PLUGIN
     105 * to allow static 'plugins' to automatically register with the PluginManager.
     106 * The trick is to put a global instance of PluginRegistrator into each engine.
     107 * Then when the application is started, the constructor of each of these
     108 * objects is run. They then hook themselves into a linked list, and store
     109 * all data passed to them, which the PluginManager then can use to load
     110 * and initialize the static plugins.
     111 * Neat, isn't it ? ;-)
     112 *
     113 * Caveat: there may be systems / linkers where this trick doesn't work because
     114 * the linker doesn't invoke the object constructors. This system has currently
     115 * been tested on Mac OS X only.
     116 */
     117class PluginRegistrator {
     118        friend class PluginManager;
     119public:
     120        typedef Engine *(*EngineFactory)(GameDetector *detector, OSystem *syst);
     121        typedef DetectedGameList (*DetectFunc)(const FSList &fslist);
     122
     123protected:
     124        static PluginRegistrator *_head;
     125       
     126        PluginRegistrator *_next;
     127
     128        const char *_name;
     129        EngineFactory _ef;
     130        DetectFunc _df;
     131        GameList _games;
     132
     133public:
     134        PluginRegistrator(const char *name, GameList games, EngineFactory ef, DetectFunc df);
     135};
     136#endif
     137
    101138
    102139/** List of plugins. */
    103140typedef Common::Array<Plugin *> PluginList;
     
    133170};
    134171
    135172
    136 #ifndef DYNAMIC_MODULES
    137 
    138 #define DECLARE_PLUGIN(name) \
    139         extern GameList Engine_##name##_gameList(); \
    140         extern Engine *Engine_##name##_create(GameDetector *detector, OSystem *syst); \
    141         extern DetectedGameList Engine_##name##_detectGames(const FSList &fslist);
    142 
    143 // Factory functions => no need to include the specific classes
    144 // in this header. This serves two purposes:
    145 // 1) Clean separation from the game modules (scumm, simon) and the generic code
    146 // 2) Faster (compiler doesn't have to parse lengthy header files)
    147 #ifndef DISABLE_SCUMM
    148 DECLARE_PLUGIN(SCUMM)
    149 #endif
    150 
    151 #ifndef DISABLE_SIMON
    152 DECLARE_PLUGIN(SIMON)
    153 #endif
    154 
    155 #ifndef DISABLE_SKY
    156 DECLARE_PLUGIN(SKY)
    157 #endif
    158 
    159 #ifndef DISABLE_SWORD1
    160 DECLARE_PLUGIN(SWORD1)
    161 #endif
    162 
    163 #ifndef DISABLE_SWORD2
    164 DECLARE_PLUGIN(SWORD2)
    165 #endif
    166 
    167 #ifndef DISABLE_QUEEN
    168 DECLARE_PLUGIN(QUEEN)
    169 #endif
    170 
    171 #ifndef DISABLE_KYRA
    172 DECLARE_PLUGIN(KYRA)
    173 #endif
    174 
    175 #ifndef DISABLE_SAGA
    176 DECLARE_PLUGIN(SAGA)
    177 #endif
    178 
    179 #endif
    180 
    181173#endif