diff options
author | Mike Buland <eichlan@xagasoft.com> | 2006-06-05 20:04:28 +0000 |
---|---|---|
committer | Mike Buland <eichlan@xagasoft.com> | 2006-06-05 20:04:28 +0000 |
commit | fa7df2006c0e241314212644c1ec5e362220defd (patch) | |
tree | 9befeb1b72869a4989fdf155414e5d0800aa9ea5 | |
parent | 390a5110c6dfe439dddb5f7d2bb6f615c1d336ad (diff) | |
download | libbu++-fa7df2006c0e241314212644c1ec5e362220defd.tar.gz libbu++-fa7df2006c0e241314212644c1ec5e362220defd.tar.bz2 libbu++-fa7df2006c0e241314212644c1ec5e362220defd.tar.xz libbu++-fa7df2006c0e241314212644c1ec5e362220defd.zip |
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...
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | src/plugger.cpp | 1 | ||||
-rw-r--r-- | src/plugger.h | 124 | ||||
-rw-r--r-- | src/plugin.cpp | 10 | ||||
-rw-r--r-- | src/plugin.h | 14 | ||||
-rw-r--r-- | src/test/params.cpp | 3 | ||||
-rw-r--r-- | src/test/plugin/main.cpp | 14 |
7 files changed, 166 insertions, 2 deletions
@@ -42,7 +42,7 @@ $(LIB): $(OBJS) | |||
42 | 42 | ||
43 | $(TESTS): $(ATOBJS) $(LIB) | 43 | $(TESTS): $(ATOBJS) $(LIB) |
44 | echo "$(TXTLNK)$@" | 44 | echo "$(TXTLNK)$@" |
45 | g++ $(LDFLAGS) -ggdb $(filter %$(patsubst tests/%,%,$@).o, $(TOBJS) ) $(patsubst %.cpp,%.o,$(wildcard $(filter %$(patsubst tests/%,%,$@), $(TDIRS))/*.cpp)) -L. -lbu++ -o $@ | 45 | g++ $(LDFLAGS) -ggdb $(filter %$(patsubst tests/%,%,$@).o, $(TOBJS) ) $(patsubst %.cpp,%.o,$(wildcard $(filter %$(patsubst tests/%,%,$@), $(TDIRS))/*.cpp)) -L. -lbu++ -ldl -o $@ |
46 | 46 | ||
47 | $(UNIT): $(USRCS) $(LIB) | 47 | $(UNIT): $(USRCS) $(LIB) |
48 | echo "$(TXTLNK)$@" | 48 | echo "$(TXTLNK)$@" |
diff --git a/src/plugger.cpp b/src/plugger.cpp new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/src/plugger.cpp | |||
@@ -0,0 +1 @@ | |||
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 | ||
diff --git a/src/plugin.cpp b/src/plugin.cpp new file mode 100644 index 0000000..ea558fd --- /dev/null +++ b/src/plugin.cpp | |||
@@ -0,0 +1,10 @@ | |||
1 | #include "plugin.h" | ||
2 | |||
3 | Plugin::Plugin() | ||
4 | { | ||
5 | } | ||
6 | |||
7 | Plugin::~Plugin() | ||
8 | { | ||
9 | } | ||
10 | |||
diff --git a/src/plugin.h b/src/plugin.h new file mode 100644 index 0000000..f726867 --- /dev/null +++ b/src/plugin.h | |||
@@ -0,0 +1,14 @@ | |||
1 | #ifndef PLUGIN_H | ||
2 | #define PLUGIN_H | ||
3 | |||
4 | class Plugin | ||
5 | { | ||
6 | public: | ||
7 | Plugin(); | ||
8 | virtual ~Plugin(); | ||
9 | |||
10 | private: | ||
11 | |||
12 | }; | ||
13 | |||
14 | #endif | ||
diff --git a/src/test/params.cpp b/src/test/params.cpp index 7bd2c0c..bb62047 100644 --- a/src/test/params.cpp +++ b/src/test/params.cpp | |||
@@ -16,7 +16,8 @@ int main( int argc, char *argv[] ) | |||
16 | "Set the bool off." }, | 16 | "Set the bool off." }, |
17 | { "char", 'c', PPROC_CHAR, NULL, &cChar, | 17 | { "char", 'c', PPROC_CHAR, NULL, &cChar, |
18 | "Set the char." }, | 18 | "Set the char." }, |
19 | { NULL, '\0', 0, NULL, NULL, NULL } | 19 | { NULL, '\0',0, NULL, NULL, |
20 | NULL } | ||
20 | }; | 21 | }; |
21 | 22 | ||
22 | processParams( argc, argv, table ); | 23 | processParams( argc, argv, table ); |
diff --git a/src/test/plugin/main.cpp b/src/test/plugin/main.cpp new file mode 100644 index 0000000..51c8390 --- /dev/null +++ b/src/test/plugin/main.cpp | |||
@@ -0,0 +1,14 @@ | |||
1 | #include "plugger.h" | ||
2 | #include "plugin.h" | ||
3 | |||
4 | int main() | ||
5 | { | ||
6 | Plugger<Plugin> p; | ||
7 | |||
8 | p.registerExternalPlugin( "./guy.so", "Guy" ); | ||
9 | |||
10 | Plugin *t = p.instantiate( "Guy" ); | ||
11 | |||
12 | p.destroy( t ); | ||
13 | } | ||
14 | |||