aboutsummaryrefslogtreecommitdiff
path: root/src/old/plugger.h
diff options
context:
space:
mode:
authorMike Buland <eichlan@xagasoft.com>2007-04-03 03:49:53 +0000
committerMike Buland <eichlan@xagasoft.com>2007-04-03 03:49:53 +0000
commitf4c20290509d7ed3a8fd5304577e7a4cc0b9d974 (patch)
tree13cdf64f7cf134f397a7165b7a3fe0807e37026b /src/old/plugger.h
parent74d4c8cd27334fc7204d5a8773deb3d424565778 (diff)
downloadlibbu++-f4c20290509d7ed3a8fd5304577e7a4cc0b9d974.tar.gz
libbu++-f4c20290509d7ed3a8fd5304577e7a4cc0b9d974.tar.bz2
libbu++-f4c20290509d7ed3a8fd5304577e7a4cc0b9d974.tar.xz
libbu++-f4c20290509d7ed3a8fd5304577e7a4cc0b9d974.zip
Ok, no code is left in src, it's all in src/old. We'll gradually move code back
into src as it's fixed and re-org'd. This includes tests, which, I may write a unit test system into libbu++ just to make my life easier.
Diffstat (limited to 'src/old/plugger.h')
-rw-r--r--src/old/plugger.h198
1 files changed, 198 insertions, 0 deletions
diff --git a/src/old/plugger.h b/src/old/plugger.h
new file mode 100644
index 0000000..d92f194
--- /dev/null
+++ b/src/old/plugger.h
@@ -0,0 +1,198 @@
1#ifndef PLUGGER_H
2#define PLUGGER_H
3
4
5#include "hashtable.h"
6#include "list"
7#include "hashfunctionstring.h"
8#include "hashfunctionint.h"
9#include "dlfcn.h"
10#include "exceptions.h"
11
12typedef struct PluginInfo
13{
14 const char *sID;
15 const char *sAuthor;
16 unsigned short nVersion;
17 unsigned short nRevision;
18 void *(*createPlugin)();
19 void (*destroyPlugin)( void * );
20} PluginInfo;
21
22typedef struct PluginReg
23{
24 bool bBuiltin;
25 void *dlHandle;
26 PluginInfo *pInfo;
27} PluginReg;
28
29#define PluginInterface( classname, baseclass, name, ver, rev ) \
30extern "C" { \
31 baseclass *create ##classname() \
32 { \
33 return new classname(); \
34 } \
35 void destroy ##classname( baseclass *pCls ) \
36 { \
37 delete pCls; \
38 } \
39 PluginInfo classname = { \
40 #classname, name, ver, rev, \
41 create ##classname, destroy ##classname }; \
42}
43
44#define PluginInterface2( pluginname, classname, baseclass, name, ver, rev ) \
45extern "C" { \
46 baseclass *create ##classname() \
47 { \
48 return new classname(); \
49 } \
50 void destroy ##classname( baseclass *pCls ) \
51 { \
52 delete pCls; \
53 } \
54 PluginInfo pluginname = { \
55 #pluginname, name, ver, rev, \
56 (void *(*)())(create ##classname), \
57 (void (*)( void * ))(destroy ##classname) }; \
58}
59
60#define PluginInterface3( structname, pluginname, classname, baseclass, name, ver, rev ) \
61extern "C" { \
62 baseclass *create ##classname() \
63 { \
64 return new classname(); \
65 } \
66 void destroy ##classname( baseclass *pCls ) \
67 { \
68 delete pCls; \
69 } \
70 PluginInfo structname = { \
71 #pluginname, name, ver, rev, \
72 (void *(*)())(create ##classname), \
73 (void (*)( void * ))(destroy ##classname) }; \
74}
75
76template<class T>
77class Plugger
78{
79public:
80
81public:
82 Plugger() :
83 hPlugin( new HashFunctionString(), 11 ),
84 hObj( new HashFunctionInt(), 11 )
85 {
86 }
87
88 virtual ~Plugger()
89 {
90 void *pos = hObj.getFirstItemPos();
91 while( (pos = hObj.getNextItemPos( pos )) )
92 {
93 T *pPlug = (T *)hObj.getItemID( pos );
94 PluginReg *pReg = (PluginReg *)hObj.getItemData( pos );
95 pReg->pInfo->destroyPlugin( pPlug );
96 }
97
98 std::list<PluginReg *>::iterator i;
99 for( i = lPlugin.begin(); i != lPlugin.end(); i++ )
100 {
101 if( (*i)->bBuiltin == false )
102 {
103 dlclose( (*i)->dlHandle );
104 }
105 delete (*i);
106 }
107 }
108
109 void registerBuiltinPlugin( PluginInfo *pInfo )
110 {
111 PluginReg *pReg = new PluginReg;
112 pReg->bBuiltin = true;
113 pReg->pInfo = pInfo;
114 lPlugin.insert( lPlugin.end(), pReg );
115 hPlugin.insert( pInfo->sID, pReg );
116 }
117
118 void registerExternalPlugin( const char *sFName, const char *sPluginName )
119 {
120 PluginReg *pReg = (PluginReg *)hPlugin[sPluginName];
121 if( pReg != NULL )
122 {
123 hPlugin.del( sPluginName );
124 dlclose( pReg->dlHandle );
125 delete pReg;
126 pReg = NULL;
127 }
128
129 pReg = new PluginReg;
130
131 pReg->bBuiltin = false;
132 pReg->dlHandle = dlopen( sFName, RTLD_NOW );
133 if( pReg->dlHandle == NULL )
134 {
135 throw PluginException( 1, "Error on %s: %s", sFName, dlerror() );
136 }
137 pReg->pInfo = (PluginInfo *)dlsym( pReg->dlHandle, sPluginName );
138 if( pReg->pInfo == NULL )
139 {
140 throw PluginException( 2, "Error on %s: %s", sFName, dlerror() );
141 }
142 hPlugin.insert( pReg->pInfo->sID, pReg );
143 lPlugin.insert( lPlugin.end(), pReg );
144 }
145
146 T *instantiate( const char *lpName )
147 {
148 PluginReg *pReg = (PluginReg *)hPlugin[lpName];
149 if( pReg == NULL )
150 return NULL;
151
152 T *p = (T *)pReg->pInfo->createPlugin();
153 hObj.insert( p, pReg );
154 //printf("pReg: %08X, pPlug: %08X\n", pReg, p );
155
156 return p;
157 }
158
159 bool hasPlugin( const char *lpName )
160 {
161 if( hPlugin[lpName] == NULL )
162 return false;
163 return true;
164 }
165
166 void destroy( T *pPlug )
167 {
168 PluginReg *pReg = (PluginReg *)hObj[pPlug];
169 //printf("pReg: %08X, pPlug: %08X\n", pReg, pPlug );
170 if( pReg == NULL )
171 return;
172
173 pReg->pInfo->destroyPlugin( pPlug );
174
175 hObj.del( pPlug );
176 }
177
178 void unloadAll()
179 {
180 std::list<PluginReg *>::iterator i;
181 for( i = lPlugin.begin(); i != lPlugin.end(); i++ )
182 {
183 if( (*i)->bBuiltin == false )
184 {
185 dlclose( (*i)->dlHandle );
186 }
187 delete (*i);
188 }
189 hPlugin.clear();
190 }
191
192private:
193 std::list<PluginReg *> lPlugin;
194 HashTable hPlugin;
195 HashTable hObj;
196};
197
198#endif