Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Class Members | File Members

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  * $Log: plugin.h,v $
00011  * Revision 1.11.2.1  2005/06/07 10:54:14  csoutheren
00012  * Backported fix from Atlas head
00013  *
00014  * Revision 1.13  2005/06/07 00:42:55  csoutheren
00015  * Apply patch 1214249 to fix crash with Suse 9.3. Thanks to Stefan Bruns
00016  *
00017  * Revision 1.11  2004/08/16 11:57:47  csoutheren
00018  * More changes for VS.net
00019  *
00020  * Revision 1.10  2004/08/16 10:55:09  csoutheren
00021  * Fixed problems compiling under Linux
00022  *
00023  * Revision 1.9  2004/08/16 06:40:59  csoutheren
00024  * Added adapters template to make device plugins available via the abstract factory interface
00025  *
00026  * Revision 1.8  2004/06/21 10:40:02  csoutheren
00027  * Fixed problem with dynamic plugins
00028  *
00029  * Revision 1.7  2004/06/21 00:57:40  csoutheren
00030  * Changed service plugin static registration to use attribute (( constructor ))
00031  *
00032  * Revision 1.6  2003/12/19 00:34:27  csoutheren
00033  * Ensured that older compilers do not get confused about functions wth empty
00034  * parameter lists. Thanks to Kilian Krause
00035  *
00036  * Revision 1.5  2003/11/19 09:29:19  csoutheren
00037  * Added super hack to avoid problems with multiple plugins in a single file
00038  *
00039  * Revision 1.4  2003/11/12 10:24:35  csoutheren
00040  * Changes to allow operation of static plugins under Windows
00041  *
00042  * Revision 1.3  2003/11/12 06:58:21  csoutheren
00043  * Changes to help in making static plugins autoregister under Windows
00044  *
00045  * Revision 1.2  2003/11/12 03:26:17  csoutheren
00046  * Initial version of plugin code from Snark of GnomeMeeting with changes
00047  *    by Craig Southeren os Post Increment
00048  *
00049  *
00050  */
00051 
00052 #ifndef _PLUGIN_H
00053 #define _PLUGIN_H
00054 
00056 //
00057 //  these templates implement an adapter to make the old style device plugins appear in the new factory system
00058 //
00059 
00060 #include <ptlib/pfactory.h>
00061 
00062 template <class _Abstract_T, typename _Key_T = PString>
00063 class PDevicePluginFactory : public PFactory<_Abstract_T, _Key_T>
00064 {
00065   public:
00066     class Worker : public PFactory<_Abstract_T, _Key_T>::WorkerBase 
00067     {
00068       public:
00069         Worker(const _Key_T & key, bool singleton = false)
00070           : PFactory<_Abstract_T, _Key_T>::WorkerBase(singleton)
00071         {
00072           PFactory<_Abstract_T, _Key_T>::Register(key, this);
00073         }
00074 
00075         ~Worker()
00076         {
00077           typedef typename PFactory<_Abstract_T, _Key_T>::WorkerBase WorkerBase_T;
00078           typedef std::map<_Key_T, WorkerBase_T *> KeyMap_T;
00079           _Key_T key;
00080 
00081           KeyMap_T km = PFactory<_Abstract_T, _Key_T>::GetKeyMap();
00082 
00083           typename KeyMap_T::const_iterator entry;
00084           for (entry = km.begin(); entry != km.end(); ++entry) {
00085             if (entry->second == this) {
00086               key = entry->first;
00087               break;
00088             }
00089           }
00090           if (key != NULL)
00091             PFactory<_Abstract_T, _Key_T>::Unregister(key);
00092         }
00093 
00094       protected:
00095         virtual _Abstract_T * Create(const _Key_T & key) const;
00096     };
00097 };
00098 
00099 class PDevicePluginAdapterBase
00100 {
00101   public:
00102     PDevicePluginAdapterBase()
00103     { }
00104     virtual ~PDevicePluginAdapterBase()
00105     { }
00106     virtual void CreateFactory(const PString & device) = 0;
00107 };
00108 
00109 template <typename DeviceBase>
00110 class PDevicePluginAdapter : public PDevicePluginAdapterBase
00111 {
00112   public:
00113     typedef PDevicePluginFactory<DeviceBase> Factory_T;
00114     typedef typename Factory_T::Worker Worker_T;
00115     void CreateFactory(const PString & device)
00116     {
00117       if (!(Factory_T::IsRegistered(device)))
00118         new Worker_T(device, FALSE);
00119     }
00120 };
00121 
00122 #define PWLIB_PLUGIN_API_VERSION 0
00123 
00125 //
00126 //  Ancestor Service descriptor for plugins
00127 //
00128 
00129 class PPluginServiceDescriptor 
00130 {
00131   public:
00132     PPluginServiceDescriptor(unsigned (*_GetPluginAPIVersion)())
00133       : GetPluginAPIVersion(_GetPluginAPIVersion)
00134     { }
00135 
00136     unsigned (*GetPluginAPIVersion)();
00137 };
00138 
00139 
00141 //
00142 // Define a service provided by a plugin, which consists of the following:
00143 //
00144 //    serviceType - the base class name of the service which is used to identify
00145 //                  the service type, such as PSoundChannel, 
00146 //
00147 //    serviceName - the name of the service provided by the plugin. This will usually
00148 //                  be related to the class implementing the service, such as:
00149 //                       service name = OSS, class name = PSoundChannelOSS
00150 //
00151 //    descriptor  - a pointer to a class containing pointers to any static functions
00152 //                  for this class
00153 //   
00154 //
00155 
00156 class PPluginService: public PObject
00157 {
00158   public:
00159     PPluginService(const PString & _serviceName,
00160                    const PString & _serviceType,
00161                    PPluginServiceDescriptor *_descriptor)
00162     {
00163       serviceName = _serviceName;
00164       serviceType = _serviceType;
00165       descriptor  = _descriptor;
00166     }
00167 
00168     PString serviceName;
00169     PString serviceType;
00170     PPluginServiceDescriptor * descriptor;
00171 };
00172 
00174 
00175 #define PCREATE_PLUGIN_VERSION_DECLARE 
00176 
00177 #define PCREATE_STATIC_PLUGIN_VERSION_FN(serviceName, serviceType) \
00178 unsigned PPlugin_##serviceType##_##serviceName##_GetVersion() \
00179   { return PWLIB_PLUGIN_API_VERSION; } 
00180 
00181 #define PCREATE_DYNAMIC_PLUGIN_VERSION_FN(serviceName, serviceType) \
00182 extern "C" unsigned PWLibPlugin_GetAPIVersion (void) \
00183 { return PWLIB_PLUGIN_API_VERSION; } 
00184 
00186 //
00187 //  These crazy macros are needed to cause automatic registration of 
00188 //  static plugins. They are made more complex by the arcane behaviour
00189 //  of the Windows link system that requires an external reference in the
00190 //  object module before it will instantiate any globals in in it
00191 //
00192 
00193 #define PCREATE_PLUGIN_REGISTERER(serviceName, serviceType, descriptor) \
00194 class PPlugin_##serviceType##_##serviceName##_Registration { \
00195   public: \
00196     PPlugin_##serviceType##_##serviceName##_Registration(PPluginManager * pluginMgr) \
00197     { \
00198       static PDevicePluginFactory<serviceType>::Worker factory(#serviceName); \
00199       pluginMgr->RegisterService(#serviceName, #serviceType, descriptor); \
00200     } \
00201     int kill_warning; \
00202 }; \
00203 
00204 #ifdef _WIN32
00205 
00206 #define PCREATE_PLUGIN_STATIC(serviceName, serviceType, descriptor) \
00207 PCREATE_PLUGIN_REGISTERER(serviceName, serviceType, descriptor) \
00208 PPlugin_##serviceType##_##serviceName##_Registration \
00209   PPlugin_##serviceType##_##serviceName##_Registration_Instance(&PPluginManager::GetPluginManager()); \
00210 
00211 #define PWLIB_STATIC_LOAD_PLUGIN(cls) \
00212   class PPlugin_##cls##_Registration; \
00213   extern PPlugin_##cls##_Registration PPlugin_##cls##_Registration_Instance; \
00214   static PPlugin_##cls##_Registration * PPlugin_##cls##_Registration_Static_Library_Loader = &PPlugin_##cls##_Registration_Instance
00215 
00216 #else
00217 
00218 #define PCREATE_PLUGIN_STATIC(serviceName, serviceType, descriptor) \
00219 static void __attribute__ (( constructor )) PWLIB_StaticLoader_##serviceName##_##serviceType() \
00220 { PPluginManager::GetPluginManager().RegisterService(#serviceName, #serviceType, descriptor); } \
00221 
00222 #define PWLIB_STATIC_LOAD_PLUGIN(cls) 
00223 
00224 #endif
00225 
00226 #define PCREATE_PLUGIN_DYNAMIC(serviceName, serviceType, descriptor) \
00227 PCREATE_PLUGIN_REGISTERER(serviceName, serviceType, descriptor) \
00228 extern "C" void PWLibPlugin_TriggerRegister (PPluginManager * pluginMgr) { \
00229 PPlugin_##serviceType##_##serviceName##_Registration \
00230      pplugin_##serviceType##_##serviceName##_Registration_Instance(pluginMgr); \
00231      pplugin_##serviceType##_##serviceName##_Registration_Instance.kill_warning = 0; \
00232 } 
00233 
00235 
00236 #if defined(P_HAS_PLUGINS) && ! defined(P_FORCE_STATIC_PLUGIN)
00237 #  define PCREATE_PLUGIN(serviceName, serviceType, descriptor) \
00238     PCREATE_PLUGIN_DYNAMIC(serviceName, serviceType, descriptor)
00239 
00240 #  define PCREATE_PLUGIN_VERSION_FN(serviceName, serviceType) \
00241     PCREATE_DYNAMIC_PLUGIN_VERSION_FN(serviceName, serviceType)
00242 
00243 #  define PPLUGIN_VERSION_FN(serviceName, serviceType) \
00244     PWLibPlugin_GetAPIVersion
00245 
00246 #else
00247 
00248 #  define PCREATE_PLUGIN(serviceName, serviceType, descriptor) \
00249     PCREATE_PLUGIN_STATIC(serviceName, serviceType, descriptor)
00250 
00251 #  define PCREATE_PLUGIN_VERSION_FN(serviceName, serviceType) \
00252     PCREATE_STATIC_PLUGIN_VERSION_FN(serviceName, serviceType)
00253 
00254 #  define PPLUGIN_VERSION_FN(serviceName, serviceType) \
00255     PPlugin_##serviceType##_##serviceName##_GetVersion
00256 
00257 #endif
00258 
00260 
00261 #endif

Generated on Wed Sep 28 10:27:33 2005 for PWLib by  doxygen 1.4.4