aboutsummaryrefslogtreecommitdiff
path: root/src/plugger.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/plugger.h124
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
10typedef 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 ) \
21extern "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
34typedef struct PluginReg
35{
36 bool bBuiltin;
37 void *dlHandle;
38 PluginInfo *pInfo;
39} PluginReg;
40
41template<class T>
42class Plugger
43{
44public:
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
118private:
119 std::list<PluginReg *> lPlugin;
120 HashTable hPlugin;
121 HashTable hObj;
122};
123
124#endif