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