00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef __CS_IUTIL_PLUGIN_H__
00021 #define __CS_IUTIL_PLUGIN_H__
00022
00032 #include "csutil/scf.h"
00033 #include "csutil/stringquote.h"
00034 #include "iutil/comp.h"
00035 #include "iutil/objreg.h"
00036 #include "iutil/threadmanager.h"
00037 #include "ivaria/reporter.h"
00038
00042 struct iPluginIterator : public virtual iBase
00043 {
00044 SCF_INTERFACE(iPluginIterator, 3,0,0);
00046 virtual bool HasNext () = 0;
00048 virtual iComponent* Next () = 0;
00049 };
00050
00062 struct iPluginManager : public virtual iBase
00063 {
00064 SCF_INTERFACE(iPluginManager, 4, 0, 1);
00065
00070 enum
00071 {
00073 lpiInitialize = 1,
00075 lpiReportErrors = 2,
00077 lpiLoadDependencies = 4,
00079 lpiReturnLoadedInstance = 8
00080 };
00081
00100 virtual csPtr<iComponent> LoadPluginInstance (const char *classID,
00101 uint loadFlags) = 0;
00102
00103 CS_DEPRECATED_METHOD_MSG("Use LoadPluginInstance()")
00104 inline iBase* LoadPlugin (const char *classID, bool init = true, bool report = true)
00105 {
00106 uint flags = 0;
00107 if (init) flags |= lpiInitialize;
00108 if (report) flags |= lpiReportErrors;
00109 csRef<iComponent> comp (LoadPluginInstance (classID, flags));
00110 if (comp) comp->IncRef();
00111 return (iBase*)comp;
00112 }
00113
00123 virtual csPtr<iComponent> QueryPluginInstance (const char *iInterface,
00124 int iVersion) = 0;
00125
00126 CS_DEPRECATED_METHOD_MSG("Use QueryPluginInstance()")
00127 inline iBase* QueryPlugin (const char *iInterface, int iVersion)
00128 {
00129 csRef<iComponent> comp (QueryPluginInstance (iInterface, iVersion));
00130 if (comp) comp->IncRef();
00131 return (iBase*)comp;
00132 }
00133
00135
00141 virtual csPtr<iComponent> QueryPluginInstance (const char* classID) = 0;
00142 virtual csPtr<iComponent> QueryPluginInstance (const char* classID,
00143 const char *iInterface, int iVersion) = 0;
00145
00146 CS_DEPRECATED_METHOD_MSG("Use QueryPluginInstance()")
00147 inline iBase* QueryPlugin (const char* classID,
00148 const char *iInterface, int iVersion)
00149 {
00150 csRef<iComponent> comp (QueryPluginInstance (classID, iInterface, iVersion));
00151 if (comp) comp->IncRef();
00152 return (iBase*)comp;
00153 }
00154
00156 virtual bool UnloadPluginInstance (iComponent *obj) = 0;
00157
00158 CS_DEPRECATED_METHOD_MSG("Use UnloadPluginInstance()")
00159 inline bool UnloadPlugin (iComponent *obj)
00160 { return UnloadPluginInstance (obj); }
00161
00163 virtual bool RegisterPluginInstance (const char *classID, iComponent *obj) = 0;
00164
00165 CS_DEPRECATED_METHOD_MSG("Use RegisterPluginInstance()")
00166 inline bool RegisterPlugin (const char *classID, iComponent *obj)
00167 { return RegisterPluginInstance (classID, obj); }
00168
00174 virtual csPtr<iPluginIterator> GetPluginInstances () = 0;
00175
00176 CS_DEPRECATED_METHOD_MSG("Use GetPluginInstances()")
00177 inline csPtr<iPluginIterator> GetPlugins ()
00178 { return GetPluginInstances (); }
00180 virtual void Clear () = 0;
00181
00189 virtual void QueryOptions (iComponent* object) = 0;
00190
00195 virtual bool SetTagClassIDMapping (const char* tag, const char* classID) = 0;
00197 virtual bool UnsetTagClassIDMapping (const char* tag) = 0;
00199 virtual const char* GetTagClassIDMapping (const char* tag) = 0;
00205 virtual csPtr<iStringArray> GetClassIDTags (const char* classID) = 0;
00211 virtual csPtr<iComponent> LoadTagPluginInstance (const char* tag,
00212 uint loadFlags) = 0;
00217 virtual csPtr<iComponent> QueryTagPluginInstance (const char* tag) = 0;
00218
00219 };
00220
00221
00230 template<class Interface>
00231 inline csPtr<Interface> csQueryPluginClass (iPluginManager *mgr,
00232 const char* ClassID)
00233 {
00234 csRef<iComponent> base = mgr->QueryPluginInstance (ClassID,
00235 scfInterfaceTraits<Interface>::GetName(),
00236 scfInterfaceTraits<Interface>::GetVersion());
00237 return scfQueryInterfaceSafe<Interface> (base);
00238 }
00239
00244 #define CS_QUERY_PLUGIN_CLASS(Object,ClassID,Interface) \
00245 csQueryPluginClass<Interface> (Object, ClassID)
00246
00253 template<class Interface>
00254 inline csPtr<Interface> csLoadPlugin (iPluginManager *mgr,
00255 const char* ClassID,
00256 bool report = true,
00257 bool returnLoadedInstance = false)
00258 {
00259 csRef<iComponent> base;
00260 uint flags = iPluginManager::lpiInitialize | iPluginManager::lpiLoadDependencies;
00261 if (report) flags |= iPluginManager::lpiReportErrors;
00262 if (returnLoadedInstance) flags |= iPluginManager::lpiReturnLoadedInstance;
00263 base = mgr->LoadPluginInstance (ClassID, flags);
00264 return scfQueryInterfaceSafe<Interface> (base);
00265 }
00266
00273 template<class Interface>
00274 inline csPtr<Interface> csLoadPlugin (iObjectRegistry* object_reg,
00275 const char* ClassID,
00276 bool report = true)
00277 {
00278 csRef<iPluginManager> mgr = csQueryRegistry<iPluginManager> (object_reg);
00279 if (!mgr) return 0;
00280 return csLoadPlugin<Interface> (mgr, ClassID, report);
00281 }
00282
00290 template<class Interface>
00291 inline csPtr<Interface> csLoadPluginCheck (iPluginManager *mgr,
00292 const char* ClassID,
00293 bool report = true)
00294 {
00295 csRef<Interface> i = csQueryPluginClass<Interface> (mgr, ClassID);
00296 if (i) return (csPtr<Interface>) i;
00297 i = csLoadPlugin<Interface> (mgr, ClassID, report, true);
00298 if (!i) return 0;
00299 return (csPtr<Interface>) i;
00300 }
00301
00310 template<class Interface>
00311 inline csPtr<Interface> csLoadPluginCheck (iObjectRegistry* object_reg,
00312 const char* ClassID, bool report = true)
00313 {
00314 csRef<iPluginManager> mgr = csQueryRegistry<iPluginManager> (object_reg);
00315 if (!mgr)
00316 {
00317 if (report)
00318 csReport (object_reg, CS_REPORTER_SEVERITY_ERROR,
00319 "crystalspace.plugin.load", "Couldn't find plugin manager!");
00320 return 0;
00321 }
00322 csRef<Interface> i = csLoadPluginCheck<Interface> (mgr, ClassID, report);
00323 if (!i)
00324 {
00325 if (report)
00326 csReport (object_reg, CS_REPORTER_SEVERITY_ERROR,
00327 "crystalspace.plugin.load", "Couldn't load plugin with class %s!",
00328 CS::Quote::Single (ClassID));
00329 return 0;
00330 }
00331 return (csPtr<Interface>) i;
00332 }
00333
00338 inline csPtr<iComponent> csLoadPluginAlways (iPluginManager *mgr,
00339 const char* ClassID,
00340 bool report = true)
00341 {
00342 uint flags =
00343 iPluginManager::lpiInitialize | iPluginManager::lpiLoadDependencies;
00344 if (report) flags |= iPluginManager::lpiReportErrors;
00345 return mgr->LoadPluginInstance (ClassID, flags);
00346 }
00347
00369 template<class Interface>
00370 inline csPtr<Interface> csQueryRegistryOrLoad (iObjectRegistry *Reg,
00371 const char* classID, bool report = true)
00372 {
00373 csRef<Interface> i = csQueryRegistry<Interface> (Reg);
00374 if (i) return (csPtr<Interface>)i;
00375 csRef<iPluginManager> plugmgr = csQueryRegistry<iPluginManager> (Reg);
00376 if (!plugmgr)
00377 {
00378 if (report)
00379 csReport (Reg, CS_REPORTER_SEVERITY_ERROR,
00380 "crystalspace.plugin.query", "Plugin manager missing!");
00381 return 0;
00382 }
00383 i = csLoadPlugin<Interface> (plugmgr, classID, report);
00384 if (!i)
00385 {
00386 if (report)
00387 csReport (Reg, CS_REPORTER_SEVERITY_ERROR,
00388 "crystalspace.plugin.query",
00389 "Couldn't load plugin with class %s!", CS::Quote::Single (classID));
00390 return 0;
00391 }
00392 if (!Reg->Register (i, scfInterfaceTraits<Interface>::GetName ()))
00393 {
00394 if (report)
00395 csReport (Reg, CS_REPORTER_SEVERITY_ERROR,
00396 "crystalspace.plugin.query",
00397 "Couldn't register plugin with class %s!", CS::Quote::Single (classID));
00398 return 0;
00399 }
00400 return (csPtr<Interface>)i;
00401 }
00402
00405 #endif // __CS_IUTIL_PLUGIN_H__