PTLib
Version 2.10.4
|
00001 /* 00002 * plugin.h 00003 * 00004 * Plugin Class Declarations 00005 * 00006 * Portable Windows Library 00007 * 00008 * Contributor(s): Snark at GnomeMeeting 00009 * 00010 * $Revision: 25329 $ 00011 * $Author: ededu $ 00012 * $Date: 2011-03-15 18:03:58 -0500 (Tue, 15 Mar 2011) $ 00013 */ 00014 00015 #ifndef PTLIB_PLUGIN_H 00016 #define PTLIB_PLUGIN_H 00017 00019 // 00020 // these templates implement an adapter to make the old style device plugins appear in the new factory system 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, false); 00082 } 00083 }; 00084 00085 00086 #ifndef PWLIB_PLUGIN_API_VERSION 00087 #define PWLIB_PLUGIN_API_VERSION 0 00088 #endif 00089 00090 00092 // 00093 // Ancestor Service descriptor for plugins 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 // Define a service provided by a plugin, which consists of the following: 00124 // 00125 // serviceType - the base class name of the service which is used to identify 00126 // the service type, such as PSoundChannel, 00127 // 00128 // serviceName - the name of the service provided by the plugin. This will usually 00129 // be related to the class implementing the service, such as: 00130 // service name = OSS, class name = PSoundChannelOSS 00131 // 00132 // descriptor - a pointer to a class containing pointers to any static functions 00133 // for this class 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 // These crazy macros are needed to cause automatic registration of 00158 // static plugins. They are made more complex by the arcane behaviour 00159 // of the Windows link system that requires an external reference in the 00160 // object module before it will instantiate any globals in in it 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 int PPlugin_##serviceType##_##serviceName##_link() { return 0; } 00181 00182 #define PPLUGIN_STATIC_LOAD(serviceName, serviceType) \ 00183 extern int PPlugin_##serviceType##_##serviceName##_link(); \ 00184 int const PPlugin_##serviceType##_##serviceName##_loader = PPlugin_##serviceType##_##serviceName##_link(); 00185 00186 // always define static plugins in Windows, since otherwise they seem not to work 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 int PPlugin_##serviceType##_##serviceName##_link() { return 0; } 00198 00199 #else 00200 #define PCREATE_PLUGIN_STATIC(serviceName, serviceType, descriptor) \ 00201 extern int PWLIB_gStaticLoader__##serviceName##_##serviceType; \ 00202 static int PWLIB_StaticLoader_##serviceName##_##serviceType() \ 00203 { PPluginManager::GetPluginManager().RegisterService(#serviceName, #serviceType, descriptor); return 1; } \ 00204 int PWLIB_gStaticLoader__##serviceName##_##serviceType = PWLIB_StaticLoader_##serviceName##_##serviceType(); \ 00205 int PPlugin_##serviceType##_##serviceName##_link() { return 0; } 00206 #endif 00207 00208 #define PPLUGIN_STATIC_LOAD(serviceName, serviceType) \ 00209 extern int PPlugin_##serviceType##_##serviceName##_link(); \ 00210 int const PPlugin_##serviceType##_##serviceName##_loader = PPlugin_##serviceType##_##serviceName##_link(); 00211 00212 #ifndef P_SHAREDLIB 00213 #ifndef P_FORCE_STATIC_PLUGIN 00214 #define P_FORCE_STATIC_PLUGIN 1 00215 #endif 00216 #endif 00217 00218 #endif 00219 00220 00222 00223 #if defined(P_PLUGINS) && ! defined(P_FORCE_STATIC_PLUGIN) 00224 00225 # define PCREATE_PLUGIN(serviceName, serviceType, descriptor) \ 00226 PCREATE_PLUGIN_REGISTERER(serviceName, serviceType, descriptor) \ 00227 extern "C" void PWLibPlugin_TriggerRegister (PPluginManager * pluginMgr) { \ 00228 PPlugin_##serviceType##_##serviceName##_Registration \ 00229 pplugin_##serviceType##_##serviceName##_Registration_Instance(pluginMgr); \ 00230 pplugin_##serviceType##_##serviceName##_Registration_Instance.kill_warning = 0; \ 00231 } \ 00232 extern "C" unsigned PWLibPlugin_GetAPIVersion (void) \ 00233 { return PWLIB_PLUGIN_API_VERSION; } 00234 00235 #else 00236 00237 # define PCREATE_PLUGIN(serviceName, serviceType, descriptor) \ 00238 PCREATE_PLUGIN_STATIC(serviceName, serviceType, descriptor) 00239 00240 #endif 00241 00243 00244 00245 #endif // PTLIB_PLUGIN_H 00246 00247 00248 // End Of File ///////////////////////////////////////////////////////////////