# 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: 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 ///////////////////////////////////////////////////////////////