CrystalSpace

Public API Reference

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