From fa7df2006c0e241314212644c1ec5e362220defd Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Mon, 5 Jun 2006 20:04:28 +0000 Subject: Added a complete, general plugin manager system. There's a little bit of cleanup to do before it's totally ready, but it's looking good... --- src/plugger.h | 124 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 src/plugger.h (limited to 'src/plugger.h') diff --git a/src/plugger.h b/src/plugger.h new file mode 100644 index 0000000..2cf224e --- /dev/null +++ b/src/plugger.h @@ -0,0 +1,124 @@ +#ifndef PLUGGER_H +#define PLUGGER_H + +#include "hashtable.h" +#include "list" +#include "hashfunctionstring.h" +#include "hashfunctionint.h" +#include "dlfcn.h" + +typedef struct PluginInfo +{ + const char *sID; + const char *sAuthor; + unsigned short nVersion; + unsigned short nRevision; + class Plugin *(*createPlugin)(); + void (*destroyPlugin)( class Plugin * ); +} PluginInfo; + +#define PluginInterface( classname, name, ver, rev ) \ +extern "C" { \ + class Plugin *create ##classname() \ + { \ + return new classname(); \ + } \ + void destroy ##classname( class Plugin *pCls ) \ + { \ + delete pCls; \ + } \ + PluginInfo classname = { #classname, name, ver, rev, \ + create ##classname, destroy ##classname }; \ +} + +typedef struct PluginReg +{ + bool bBuiltin; + void *dlHandle; + PluginInfo *pInfo; +} PluginReg; + +template +class Plugger +{ +public: + Plugger() : + hPlugin( new HashFunctionString(), 11 ), + hObj( new HashFunctionInt(), 11 ) + { + } + + virtual ~Plugger() + { + std::list::iterator i; + for( i = lPlugin.begin(); i != lPlugin.end(); i++ ) + { + if( (*i)->bBuiltin == false ) + { + dlclose( (*i)->dlHandle ); + } + delete (*i); + } + } + + void registerBuiltinPlugin( PluginInfo *pInfo ) + { + PluginReg *pReg = new PluginReg; + pReg->bBuiltin = true; + pReg->pInfo = pInfo; + lPlugin.insert( lPlugin.end(), pReg ); + hPlugin.insert( pInfo->sID, pReg ); + } + + void registerExternalPlugin( const char *sFName, const char *sPluginName ) + { + PluginReg *pReg = new PluginReg; + pReg->bBuiltin = false; + pReg->dlHandle = dlopen( sFName, RTLD_NOW ); + if( pReg->dlHandle == NULL ) + { + printf("***ERROR: %s\n\n", dlerror() ); + exit( 105 ); + } + pReg->pInfo = (PluginInfo *)dlsym( pReg->dlHandle, sPluginName ); + if( pReg->pInfo == NULL ) + { + printf("***ERROR: %s\n\n", dlerror() ); + exit( 106 ); + } + hPlugin.insert( pReg->pInfo->sID, pReg ); + lPlugin.insert( lPlugin.end(), pReg ); + } + + T *instantiate( const char *lpName ) + { + PluginReg *pReg = (PluginReg *)hPlugin[lpName]; + if( pReg == NULL ) + return NULL; + + T *p = pReg->pInfo->createPlugin(); + hObj.insert( p, pReg ); + printf("pReg: %08X, pPlug: %08X\n", pReg, p ); + + return p; + } + + void destroy( T *pPlug ) + { + PluginReg *pReg = (PluginReg *)hObj[pPlug]; + printf("pReg: %08X, pPlug: %08X\n", pReg, pPlug ); + if( pReg == NULL ) + return; + + pReg->pInfo->destroyPlugin( pPlug ); + + hObj.del( pPlug ); + } + +private: + std::list lPlugin; + HashTable hPlugin; + HashTable hObj; +}; + +#endif -- cgit v1.2.3