00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #ifndef PTLIB_PLUGIN_H
00016 #define PTLIB_PLUGIN_H
00017
00019
00020
00021
00022
00023 #include <ptlib/pfactory.h>
00024
00025 template <class AbstractClass, typename KeyType = PString>
00026 class PDevicePluginFactory : public PFactory<AbstractClass, KeyType>
00027 {
00028 public:
00029 class Worker : public PFactory<AbstractClass, KeyType>::WorkerBase
00030 {
00031 public:
00032 Worker(const KeyType & key, bool singleton = false)
00033 : PFactory<AbstractClass, KeyType>::WorkerBase(singleton)
00034 {
00035 PFactory<AbstractClass, KeyType>::Register(key, this);
00036 }
00037
00038 ~Worker()
00039 {
00040 typedef typename PFactory<AbstractClass, KeyType>::WorkerBase WorkerBase_T;
00041 typedef std::map<KeyType, WorkerBase_T *> KeyMap_T;
00042 KeyType key;
00043
00044 KeyMap_T km = PFactory<AbstractClass, KeyType>::GetKeyMap();
00045
00046 typename KeyMap_T::const_iterator entry;
00047 for (entry = km.begin(); entry != km.end(); ++entry) {
00048 if (entry->second == this) {
00049 key = entry->first;
00050 break;
00051 }
00052 }
00053 if (key != NULL)
00054 PFactory<AbstractClass, KeyType>::Unregister(key);
00055 }
00056
00057 protected:
00058 virtual AbstractClass * Create(const KeyType & key) const;
00059 };
00060 };
00061
00062 class PDevicePluginAdapterBase
00063 {
00064 public:
00065 PDevicePluginAdapterBase()
00066 { }
00067 virtual ~PDevicePluginAdapterBase()
00068 { }
00069 virtual void CreateFactory(const PString & device) = 0;
00070 };
00071
00072 template <typename DeviceBase>
00073 class PDevicePluginAdapter : public PDevicePluginAdapterBase
00074 {
00075 public:
00076 typedef PDevicePluginFactory<DeviceBase> Factory_T;
00077 typedef typename Factory_T::Worker Worker_T;
00078 void CreateFactory(const PString & device)
00079 {
00080 if (!(Factory_T::IsRegistered(device)))
00081 new Worker_T(device, PFalse);
00082 }
00083 };
00084
00085
00086 #ifndef PWLIB_PLUGIN_API_VERSION
00087 #define PWLIB_PLUGIN_API_VERSION 0
00088 #endif
00089
00090
00092
00093
00094
00095
00096 class PPluginServiceDescriptor
00097 {
00098 public:
00099 PPluginServiceDescriptor() { version = PWLIB_PLUGIN_API_VERSION; }
00100 virtual ~PPluginServiceDescriptor() { }
00101
00102 virtual unsigned GetPluginAPIVersion() const { return version; }
00103
00104 protected:
00105 unsigned version;
00106 };
00107
00108
00109 class PDevicePluginServiceDescriptor : public PPluginServiceDescriptor
00110 {
00111 public:
00112 static const char SeparatorChar;
00113
00114 virtual PObject * CreateInstance(int userData) const = 0;
00115 virtual PStringArray GetDeviceNames(int userData) const = 0;
00116 virtual bool ValidateDeviceName(const PString & deviceName, int userData) const;
00117 virtual bool GetDeviceCapabilities(const PString & deviceName, void * capabilities) const;
00118 };
00119
00120
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137 class PPluginService: public PObject
00138 {
00139 public:
00140 PPluginService(const PString & name,
00141 const PString & type,
00142 PPluginServiceDescriptor * desc)
00143 : serviceName(name)
00144 , serviceType(type)
00145 , descriptor(desc)
00146 {
00147 }
00148
00149 PString serviceName;
00150 PString serviceType;
00151 PPluginServiceDescriptor * descriptor;
00152 };
00153
00154
00156
00157
00158
00159
00160
00161
00162
00163 #define PCREATE_PLUGIN_REGISTERER(serviceName, serviceType, descriptor) \
00164 class PPlugin_##serviceType##_##serviceName##_Registration { \
00165 public: \
00166 PPlugin_##serviceType##_##serviceName##_Registration(PPluginManager * pluginMgr) \
00167 { \
00168 static PDevicePluginFactory<serviceType>::Worker factory(#serviceName); \
00169 pluginMgr->RegisterService(#serviceName, #serviceType, descriptor); \
00170 } \
00171 int kill_warning; \
00172 }; \
00173
00174 #ifdef _WIN32
00175
00176 #define PCREATE_PLUGIN_STATIC(serviceName, serviceType, descriptor) \
00177 PCREATE_PLUGIN_REGISTERER(serviceName, serviceType, descriptor) \
00178 PPlugin_##serviceType##_##serviceName##_Registration \
00179 PPlugin_##serviceType##_##serviceName##_Registration_Instance(&PPluginManager::GetPluginManager()); \
00180
00181 #define PWLIB_STATIC_LOAD_PLUGIN(serviceName, serviceType) \
00182 class PPlugin_##serviceType##_##serviceName##_Registration; \
00183 extern PPlugin_##serviceType##_##serviceName##_Registration PPlugin_##serviceType##_##serviceName##_Registration_Instance; \
00184 static PPlugin_##serviceType##_##serviceName##_Registration * PPlugin_##serviceType##_##serviceName##_Registration_Static_Library_Loader = &PPlugin_##serviceType##_##serviceName##_Registration_Instance;
00185
00186
00187 #ifndef P_FORCE_STATIC_PLUGIN
00188 #define P_FORCE_STATIC_PLUGIN 1
00189 #endif
00190
00191 #else
00192
00193 #ifdef USE_GCC
00194 #define PCREATE_PLUGIN_STATIC(serviceName, serviceType, descriptor) \
00195 static void __attribute__ (( constructor )) PWLIB_StaticLoader_##serviceName##_##serviceType() \
00196 { PPluginManager::GetPluginManager().RegisterService(#serviceName, #serviceType, descriptor); } \
00197
00198 #else
00199 #define PCREATE_PLUGIN_STATIC(serviceName, serviceType, descriptor) \
00200 extern int PWLIB_gStaticLoader__##serviceName##_##serviceType; \
00201 static int PWLIB_StaticLoader_##serviceName##_##serviceType() \
00202 { PPluginManager::GetPluginManager().RegisterService(#serviceName, #serviceType, descriptor); return 1; } \
00203 int PWLIB_gStaticLoader__##serviceName##_##serviceType = PWLIB_StaticLoader_##serviceName##_##serviceType();
00204 #endif
00205 #define PWLIB_STATIC_LOAD_PLUGIN(serviceName, serviceType)
00206
00207 #endif
00208
00209
00211
00212 #if defined(P_PLUGINS) && ! defined(P_FORCE_STATIC_PLUGIN)
00213
00214 # define PCREATE_PLUGIN(serviceName, serviceType, descriptor) \
00215 PCREATE_PLUGIN_REGISTERER(serviceName, serviceType, descriptor) \
00216 extern "C" void PWLibPlugin_TriggerRegister (PPluginManager * pluginMgr) { \
00217 PPlugin_##serviceType##_##serviceName##_Registration \
00218 pplugin_##serviceType##_##serviceName##_Registration_Instance(pluginMgr); \
00219 pplugin_##serviceType##_##serviceName##_Registration_Instance.kill_warning = 0; \
00220 } \
00221 extern "C" unsigned PWLibPlugin_GetAPIVersion (void) \
00222 { return PWLIB_PLUGIN_API_VERSION; }
00223
00224 #else
00225
00226 # define PCREATE_PLUGIN(serviceName, serviceType, descriptor) \
00227 PCREATE_PLUGIN_STATIC(serviceName, serviceType, descriptor)
00228
00229 #endif
00230
00232
00233
00234 #endif // PTLIB_PLUGIN_H
00235
00236
00237