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: 19008 $
00011  * $Author: rjongbloed $
00012  * $Date: 2007-11-29 09:17:41 +0000 (Thu, 29 Nov 2007) $
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 PStringList GetDeviceNames(int userData) const = 0;
00116     virtual bool        ValidateDeviceName(const PString & deviceName, int userData) const;
00117         virtual bool        GetDeviceCapabilities(const PString & deviceName, 
00118                                                                                                  void * capabilities) const;
00119 };
00120 
00121 
00123 //
00124 // Define a service provided by a plugin, which consists of the following:
00125 //
00126 //    serviceType - the base class name of the service which is used to identify
00127 //                  the service type, such as PSoundChannel, 
00128 //
00129 //    serviceName - the name of the service provided by the plugin. This will usually
00130 //                  be related to the class implementing the service, such as:
00131 //                       service name = OSS, class name = PSoundChannelOSS
00132 //
00133 //    descriptor  - a pointer to a class containing pointers to any static functions
00134 //                  for this class
00135 //   
00136 //
00137 
00138 class PPluginService: public PObject
00139 {
00140   public:
00141     PPluginService(const PString & _serviceName,
00142                    const PString & _serviceType,
00143                    PPluginServiceDescriptor *_descriptor)
00144     {
00145       serviceName = _serviceName;
00146       serviceType = _serviceType;
00147       descriptor  = _descriptor;
00148     }
00149 
00150     PString serviceName;
00151     PString serviceType;
00152     PPluginServiceDescriptor * descriptor;
00153 };
00154 
00155 
00157 //
00158 //  These crazy macros are needed to cause automatic registration of 
00159 //  static plugins. They are made more complex by the arcane behaviour
00160 //  of the Windows link system that requires an external reference in the
00161 //  object module before it will instantiate any globals in in it
00162 //
00163 
00164 #define PCREATE_PLUGIN_REGISTERER(serviceName, serviceType, descriptor) \
00165 class PPlugin_##serviceType##_##serviceName##_Registration { \
00166   public: \
00167     PPlugin_##serviceType##_##serviceName##_Registration(PPluginManager * pluginMgr) \
00168     { \
00169       static PDevicePluginFactory<serviceType>::Worker factory(#serviceName); \
00170       pluginMgr->RegisterService(#serviceName, #serviceType, descriptor); \
00171     } \
00172     int kill_warning; \
00173 }; \
00174 
00175 #ifdef _WIN32
00176 
00177 #define PCREATE_PLUGIN_STATIC(serviceName, serviceType, descriptor) \
00178 PCREATE_PLUGIN_REGISTERER(serviceName, serviceType, descriptor) \
00179 PPlugin_##serviceType##_##serviceName##_Registration \
00180   PPlugin_##serviceType##_##serviceName##_Registration_Instance(&PPluginManager::GetPluginManager()); \
00181 
00182 #define PWLIB_STATIC_LOAD_PLUGIN(serviceName, serviceType) \
00183   class PPlugin_##serviceType##_##serviceName##_Registration; \
00184   extern PPlugin_##serviceType##_##serviceName##_Registration PPlugin_##serviceType##_##serviceName##_Registration_Instance; \
00185   static PPlugin_##serviceType##_##serviceName##_Registration * PPlugin_##serviceType##_##serviceName##_Registration_Static_Library_Loader = &PPlugin_##serviceType##_##serviceName##_Registration_Instance;
00186 
00187 // Win32 onl;y has static plugins at present, maybe one day ...
00188 #define P_FORCE_STATIC_PLUGIN
00189 
00190 #else
00191 
00192 #ifdef USE_GCC
00193 #define PCREATE_PLUGIN_STATIC(serviceName, serviceType, descriptor) \
00194 static void __attribute__ (( constructor )) PWLIB_StaticLoader_##serviceName##_##serviceType() \
00195 { PPluginManager::GetPluginManager().RegisterService(#serviceName, #serviceType, descriptor); } \
00196 
00197 #else
00198 #define PCREATE_PLUGIN_STATIC(serviceName, serviceType, descriptor) \
00199 extern int PWLIB_gStaticLoader__##serviceName##_##serviceType; \
00200 static int PWLIB_StaticLoader_##serviceName##_##serviceType() \
00201 { PPluginManager::GetPluginManager().RegisterService(#serviceName, #serviceType, descriptor); return 1; } \
00202 int PWLIB_gStaticLoader__##serviceName##_##serviceType =  PWLIB_StaticLoader_##serviceName##_##serviceType(); 
00203 #endif
00204 #define PWLIB_STATIC_LOAD_PLUGIN(serviceName, serviceType) 
00205 
00206 #endif
00207 
00208 
00210 
00211 #if defined(P_HAS_PLUGINS) && ! defined(P_FORCE_STATIC_PLUGIN)
00212 
00213 #  define PCREATE_PLUGIN(serviceName, serviceType, descriptor) \
00214     PCREATE_PLUGIN_REGISTERER(serviceName, serviceType, descriptor) \
00215     extern "C" void PWLibPlugin_TriggerRegister (PPluginManager * pluginMgr) { \
00216     PPlugin_##serviceType##_##serviceName##_Registration \
00217         pplugin_##serviceType##_##serviceName##_Registration_Instance(pluginMgr); \
00218         pplugin_##serviceType##_##serviceName##_Registration_Instance.kill_warning = 0; \
00219     } \
00220     extern "C" unsigned PWLibPlugin_GetAPIVersion (void) \
00221     { return PWLIB_PLUGIN_API_VERSION; }
00222 
00223 #else
00224 
00225 #  define PCREATE_PLUGIN(serviceName, serviceType, descriptor) \
00226     PCREATE_PLUGIN_STATIC(serviceName, serviceType, descriptor)
00227 
00228 #endif
00229 
00231 
00232 #endif

Generated on Mon Dec 10 11:18:57 2007 for PTLib by  doxygen 1.5.1