csutil/scf_interface.h
Go to the documentation of this file.00001 /* 00002 Crystal Space Shared Class Facility (SCF) 00003 This header contains the parts of SCF that is needed for defining 00004 new interfaces. 00005 00006 Copyright (C) 1999 by Andrew Zabolotny 00007 (C) 2005 by Marten Svanfeldt 00008 (C) 2005 by Michael Adams 00009 00010 This library is free software; you can redistribute it and/or 00011 modify it under the terms of the GNU Library General Public 00012 License as published by the Free Software Foundation; either 00013 version 2 of the License, or (at your option) any later version. 00014 00015 This library is distributed in the hope that it will be useful, 00016 but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00018 Library General Public License for more details. 00019 00020 You should have received a copy of the GNU Library General Public 00021 License along with this library; if not, write to the Free 00022 Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00023 */ 00024 00025 #ifndef __CSUTIL_SCF_INTERFACE_H__ 00026 #define __CSUTIL_SCF_INTERFACE_H__ 00027 00028 #include "csextern.h" 00029 00030 // These are needed for compiletime checks on interfaces 00031 00032 #include "csutil/compileassert.h" 00033 #include "csutil/typetraits.h" 00034 00035 // -- Forward declarations 00036 struct iDocument; 00037 #if defined(CS_DEBUG) || defined(CS_MEMORY_TRACKER) 00038 struct iObjectRegistry; 00039 #endif 00040 template<class T> 00041 class csRef; 00042 struct iStringArray; 00043 00055 typedef unsigned long scfInterfaceID; 00056 00060 typedef int scfInterfaceVersion; 00061 00062 // -- Some helpers needed below 00076 #define SCF_INTERFACE(Name,Major,Minor,Micro) \ 00077 struct InterfaceTraits { \ 00078 typedef Name InterfaceType; \ 00079 CS_FORCEINLINE static scfInterfaceVersion GetVersion() \ 00080 { return SCF_CONSTRUCT_VERSION(Major, Minor, Micro); } \ 00081 CS_FORCEINLINE static char const * GetName() { return #Name; } \ 00082 } 00083 00084 00086 #define SCF_CONSTRUCT_VERSION(Major,Minor,Micro) \ 00087 ((Major << 24) | (Minor << 16) | Micro) 00088 00089 00096 static CS_FORCEINLINE bool scfCompatibleVersion ( 00097 scfInterfaceVersion iVersion, scfInterfaceVersion iItfVersion) 00098 { 00099 return (((iVersion & 0xff000000) == (iItfVersion & 0xff000000)) 00100 && ((iVersion & 0x00ffffff) <= (iItfVersion & 0x00ffffff))) 00101 || iVersion == 0; 00102 } 00103 00104 // -- The main two SCF interfaces, iBase and iSCF 00105 00111 struct iBase 00112 { 00113 protected: 00118 virtual ~iBase() {} 00119 public: 00120 SCF_INTERFACE(iBase, 1, 0, 0); 00122 virtual void IncRef () = 0; 00124 virtual void DecRef () = 0; 00126 virtual int GetRefCount () = 0; 00133 virtual void *QueryInterface (scfInterfaceID iInterfaceID, int iVersion) = 0; 00135 virtual void AddRefOwner (void** ref_owner) = 0; 00137 virtual void RemoveRefOwner (void** ref_owner) = 0; 00138 }; 00139 00141 typedef iBase* (*scfFactoryFunc)(iBase*); 00142 00149 struct iSCF : public iBase 00150 { 00151 SCF_INTERFACE(iSCF, 2, 0,0); 00163 static CS_CRYSTALSPACE_EXPORT iSCF* SCF; 00164 00165 #if defined(CS_DEBUG) || defined(CS_MEMORY_TRACKER) 00166 // This is EXTREMELY dirty but I see no other solution for now. 00167 // For debugging reasons I must have a global (global over the application 00168 // and all plugins)pointer to the object registry. I have no other 00169 // global object to tag this pointer on that except for iSCF. 00170 // This pointer is only here in debug mode though. That ensures that it 00171 // cannot be misused in real code. 00172 // If you know another solution for this problem? This global pointer 00173 // will be used by csDebuggingGraph in csutil. 00174 iObjectRegistry* object_reg; 00175 #endif 00176 00180 virtual void RegisterClasses (iDocument* metadata, 00181 const char* context = 0) = 0; 00182 00188 virtual void RegisterClasses (char const* xml, 00189 const char* context = 0) = 0; 00190 00194 virtual void RegisterClasses (const char* pluginPath, 00195 iDocument* metadata, const char* context = 0) = 0; 00196 00203 virtual bool ClassRegistered (const char *iClassID) = 0; 00204 00216 virtual iBase *CreateInstance (const char *iClassID) = 0; 00217 00223 virtual const char *GetClassDescription (const char *iClassID) = 0; 00224 00230 virtual const char *GetClassDependencies (const char *iClassID) = 0; 00231 00258 virtual csRef<iDocument> GetPluginMetadata (char const *iClassID) = 0; 00259 00266 virtual void UnloadUnusedModules () = 0; 00267 00278 virtual bool RegisterClass (const char *iClassID, 00279 const char *iLibraryName, const char *iFactoryClass, 00280 const char *Description, const char *Dependencies = 0, 00281 const char* context = 0) = 0; 00282 00289 virtual bool RegisterClass (scfFactoryFunc, const char *iClassID, 00290 const char *Description, const char *Dependencies = 0, 00291 const char* context = 0) = 0; 00292 00300 virtual bool RegisterFactoryFunc (scfFactoryFunc, const char *FactClass) = 0; 00301 00308 virtual bool UnregisterClass (const char *iClassID) = 0; 00309 00314 virtual char const* GetInterfaceName (scfInterfaceID) const = 0; 00315 00321 virtual scfInterfaceID GetInterfaceID (const char *iInterface) = 0; 00322 00329 virtual void Finish () = 0; 00330 00340 virtual csRef<iStringArray> QueryClassList (char const* pattern) = 0; 00341 00345 virtual void ScanPluginsPath (const char* path, bool recursive = false, 00346 const char* context = 0) = 0; 00347 00357 virtual bool RegisterPlugin (const char* path) = 0; 00358 }; 00359 00360 00361 //-- Interface traits 00362 00372 template <class Interface> 00373 class scfInterfaceTraits 00374 { 00375 public: 00376 typedef typename Interface::InterfaceTraits::InterfaceType 00377 InterfaceType; 00378 00379 /* 00380 Make sure that we either have a SCF_VERSION macro which results in this class 00381 being specialized, or that we have a SCF_INTERFACE macro in the interface itself. 00382 */ 00383 CS_COMPILE_ASSERT((::CS::TypeTraits::IsSame<InterfaceType, 00384 Interface>::value)); 00385 00389 CS_FORCEINLINE_TEMPLATEMETHOD static scfInterfaceVersion GetVersion () 00390 { 00391 return Interface::InterfaceTraits::GetVersion (); 00392 } 00393 00401 CS_FORCEINLINE_TEMPLATEMETHOD static scfInterfaceID GetID () 00402 { 00403 scfInterfaceID& ID = GetMyID (); 00404 if (ID == (scfInterfaceID)(-1)) 00405 { 00406 ID = iSCF::SCF->GetInterfaceID (GetName ()); 00407 csStaticVarCleanup (CleanupID); 00408 } 00409 return ID; 00410 } 00411 00415 CS_FORCEINLINE_TEMPLATEMETHOD static char const* GetName () 00416 { 00417 return Interface::InterfaceTraits::GetName (); 00418 } 00419 00420 private: 00421 // This idiom is a Meyers singleton 00422 CS_FORCEINLINE_TEMPLATEMETHOD static scfInterfaceID& GetMyID () 00423 { 00424 static scfInterfaceID ID = (scfInterfaceID)-1; 00425 return ID; 00426 } 00427 static void CleanupID () 00428 { 00429 GetMyID () = (scfInterfaceID)-1; 00430 } 00431 }; 00432 00446 #define SCF_VERSION(Name,Major,Minor,Micro) \ 00447 struct Name; \ 00448 template<> \ 00449 class scfInterfaceTraits<Name> \ 00450 { \ 00451 public: \ 00452 typedef Name InterfaceType; \ 00453 static scfInterfaceVersion GetVersion() \ 00454 { return SCF_CONSTRUCT_VERSION(Major, Minor, Micro); } \ 00455 static char const* GetName () \ 00456 { return #Name; } \ 00457 static scfInterfaceID GetID () \ 00458 { scfInterfaceID& ID = GetMyID (); \ 00459 if (ID == (scfInterfaceID)(-1)) \ 00460 { ID = iSCF::SCF->GetInterfaceID (GetName ()); \ 00461 csStaticVarCleanup (CleanupID); } \ 00462 return ID; \ 00463 } \ 00464 private: \ 00465 static scfInterfaceID& GetMyID () \ 00466 { static scfInterfaceID ID = (scfInterfaceID)-1; return ID; } \ 00467 static void CleanupID () \ 00468 { GetMyID () = (scfInterfaceID)-1; } \ 00469 } 00470 00473 #endif 00474
Generated for Crystal Space by doxygen 1.4.7