diff options
Diffstat (limited to '')
-rw-r--r-- | src/plugger.h | 124 |
1 files changed, 124 insertions, 0 deletions
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 @@ | |||
1 | #ifndef PLUGGER_H | ||
2 | #define PLUGGER_H | ||
3 | |||
4 | #include "hashtable.h" | ||
5 | #include "list" | ||
6 | #include "hashfunctionstring.h" | ||
7 | #include "hashfunctionint.h" | ||
8 | #include "dlfcn.h" | ||
9 | |||
10 | typedef struct PluginInfo | ||
11 | { | ||
12 | const char *sID; | ||
13 | const char *sAuthor; | ||
14 | unsigned short nVersion; | ||
15 | unsigned short nRevision; | ||
16 | class Plugin *(*createPlugin)(); | ||
17 | void (*destroyPlugin)( class Plugin * ); | ||
18 | } PluginInfo; | ||
19 | |||
20 | #define PluginInterface( classname, name, ver, rev ) \ | ||
21 | extern "C" { \ | ||
22 | class Plugin *create ##classname() \ | ||
23 | { \ | ||
24 | return new classname(); \ | ||
25 | } \ | ||
26 | void destroy ##classname( class Plugin *pCls ) \ | ||
27 | { \ | ||
28 | delete pCls; \ | ||
29 | } \ | ||
30 | PluginInfo classname = { #classname, name, ver, rev, \ | ||
31 | create ##classname, destroy ##classname }; \ | ||
32 | } | ||
33 | |||
34 | typedef struct PluginReg | ||
35 | { | ||
36 | bool bBuiltin; | ||
37 | void *dlHandle; | ||
38 | PluginInfo *pInfo; | ||
39 | } PluginReg; | ||
40 | |||
41 | template<class T> | ||
42 | class Plugger | ||
43 | { | ||
44 | public: | ||
45 | Plugger() : | ||
46 | hPlugin( new HashFunctionString(), 11 ), | ||
47 | hObj( new HashFunctionInt(), 11 ) | ||
48 | { | ||
49 | } | ||
50 | |||
51 | virtual ~Plugger() | ||
52 | { | ||
53 | std::list<PluginReg *>::iterator i; | ||
54 | for( i = lPlugin.begin(); i != lPlugin.end(); i++ ) | ||
55 | { | ||
56 | if( (*i)->bBuiltin == false ) | ||
57 | { | ||
58 | dlclose( (*i)->dlHandle ); | ||
59 | } | ||
60 | delete (*i); | ||
61 | } | ||
62 | } | ||
63 | |||
64 | void registerBuiltinPlugin( PluginInfo *pInfo ) | ||
65 | { | ||
66 | PluginReg *pReg = new PluginReg; | ||
67 | pReg->bBuiltin = true; | ||
68 | pReg->pInfo = pInfo; | ||
69 | lPlugin.insert( lPlugin.end(), pReg ); | ||
70 | hPlugin.insert( pInfo->sID, pReg ); | ||
71 | } | ||
72 | |||
73 | void registerExternalPlugin( const char *sFName, const char *sPluginName ) | ||
74 | { | ||
75 | PluginReg *pReg = new PluginReg; | ||
76 | pReg->bBuiltin = false; | ||
77 | pReg->dlHandle = dlopen( sFName, RTLD_NOW ); | ||
78 | if( pReg->dlHandle == NULL ) | ||
79 | { | ||
80 | printf("***ERROR: %s\n\n", dlerror() ); | ||
81 | exit( 105 ); | ||
82 | } | ||
83 | pReg->pInfo = (PluginInfo *)dlsym( pReg->dlHandle, sPluginName ); | ||
84 | if( pReg->pInfo == NULL ) | ||
85 | { | ||
86 | printf("***ERROR: %s\n\n", dlerror() ); | ||
87 | exit( 106 ); | ||
88 | } | ||
89 | hPlugin.insert( pReg->pInfo->sID, pReg ); | ||
90 | lPlugin.insert( lPlugin.end(), pReg ); | ||
91 | } | ||
92 | |||
93 | T *instantiate( const char *lpName ) | ||
94 | { | ||
95 | PluginReg *pReg = (PluginReg *)hPlugin[lpName]; | ||
96 | if( pReg == NULL ) | ||
97 | return NULL; | ||
98 | |||
99 | T *p = pReg->pInfo->createPlugin(); | ||
100 | hObj.insert( p, pReg ); | ||
101 | printf("pReg: %08X, pPlug: %08X\n", pReg, p ); | ||
102 | |||
103 | return p; | ||
104 | } | ||
105 | |||
106 | void destroy( T *pPlug ) | ||
107 | { | ||
108 | PluginReg *pReg = (PluginReg *)hObj[pPlug]; | ||
109 | printf("pReg: %08X, pPlug: %08X\n", pReg, pPlug ); | ||
110 | if( pReg == NULL ) | ||
111 | return; | ||
112 | |||
113 | pReg->pInfo->destroyPlugin( pPlug ); | ||
114 | |||
115 | hObj.del( pPlug ); | ||
116 | } | ||
117 | |||
118 | private: | ||
119 | std::list<PluginReg *> lPlugin; | ||
120 | HashTable hPlugin; | ||
121 | HashTable hObj; | ||
122 | }; | ||
123 | |||
124 | #endif | ||