Ticket #8397: plugin3.patch

File plugin3.patch, 12.5 KB (added by fingolfin, 19 years ago)

Revised 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
     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        }
    251251
    252 #ifndef DISABLE_SWORD2
    253         LOAD_MODULE("sword2", SWORD2);
    254 #endif
     252#else
     253        #define LINK_PLUGIN(ID) \
     254                extern PluginRegistrator g_##ID##_PluginReg; \
     255                plugin = &g_##ID##_PluginReg;
    255256
    256 #ifndef DISABLE_QUEEN
    257         LOAD_MODULE("queen", QUEEN);
    258 #endif
     257        // "Loader" for the static plugins.
     258        // Iterate over all registered (static) plugins and load them.
     259        PluginRegistrator *plugin;
     260       
     261        LINK_PLUGIN(SCUMM)
     262        LINK_PLUGIN(SKY)
     263        LINK_PLUGIN(SWORD1)
     264        LINK_PLUGIN(SWORD2)
     265        LINK_PLUGIN(SIMON)
     266        LINK_PLUGIN(QUEEN)
     267        LINK_PLUGIN(SAGA)
     268        //LOAD_PLUGIN(KYRA)
    259269
    260 #ifndef DISABLE_KYRA
    261         LOAD_MODULE("kyra", KYRA);
     270        for (plugin = PluginRegistrator::_head; plugin != 0; plugin = plugin->_next) {
     271                tryLoadPlugin(new StaticPlugin(plugin->_name, plugin->_games, plugin->_ef, plugin->_df));
     272        }
    262273#endif
    263274
    264 #ifndef DISABLE_SAGA
    265         LOAD_MODULE("saga", SAGA);
    266 #endif
    267275}
    268276
    269277void 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(ID,name) \
     91        PluginRegistrator g_##ID##_PluginReg(name, Engine_##ID##_gameList(), Engine_##ID##_create, Engine_##ID##_detectGames);
    9192#else
    92 #define REGISTER_PLUGIN(name,gameListFactory,engineFactory,detectGames) \
     93#define REGISTER_PLUGIN(ID,name) \
    9394        extern "C" { \
    9495                const char *PLUGIN_name() { return name; } \
    95                 GameList PLUGIN_getSupportedGames() { return gameListFactory(); } \
    96                 Engine *PLUGIN_createEngine(GameDetector *detector, OSystem *syst) { return engineFactory(detector, syst); } \
    97                 DetectedGameList PLUGIN_detectGames(const FSList &fslist) { return detectGames(fslist); } \
     96                GameList PLUGIN_getSupportedGames() { return Engine_##ID##_gameList(); } \
     97                Engine *PLUGIN_createEngine(GameDetector *detector, OSystem *syst) { return Engine_##ID##_create(detector, syst); } \
     98                DetectedGameList PLUGIN_detectGames(const FSList &fslist) { return Engine_##ID##_detectGames(fslist); } \
    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
  • kyra/kyra.cpp

    RCS file: /cvsroot/scummvm/scummvm/kyra/kyra.cpp,v
    retrieving revision 1.25
    diff -u -d -r1.25 kyra.cpp
     
    9595        return new Kyra::KyraEngine(detector, syst);
    9696}
    9797
    98 REGISTER_PLUGIN("Legend of Kyrandia Engine", Engine_KYRA_gameList, Engine_KYRA_create, Engine_KYRA_detectGames)
     98REGISTER_PLUGIN(KYRA, "Legend of Kyrandia Engine")
    9999
    100100namespace Kyra {
    101101KyraEngine::KyraEngine(GameDetector *detector, OSystem *syst)
  • queen/queen.cpp

    RCS file: /cvsroot/scummvm/scummvm/queen/queen.cpp,v
    retrieving revision 1.118
    diff -u -d -r1.118 queen.cpp
     
    8383        return new Queen::QueenEngine(detector, syst);
    8484}
    8585
    86 REGISTER_PLUGIN("Flight of the Amazon Queen", Engine_QUEEN_gameList, Engine_QUEEN_create, Engine_QUEEN_detectGames)
     86REGISTER_PLUGIN(QUEEN, "Flight of the Amazon Queen")
    8787
    8888namespace Queen {
    8989
  • saga/saga.cpp

    RCS file: /cvsroot/scummvm/scummvm/saga/saga.cpp,v
    retrieving revision 1.98
    diff -u -d -r1.98 saga.cpp
     
    105105        return new Saga::SagaEngine(detector, syst);
    106106}
    107107
    108 REGISTER_PLUGIN("SAGA Engine", Engine_SAGA_gameList, Engine_SAGA_create, Engine_SAGA_detectGames)
     108REGISTER_PLUGIN(SAGA, "SAGA Engine")
    109109
    110110namespace Saga {
    111111
  • scumm/scumm.cpp

    RCS file: /cvsroot/scummvm/scummvm/scumm/scumm.cpp,v
    retrieving revision 1.329
    diff -u -d -r1.329 scumm.cpp
     
    30213021        return engine;
    30223022}
    30233023
    3024 REGISTER_PLUGIN("Scumm Engine", Engine_SCUMM_gameList, Engine_SCUMM_create, Engine_SCUMM_detectGames)
     3024REGISTER_PLUGIN(SCUMM, "Scumm Engine")
  • simon/simon.cpp

    RCS file: /cvsroot/scummvm/scummvm/simon/simon.cpp,v
    retrieving revision 1.484
    diff -u -d -r1.484 simon.cpp
     
    159159        return new Simon::SimonEngine(detector, syst);
    160160}
    161161
    162 REGISTER_PLUGIN("Simon the Sorcerer", Engine_SIMON_gameList, Engine_SIMON_create, Engine_SIMON_detectGames)
     162REGISTER_PLUGIN(SIMON, "Simon the Sorcerer")
    163163
    164164namespace Simon {
    165165
  • sky/sky.cpp

    RCS file: /cvsroot/scummvm/scummvm/sky/sky.cpp,v
    retrieving revision 1.171
    diff -u -d -r1.171 sky.cpp
     
    106106        return new Sky::SkyEngine(detector, syst);
    107107}
    108108
    109 REGISTER_PLUGIN("Beneath a Steel Sky", Engine_SKY_gameList, Engine_SKY_create, Engine_SKY_detectGames)
     109REGISTER_PLUGIN(SKY, "Beneath a Steel Sky")
    110110
    111111
    112112namespace Sky {
  • sword1/sword1.cpp

    RCS file: /cvsroot/scummvm/scummvm/sword1/sword1.cpp,v
    retrieving revision 1.83
    diff -u -d -r1.83 sword1.cpp
     
    112112        return new SwordEngine(detector, syst);
    113113}
    114114
    115 REGISTER_PLUGIN("Broken Sword", Engine_SWORD1_gameList, Engine_SWORD1_create, Engine_SWORD1_detectGames)
     115REGISTER_PLUGIN(SWORD1, "Broken Sword")
    116116
    117117namespace Sword1 {
    118118
  • sword2/sword2.cpp

    RCS file: /cvsroot/scummvm/scummvm/sword2/sword2.cpp,v
    retrieving revision 1.133
    diff -u -d -r1.133 sword2.cpp
     
    102102        return new Sword2::Sword2Engine(detector, syst);
    103103}
    104104
    105 REGISTER_PLUGIN("Broken Sword II", Engine_SWORD2_gameList, Engine_SWORD2_create, Engine_SWORD2_detectGames)
     105REGISTER_PLUGIN(SWORD2, "Broken Sword II")
    106106
    107107namespace Sword2 {
    108108