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.16  2007/09/04 02:15:53  rjongbloed
00012  * Allow for API versions other than zero.
00013  *
00014  * Revision 1.15  2006/01/08 14:49:08  dsandras
00015  * Several fixes to allow compilation on Open Solaris thanks to Brian Lu <brian.lu _AT_____ sun.com>. Many thanks!
00016  *
00017  * Revision 1.14  2005/08/09 09:08:09  rjongbloed
00018  * Merged new video code from branch back to the trunk.
00019  *
00020  * Revision 1.13.2.1  2005/07/17 09:27:04  rjongbloed
00021  * Major revisions of the PWLib video subsystem including:
00022  *   removal of F suffix on colour formats for vertical flipping, all done with existing bool
00023  *   working through use of RGB and BGR formats so now consistent
00024  *   cleaning up the plug in system to use virtuals instead of pointers to functions.
00025  *   rewrite of SDL to be a plug in compatible video output device.
00026  *   extensive enhancement of video test program
00027  *
00028  * Revision 1.13  2005/06/07 00:42:55  csoutheren
00029  * Apply patch 1214249 to fix crash with Suse 9.3. Thanks to Stefan Bruns
00030  *
00031  * Revision 1.12  2005/01/04 07:44:03  csoutheren
00032  * More changes to implement the new configuration methodology, and also to
00033  * attack the global static problem
00034  *
00035  * Revision 1.11  2004/08/16 11:57:47  csoutheren
00036  * More changes for VS.net
00037  *
00038  * Revision 1.10  2004/08/16 10:55:09  csoutheren
00039  * Fixed problems compiling under Linux
00040  *
00041  * Revision 1.9  2004/08/16 06:40:59  csoutheren
00042  * Added adapters template to make device plugins available via the abstract factory interface
00043  *
00044  * Revision 1.8  2004/06/21 10:40:02  csoutheren
00045  * Fixed problem with dynamic plugins
00046  *
00047  * Revision 1.7  2004/06/21 00:57:40  csoutheren
00048  * Changed service plugin static registration to use attribute (( constructor ))
00049  *
00050  * Revision 1.6  2003/12/19 00:34:27  csoutheren
00051  * Ensured that older compilers do not get confused about functions wth empty
00052  * parameter lists. Thanks to Kilian Krause
00053  *
00054  * Revision 1.5  2003/11/19 09:29:19  csoutheren
00055  * Added super hack to avoid problems with multiple plugins in a single file
00056  *
00057  * Revision 1.4  2003/11/12 10:24:35  csoutheren
00058  * Changes to allow operation of static plugins under Windows
00059  *
00060  * Revision 1.3  2003/11/12 06:58:21  csoutheren
00061  * Changes to help in making static plugins autoregister under Windows
00062  *
00063  * Revision 1.2  2003/11/12 03:26:17  csoutheren
00064  * Initial version of plugin code from Snark of GnomeMeeting with changes
00065  *    by Craig Southeren os Post Increment
00066  *
00067  *
00068  */
00069 
00070 #ifndef _PLUGIN_H
00071 #define _PLUGIN_H
00072 
00074 //
00075 //  these templates implement an adapter to make the old style device plugins appear in the new factory system
00076 //
00077 
00078 #include <ptlib/pfactory.h>
00079 
00080 template <class _Abstract_T, typename _Key_T = PString>
00081 class PDevicePluginFactory : public PFactory<_Abstract_T, _Key_T>
00082 {
00083   public:
00084     class Worker : public PFactory<_Abstract_T, _Key_T>::WorkerBase 
00085     {
00086       public:
00087         Worker(const _Key_T & key, bool singleton = false)
00088           : PFactory<_Abstract_T, _Key_T>::WorkerBase(singleton)
00089         {
00090           PFactory<_Abstract_T, _Key_T>::Register(key, this);
00091         }
00092 
00093         ~Worker()
00094         {
00095           typedef typename PFactory<_Abstract_T, _Key_T>::WorkerBase WorkerBase_T;
00096           typedef std::map<_Key_T, WorkerBase_T *> KeyMap_T;
00097           _Key_T key;
00098 
00099           KeyMap_T km = PFactory<_Abstract_T, _Key_T>::GetKeyMap();
00100 
00101           typename KeyMap_T::const_iterator entry;
00102           for (entry = km.begin(); entry != km.end(); ++entry) {
00103             if (entry->second == this) {
00104               key = entry->first;
00105               break;
00106             }
00107           }
00108           if (key != NULL)
00109             PFactory<_Abstract_T, _Key_T>::Unregister(key);
00110         }
00111 
00112       protected:
00113         virtual _Abstract_T * Create(const _Key_T & key) const;
00114     };
00115 };
00116 
00117 class PDevicePluginAdapterBase
00118 {
00119   public:
00120     PDevicePluginAdapterBase()
00121     { }
00122     virtual ~PDevicePluginAdapterBase()
00123     { }
00124     virtual void CreateFactory(const PString & device) = 0;
00125 };
00126 
00127 template <typename DeviceBase>
00128 class PDevicePluginAdapter : public PDevicePluginAdapterBase
00129 {
00130   public:
00131     typedef PDevicePluginFactory<DeviceBase> Factory_T;
00132     typedef typename Factory_T::Worker Worker_T;
00133     void CreateFactory(const PString & device)
00134     {
00135       if (!(Factory_T::IsRegistered(device)))
00136         new Worker_T(device, FALSE);
00137     }
00138 };
00139 
00140 
00141 #ifndef PWLIB_PLUGIN_API_VERSION
00142 #define PWLIB_PLUGIN_API_VERSION 0
00143 #endif
00144 
00145 
00147 //
00148 //  Ancestor Service descriptor for plugins
00149 //
00150 
00151 class PPluginServiceDescriptor 
00152 {
00153   public:
00154     PPluginServiceDescriptor() { version = PWLIB_PLUGIN_API_VERSION; }
00155     virtual ~PPluginServiceDescriptor() { }
00156 
00157     virtual unsigned GetPluginAPIVersion() const { return version; }
00158 
00159   protected:
00160     unsigned version;
00161 };
00162 
00163 
00164 class PDevicePluginServiceDescriptor : public PPluginServiceDescriptor
00165 {
00166   public:
00167     static const char SeparatorChar;
00168 
00169     virtual PObject *   CreateInstance(int userData) const = 0;
00170     virtual PStringList GetDeviceNames(int userData) const = 0;
00171     virtual bool        ValidateDeviceName(const PString & deviceName, int userData) const;
00172 };
00173 
00174 
00176 //
00177 // Define a service provided by a plugin, which consists of the following:
00178 //
00179 //    serviceType - the base class name of the service which is used to identify
00180 //                  the service type, such as PSoundChannel, 
00181 //
00182 //    serviceName - the name of the service provided by the plugin. This will usually
00183 //                  be related to the class implementing the service, such as:
00184 //                       service name = OSS, class name = PSoundChannelOSS
00185 //
00186 //    descriptor  - a pointer to a class containing pointers to any static functions
00187 //                  for this class
00188 //   
00189 //
00190 
00191 class PPluginService: public PObject
00192 {
00193   public:
00194     PPluginService(const PString & _serviceName,
00195                    const PString & _serviceType,
00196                    PPluginServiceDescriptor *_descriptor)
00197     {
00198       serviceName = _serviceName;
00199       serviceType = _serviceType;
00200       descriptor  = _descriptor;
00201     }
00202 
00203     PString serviceName;
00204     PString serviceType;
00205     PPluginServiceDescriptor * descriptor;
00206 };
00207 
00208 
00210 //
00211 //  These crazy macros are needed to cause automatic registration of 
00212 //  static plugins. They are made more complex by the arcane behaviour
00213 //  of the Windows link system that requires an external reference in the
00214 //  object module before it will instantiate any globals in in it
00215 //
00216 
00217 #define PCREATE_PLUGIN_REGISTERER(serviceName, serviceType, descriptor) \
00218 class PPlugin_##serviceType##_##serviceName##_Registration { \
00219   public: \
00220     PPlugin_##serviceType##_##serviceName##_Registration(PPluginManager * pluginMgr) \
00221     { \
00222       static PDevicePluginFactory<serviceType>::Worker factory(#serviceName); \
00223       pluginMgr->RegisterService(#serviceName, #serviceType, descriptor); \
00224     } \
00225     int kill_warning; \
00226 }; \
00227 
00228 #ifdef _WIN32
00229 
00230 #define PCREATE_PLUGIN_STATIC(serviceName, serviceType, descriptor) \
00231 PCREATE_PLUGIN_REGISTERER(serviceName, serviceType, descriptor) \
00232 PPlugin_##serviceType##_##serviceName##_Registration \
00233   PPlugin_##serviceType##_##serviceName##_Registration_Instance(&PPluginManager::GetPluginManager()); \
00234 
00235 #define PWLIB_STATIC_LOAD_PLUGIN(serviceName, serviceType) \
00236   class PPlugin_##serviceType##_##serviceName##_Registration; \
00237   extern PPlugin_##serviceType##_##serviceName##_Registration PPlugin_##serviceType##_##serviceName##_Registration_Instance; \
00238   static PPlugin_##serviceType##_##serviceName##_Registration * PPlugin_##serviceType##_##serviceName##_Registration_Static_Library_Loader = &PPlugin_##serviceType##_##serviceName##_Registration_Instance;
00239 
00240 // Win32 onl;y has static plugins at present, maybe one day ...
00241 #define P_FORCE_STATIC_PLUGIN
00242 
00243 #else
00244 
00245 #ifdef USE_GCC
00246 #define PCREATE_PLUGIN_STATIC(serviceName, serviceType, descriptor) \
00247 static void __attribute__ (( constructor )) PWLIB_StaticLoader_##serviceName##_##serviceType() \
00248 { PPluginManager::GetPluginManager().RegisterService(#serviceName, #serviceType, descriptor); } \
00249 
00250 #else
00251 #define PCREATE_PLUGIN_STATIC(serviceName, serviceType, descriptor) \
00252 extern int PWLIB_gStaticLoader__##serviceName##_##serviceType; \
00253 static int PWLIB_StaticLoader_##serviceName##_##serviceType() \
00254 { PPluginManager::GetPluginManager().RegisterService(#serviceName, #serviceType, descriptor); return 1; } \
00255 int PWLIB_gStaticLoader__##serviceName##_##serviceType =  PWLIB_StaticLoader_##serviceName##_##serviceType(); 
00256 #endif
00257 #define PWLIB_STATIC_LOAD_PLUGIN(serviceName, serviceType) 
00258 
00259 #endif
00260 
00261 
00263 
00264 #if defined(P_HAS_PLUGINS) && ! defined(P_FORCE_STATIC_PLUGIN)
00265 
00266 #  define PCREATE_PLUGIN(serviceName, serviceType, descriptor) \
00267     PCREATE_PLUGIN_REGISTERER(serviceName, serviceType, descriptor) \
00268     extern "C" void PWLibPlugin_TriggerRegister (PPluginManager * pluginMgr) { \
00269     PPlugin_##serviceType##_##serviceName##_Registration \
00270         pplugin_##serviceType##_##serviceName##_Registration_Instance(pluginMgr); \
00271         pplugin_##serviceType##_##serviceName##_Registration_Instance.kill_warning = 0; \
00272     } \
00273     extern "C" unsigned PWLibPlugin_GetAPIVersion (void) \
00274     { return PWLIB_PLUGIN_API_VERSION; }
00275 
00276 #else
00277 
00278 #  define PCREATE_PLUGIN(serviceName, serviceType, descriptor) \
00279     PCREATE_PLUGIN_STATIC(serviceName, serviceType, descriptor)
00280 
00281 #endif
00282 
00284 
00285 #endif

Generated on Fri Mar 7 06:25:02 2008 for PTLib by  doxygen 1.5.1