plugin.h

Go to the documentation of this file.
00001 /*
00002  * plugin.h
00003  *
00004  * Plugin Class Declarations
00005  *
00006  * Portable Windows Library
00007  *
00008  * Contributor(s): Snark at GnomeMeeting
00009  *
00010  * $Revision: 21177 $
00011  * $Author: ms30002000 $
00012  * $Date: 2008-09-27 20:35:51 +0000 (Sat, 27 Sep 2008) $
00013  */
00014 
00015 #ifndef _PLUGIN_H
00016 #define _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 _Abstract_T, typename _Key_T = PString>
00026 class PDevicePluginFactory : public PFactory<_Abstract_T, _Key_T>
00027 {
00028   public:
00029     class Worker : public PFactory<_Abstract_T, _Key_T>::WorkerBase 
00030     {
00031       public:
00032         Worker(const _Key_T & key, bool singleton = false)
00033           : PFactory<_Abstract_T, _Key_T>::WorkerBase(singleton)
00034         {
00035           PFactory<_Abstract_T, _Key_T>::Register(key, this);
00036         }
00037 
00038         ~Worker()
00039         {
00040           typedef typename PFactory<_Abstract_T, _Key_T>::WorkerBase WorkerBase_T;
00041           typedef std::map<_Key_T, WorkerBase_T *> KeyMap_T;
00042           _Key_T key;
00043 
00044           KeyMap_T km = PFactory<_Abstract_T, _Key_T>::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<_Abstract_T, _Key_T>::Unregister(key);
00055         }
00056 
00057       protected:
00058         virtual _Abstract_T * Create(const _Key_T & 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 //  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 & _serviceName,
00141                    const PString & _serviceType,
00142                    PPluginServiceDescriptor *_descriptor)
00143     {
00144       serviceName = _serviceName;
00145       serviceType = _serviceType;
00146       descriptor  = _descriptor;
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 
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 // Win32 only has static plugins at present, maybe one day ...
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 #endif

Generated on Mon Feb 23 01:57:54 2009 for PTLib by  doxygen 1.5.1