PTLib Version 2.12.9

- Main Page
- Related Pages
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
plugin.h
Go to the documentation of this file.
1 /*
2 * plugin.h
3 *
4 * Plugin Class Declarations
5 *
6 * Portable Windows Library
7 *
8 * Contributor(s): Snark at GnomeMeeting
9 *
10 * $Revision: 26992 $
11 * $Author: rjongbloed $
12 * $Date: 2012-02-16 17:25:26 +1100 (Thu, 16 Feb 2012) $
13 */
14
15 #ifndef PTLIB_PLUGIN_H
16 #define PTLIB_PLUGIN_H
17
19 //
20 // these templates implement an adapter to make the old style device plugins appear in the new factory system
21 //
22
23 #include <ptlib/pfactory.h>
24
25 template <class AbstractClass, typename KeyType = PDefaultPFactoryKey>
26 class PDevicePluginFactory : public PFactory<AbstractClass, KeyType>
27 {
28 public:
29 typedef PFactory<AbstractClass, KeyType> Base_T;
30 typedef typename Base_T::WorkerBase WorkerBase_T;
31
32 class Worker : protected WorkerBase_T
33 {
34 public:
35 Worker(const KeyType & key, bool singleton = false)
36 : WorkerBase_T(singleton)
37 {
38 Base_T::Register(key, this);
39 }
40
41 ~Worker()
42 {
43 Base_T::Unregister(this);
44 }
45
46 protected:
47 virtual AbstractClass * Create(const KeyType & key) const;
48 };
49 };
50
51 class PDevicePluginAdapterBase
52 {
53 public:
54 PDevicePluginAdapterBase()
55 { }
56 virtual ~PDevicePluginAdapterBase()
57 { }
58 virtual void CreateFactory(const PString & device) = 0;
59 };
60
61 template <typename DeviceBase>
62 class PDevicePluginAdapter : public PDevicePluginAdapterBase
63 {
64 public:
65 typedef PDevicePluginFactory<DeviceBase> Factory_T;
66 typedef typename Factory_T::Worker Worker_T;
67 void CreateFactory(const PString & device)
68 {
69 if (!(Factory_T::IsRegistered(device)))
70 new Worker_T(device, false);
71 }
72 };
73
74
75 #ifndef PWLIB_PLUGIN_API_VERSION
76 #define PWLIB_PLUGIN_API_VERSION 0
77 #endif
78
79
81 //
82 // Ancestor Service descriptor for plugins
83 //
84
85 class PPluginServiceDescriptor
86 {
87 public:
88 PPluginServiceDescriptor() { version = PWLIB_PLUGIN_API_VERSION; }
89 virtual ~PPluginServiceDescriptor() { }
90
91 virtual unsigned GetPluginAPIVersion() const { return version; }
92
93 protected:
94 unsigned version;
95 };
96
97
98 class PDevicePluginServiceDescriptor : public PPluginServiceDescriptor
99 {
100 public:
101 static const char SeparatorChar;
102
103 virtual PObject * CreateInstance(int userData) const = 0;
104 virtual PStringArray GetDeviceNames(int userData) const = 0;
105 virtual bool ValidateDeviceName(const PString & deviceName, int userData) const;
106 virtual bool GetDeviceCapabilities(const PString & deviceName, void * capabilities) const;
107 };
108
109
111 //
112 // Define a service provided by a plugin, which consists of the following:
113 //
114 // serviceType - the base class name of the service which is used to identify
115 // the service type, such as PSoundChannel,
116 //
117 // serviceName - the name of the service provided by the plugin. This will usually
118 // be related to the class implementing the service, such as:
119 // service name = OSS, class name = PSoundChannelOSS
120 //
121 // descriptor - a pointer to a class containing pointers to any static functions
122 // for this class
123 //
124 //
125
126 class PPluginService: public PObject
127 {
128 public:
129 PPluginService(const PString & name,
130 const PString & type,
131 PPluginServiceDescriptor * desc)
132 : serviceName(name)
133 , serviceType(type)
134 , descriptor(desc)
135 {
136 }
137
138 PString serviceName;
139 PString serviceType;
140 PPluginServiceDescriptor * descriptor;
141 };
142
143
145 //
146 // These crazy macros are needed to cause automatic registration of
147 // static plugins. They are made more complex by the arcane behaviour
148 // of the Windows link system that requires an external reference in the
149 // object module before it will instantiate any globals in in it
150 //
151
152 #define PCREATE_PLUGIN_REGISTERER(serviceName, serviceType, descriptor) \
153 class PPlugin_##serviceType##_##serviceName##_Registration { \
154 public: \
155 PPlugin_##serviceType##_##serviceName##_Registration(PPluginManager * pluginMgr) \
156 { \
157 static PDevicePluginFactory<serviceType>::Worker factory(#serviceName); \
158 pluginMgr->RegisterService(#serviceName, #serviceType, descriptor); \
159 } \
160 int kill_warning; \
161 }; \
162
163 #ifdef _WIN32
164
165 #define PCREATE_PLUGIN_STATIC(serviceName, serviceType, descriptor) \
166 PCREATE_PLUGIN_REGISTERER(serviceName, serviceType, descriptor) \
167 PPlugin_##serviceType##_##serviceName##_Registration \
168 PPlugin_##serviceType##_##serviceName##_Registration_Instance(&PPluginManager::GetPluginManager()); \
169 int PPlugin_##serviceType##_##serviceName##_link() { return 0; }
170
171 #define PPLUGIN_STATIC_LOAD(serviceName, serviceType) \
172 extern int PPlugin_##serviceType##_##serviceName##_link(); \
173 int const PPlugin_##serviceType##_##serviceName##_loader = PPlugin_##serviceType##_##serviceName##_link();
174
175 // always define static plugins in Windows, since otherwise they seem not to work
176 #ifndef P_FORCE_STATIC_PLUGIN
177 #define P_FORCE_STATIC_PLUGIN 1
178 #endif
179
180 #else
181
182 #ifdef USE_GCC
183 #define PCREATE_PLUGIN_STATIC(serviceName, serviceType, descriptor) \
184 static void __attribute__ (( constructor )) PWLIB_StaticLoader_##serviceName##_##serviceType() \
185 { PPluginManager::GetPluginManager().RegisterService(#serviceName, #serviceType, descriptor); } \
186 int PPlugin_##serviceType##_##serviceName##_link() { return 0; }
187
188 #else
189 #define PCREATE_PLUGIN_STATIC(serviceName, serviceType, descriptor) \
190 extern int PWLIB_gStaticLoader__##serviceName##_##serviceType; \
191 static int PWLIB_StaticLoader_##serviceName##_##serviceType() \
192 { PPluginManager::GetPluginManager().RegisterService(#serviceName, #serviceType, descriptor); return 1; } \
193 int PWLIB_gStaticLoader__##serviceName##_##serviceType = PWLIB_StaticLoader_##serviceName##_##serviceType(); \
194 int PPlugin_##serviceType##_##serviceName##_link() { return 0; }
195 #endif
196
197 #define PPLUGIN_STATIC_LOAD(serviceName, serviceType) \
198 extern int PPlugin_##serviceType##_##serviceName##_link(); \
199 int const PPlugin_##serviceType##_##serviceName##_loader = PPlugin_##serviceType##_##serviceName##_link();
200
201 #ifndef P_SHAREDLIB
202 #ifndef P_FORCE_STATIC_PLUGIN
203 #define P_FORCE_STATIC_PLUGIN 1
204 #endif
205 #endif
206
207 #endif
208
209
211
212 #if defined(P_PLUGINS) && ! defined(P_FORCE_STATIC_PLUGIN)
213
214 # define PCREATE_PLUGIN(serviceName, serviceType, descriptor) \
215 PCREATE_PLUGIN_REGISTERER(serviceName, serviceType, descriptor) \
216 extern "C" void PWLibPlugin_TriggerRegister (PPluginManager * pluginMgr) { \
217 PPlugin_##serviceType##_##serviceName##_Registration \
218 pplugin_##serviceType##_##serviceName##_Registration_Instance(pluginMgr); \
219 pplugin_##serviceType##_##serviceName##_Registration_Instance.kill_warning = 0; \
220 } \
221 extern "C" unsigned PWLibPlugin_GetAPIVersion (void) \
222 { return PWLIB_PLUGIN_API_VERSION; }
223
224 #else
225
226 # define PCREATE_PLUGIN(serviceName, serviceType, descriptor) \
227 PCREATE_PLUGIN_STATIC(serviceName, serviceType, descriptor)
228
229 #endif
230
232
233
234 #endif // PTLIB_PLUGIN_H
235
236
237 // End Of File ///////////////////////////////////////////////////////////////