## Public API Reference

- Main Page
- Modules
- Namespaces
- Classes
- Files
- Related Pages

- File List
- File Members

# 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