aboutsummaryrefslogtreecommitdiff
path: root/src/plugger.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/plugger.h316
1 files changed, 158 insertions, 158 deletions
diff --git a/src/plugger.h b/src/plugger.h
index d92f194..2124b7a 100644
--- a/src/plugger.h
+++ b/src/plugger.h
@@ -1,198 +1,198 @@
1#ifndef PLUGGER_H 1#ifndef BU_PLUGGER_H
2#define PLUGGER_H 2#define BU_PLUGGER_H
3 3
4 4
5#include "hashtable.h" 5#include "bu/hash.h"
6#include "list" 6#include "bu/list.h"
7#include "hashfunctionstring.h" 7#include <dlfcn.h>
8#include "hashfunctionint.h" 8#include "bu/exceptions.h"
9#include "dlfcn.h" 9#include "bu/fstring.h"
10#include "exceptions.h"
11 10
12typedef struct PluginInfo 11namespace Bu
13{ 12{
14 const char *sID; 13 typedef struct PluginInfo
15 const char *sAuthor; 14 {
16 unsigned short nVersion; 15 const char *sID;
17 unsigned short nRevision; 16 const char *sAuthor;
18 void *(*createPlugin)(); 17 unsigned short nVersion;
19 void (*destroyPlugin)( void * ); 18 unsigned short nRevision;
20} PluginInfo; 19 void *(*createPlugin)();
21 20 void (*destroyPlugin)( void * );
22typedef struct PluginReg 21 } PluginInfo;
23{ 22
24 bool bBuiltin; 23 typedef struct PluginReg
25 void *dlHandle; 24 {
26 PluginInfo *pInfo; 25 bool bBuiltin;
27} PluginReg; 26 void *dlHandle;
27 PluginInfo *pInfo;
28 } PluginReg;
28 29
29#define PluginInterface( classname, baseclass, name, ver, rev ) \ 30#define PluginInterface( classname, baseclass, name, ver, rev ) \
30extern "C" { \ 31 extern "C" { \
31 baseclass *create ##classname() \ 32 baseclass *create ##classname() \
32 { \ 33 { \
33 return new classname(); \ 34 return new classname(); \
34 } \ 35 } \
35 void destroy ##classname( baseclass *pCls ) \ 36 void destroy ##classname( baseclass *pCls ) \
36 { \ 37 { \
37 delete pCls; \ 38 delete pCls; \
38 } \ 39 } \
39 PluginInfo classname = { \ 40 Bu::PluginInfo classname = { \
40 #classname, name, ver, rev, \ 41 #classname, name, ver, rev, \
41 create ##classname, destroy ##classname }; \ 42 create ##classname, destroy ##classname }; \
42} 43 }
43 44
44#define PluginInterface2( pluginname, classname, baseclass, name, ver, rev ) \ 45#define PluginInterface2( pluginname, classname, baseclass, name, ver, rev ) \
45extern "C" { \ 46 extern "C" { \
46 baseclass *create ##classname() \ 47 baseclass *create ##classname() \
47 { \ 48 { \
48 return new classname(); \ 49 return new classname(); \
49 } \ 50 } \
50 void destroy ##classname( baseclass *pCls ) \ 51 void destroy ##classname( baseclass *pCls ) \
51 { \ 52 { \
52 delete pCls; \ 53 delete pCls; \
53 } \ 54 } \
54 PluginInfo pluginname = { \ 55 Bu::PluginInfo pluginname = { \
55 #pluginname, name, ver, rev, \ 56 #pluginname, name, ver, rev, \
56 (void *(*)())(create ##classname), \ 57 (void *(*)())(create ##classname), \
57 (void (*)( void * ))(destroy ##classname) }; \ 58 (void (*)( void * ))(destroy ##classname) }; \
58} 59 }
59 60
60#define PluginInterface3( structname, pluginname, classname, baseclass, name, ver, rev ) \ 61#define PluginInterface3( structname, pluginname, classname, baseclass, name, ver, rev ) \
61extern "C" { \ 62 extern "C" { \
62 baseclass *create ##classname() \ 63 baseclass *create ##classname() \
63 { \ 64 { \
64 return new classname(); \ 65 return new classname(); \
65 } \ 66 } \
66 void destroy ##classname( baseclass *pCls ) \ 67 void destroy ##classname( baseclass *pCls ) \
67 { \ 68 { \
68 delete pCls; \ 69 delete pCls; \
69 } \ 70 } \
70 PluginInfo structname = { \ 71 Bu::PluginInfo structname = { \
71 #pluginname, name, ver, rev, \ 72 #pluginname, name, ver, rev, \
72 (void *(*)())(create ##classname), \ 73 (void *(*)())(create ##classname), \
73 (void (*)( void * ))(destroy ##classname) }; \ 74 (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 } 75 }
87 76
88 virtual ~Plugger() 77 template<class T>
78 class Plugger
89 { 79 {
90 void *pos = hObj.getFirstItemPos(); 80 public:
91 while( (pos = hObj.getNextItemPos( pos )) ) 81 typedef Bu::Hash<Bu::FString, PluginReg *> PluginHash;
82 typedef Bu::Hash<int, void *> InstHash;
83
84 public:
85 Plugger()
92 { 86 {
93 T *pPlug = (T *)hObj.getItemID( pos );
94 PluginReg *pReg = (PluginReg *)hObj.getItemData( pos );
95 pReg->pInfo->destroyPlugin( pPlug );
96 } 87 }
97 88
98 std::list<PluginReg *>::iterator i; 89 virtual ~Plugger()
99 for( i = lPlugin.begin(); i != lPlugin.end(); i++ )
100 { 90 {
101 if( (*i)->bBuiltin == false ) 91 for( InstHash::iterator i = hObj.begin(); i != hObj.end(); i++ )
102 { 92 {
103 dlclose( (*i)->dlHandle ); 93 T *pPlug = (T *)i.getKey();
94 PluginReg *pReg = (PluginReg *)*i;
95 pReg->pInfo->destroyPlugin( pPlug );
104 } 96 }
105 delete (*i);
106 }
107 }
108 97
109 void registerBuiltinPlugin( PluginInfo *pInfo ) 98 for( PluginHash::iterator i = hPlugin.begin();
110 { 99 i != hPlugin.end(); i++ )
111 PluginReg *pReg = new PluginReg; 100 {
112 pReg->bBuiltin = true; 101 if( (*i)->bBuiltin == false )
113 pReg->pInfo = pInfo; 102 {
114 lPlugin.insert( lPlugin.end(), pReg ); 103 dlclose( (*i)->dlHandle );
115 hPlugin.insert( pInfo->sID, pReg ); 104 }
116 } 105 delete (*i);
106 }
107 }
117 108
118 void registerExternalPlugin( const char *sFName, const char *sPluginName ) 109 void registerBuiltinPlugin( PluginInfo *pInfo )
119 {
120 PluginReg *pReg = (PluginReg *)hPlugin[sPluginName];
121 if( pReg != NULL )
122 { 110 {
123 hPlugin.del( sPluginName ); 111 PluginReg *pReg = new PluginReg;
124 dlclose( pReg->dlHandle ); 112 pReg->bBuiltin = true;
125 delete pReg; 113 pReg->pInfo = pInfo;
126 pReg = NULL; 114 hPlugin.insert( pInfo->sID, pReg );
127 } 115 }
128 116
129 pReg = new PluginReg; 117 void registerExternalPlugin( const char *sFName, const char *sPluginName )
130
131 pReg->bBuiltin = false;
132 pReg->dlHandle = dlopen( sFName, RTLD_NOW );
133 if( pReg->dlHandle == NULL )
134 { 118 {
135 throw PluginException( 1, "Error on %s: %s", sFName, dlerror() ); 119 PluginReg *pReg;
120 try {
121 pReg = (PluginReg *)hPlugin[sPluginName];
122 hPlugin.erase( sPluginName );
123 dlclose( pReg->dlHandle );
124 delete pReg;
125 pReg = NULL;
126 } catch( Bu::HashException &e )
127 {
128 }
129
130 pReg = new PluginReg;
131
132 pReg->bBuiltin = false;
133 pReg->dlHandle = dlopen( sFName, RTLD_NOW );
134 if( pReg->dlHandle == NULL )
135 {
136 throw PluginException( 1, "Error on %s: %s", sFName, dlerror() );
137 }
138 pReg->pInfo = (PluginInfo *)dlsym( pReg->dlHandle, sPluginName );
139 if( pReg->pInfo == NULL )
140 {
141 throw PluginException( 2, "Error on %s: %s", sFName, dlerror() );
142 }
143 hPlugin.insert( pReg->pInfo->sID, pReg );
136 } 144 }
137 pReg->pInfo = (PluginInfo *)dlsym( pReg->dlHandle, sPluginName ); 145
138 if( pReg->pInfo == NULL ) 146 T *instantiate( const char *lpName )
139 { 147 {
140 throw PluginException( 2, "Error on %s: %s", sFName, dlerror() ); 148 PluginReg *pReg = (PluginReg *)hPlugin[lpName];
149 if( pReg == NULL )
150 return NULL;
151
152 T *p = (T *)pReg->pInfo->createPlugin();
153 hObj.insert( (int )p, pReg );
154 //printf("pReg: %08X, pPlug: %08X\n", pReg, p );
155
156 return p;
141 } 157 }
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 158
159 bool hasPlugin( const char *lpName ) 159 bool hasPlugin( const char *lpName )
160 { 160 {
161 if( hPlugin[lpName] == NULL ) 161 if( hPlugin[lpName] == NULL )
162 return false; 162 return false;
163 return true; 163 return true;
164 } 164 }
165 165
166 void destroy( T *pPlug ) 166 void destroy( T *pPlug )
167 { 167 {
168 PluginReg *pReg = (PluginReg *)hObj[pPlug]; 168 PluginReg *pReg = (PluginReg *)hObj.get((int)pPlug);
169 //printf("pReg: %08X, pPlug: %08X\n", pReg, pPlug ); 169 //printf("pReg: %08X, pPlug: %08X\n", pReg, pPlug );
170 if( pReg == NULL ) 170 if( pReg == NULL )
171 return; 171 return;
172 172
173 pReg->pInfo->destroyPlugin( pPlug ); 173 pReg->pInfo->destroyPlugin( pPlug );
174 174
175 hObj.del( pPlug ); 175 hObj.erase( (int)pPlug );
176 } 176 }
177 177
178 void unloadAll() 178 void unloadAll()
179 {
180 std::list<PluginReg *>::iterator i;
181 for( i = lPlugin.begin(); i != lPlugin.end(); i++ )
182 { 179 {
183 if( (*i)->bBuiltin == false ) 180 for( PluginHash::iterator i = hPlugin.begin();
181 i != hPlugin.end(); i++ )
184 { 182 {
185 dlclose( (*i)->dlHandle ); 183 if( (*i)->bBuiltin == false )
184 {
185 dlclose( (*i)->dlHandle );
186 }
187 delete (*i);
186 } 188 }
187 delete (*i); 189 hPlugin.clear();
188 } 190 }
189 hPlugin.clear();
190 }
191 191
192private: 192 private:
193 std::list<PluginReg *> lPlugin; 193 PluginHash hPlugin;
194 HashTable hPlugin; 194 InstHash hObj;
195 HashTable hObj; 195 };
196}; 196}
197 197
198#endif 198#endif