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 
00031 // -- Forward declarations
00032 struct iDocument;
00033 #if defined(CS_DEBUG) || defined(CS_MEMORY_TRACKER)
00034   struct iObjectRegistry;
00035 #endif
00036 template<class T>
00037 class csRef;
00038 struct iStringArray;
00039 
00051 typedef unsigned long scfInterfaceID;
00052 
00056 typedef int scfInterfaceVersion;
00057 
00058 // -- Some helpers needed below
00072 #define SCF_INTERFACE(Name,Major,Minor,Micro)             \
00073 struct InterfaceTraits {                                  \
00074   CS_DEPRECATION_WARNINGS_DISABLE                         \
00075   typedef Name InterfaceType;                             \
00076   CS_DEPRECATION_WARNINGS_ENABLE                          \
00077   CS_FORCEINLINE static scfInterfaceVersion GetVersion() \
00078   { return SCF_CONSTRUCT_VERSION(Major, Minor, Micro); }  \
00079   CS_FORCEINLINE static char const * GetName() { return #Name; }  \
00080 }
00081 
00082 
00084 #define SCF_CONSTRUCT_VERSION(Major,Minor,Micro)          \
00085   ((Major << 24) | (Minor << 16) | Micro)
00086 
00087 
00094 static CS_FORCEINLINE bool scfCompatibleVersion (
00095   scfInterfaceVersion iVersion, scfInterfaceVersion iItfVersion)
00096 {
00097   return (((iVersion & 0xff000000) == (iItfVersion & 0xff000000))
00098      && ((iVersion & 0x00ffffff) <= (iItfVersion & 0x00ffffff)))
00099      || iVersion == 0;
00100 }
00101 
00105 struct scfInterfaceMetadata
00106 {
00108   const char* interfaceName;
00109 
00111   scfInterfaceID interfaceID;
00112 
00114   scfInterfaceVersion interfaceVersion;
00115 };
00116 
00120 struct scfInterfaceMetadataList
00121 {
00123   scfInterfaceMetadata* metadata;
00124 
00126   size_t metadataCount;
00127 };
00128 
00129 // -- The main two SCF interfaces, iBase and iSCF
00130 
00136 struct iBase
00137 {
00138 protected:
00143   virtual ~iBase() {}
00144 public:
00145   SCF_INTERFACE(iBase, 1, 1, 0);
00151   virtual void IncRef () = 0;
00160   virtual void DecRef () = 0;
00167   virtual int GetRefCount () = 0;
00176   virtual void *QueryInterface (scfInterfaceID iInterfaceID, int iVersion) = 0;
00186   virtual void AddRefOwner (void** ref_owner) = 0;
00193   virtual void RemoveRefOwner (void** ref_owner) = 0;
00194 
00200   virtual scfInterfaceMetadataList* GetInterfaceMetadata () = 0;
00201 };
00202 
00204 typedef iBase* (*scfFactoryFunc)(iBase*);
00205 
00212 struct iSCF : public virtual iBase
00213 {
00214   SCF_INTERFACE(iSCF, 3,0,0);
00226   static CS_CRYSTALSPACE_EXPORT iSCF* SCF;
00227 
00228 #if defined(CS_DEBUG) || defined(CS_MEMORY_TRACKER)
00229   // This is EXTREMELY dirty but I see no other solution for now.
00230   // For debugging reasons I must have a global (global over the application
00231   // and all plugins)pointer to the object registry. I have no other
00232   // global object to tag this pointer on that except for iSCF.
00233   // This pointer is only here in debug mode though. That ensures that it
00234   // cannot be misused in real code.
00235   // If you know another solution for this problem? This global pointer
00236   // will be used by csDebuggingGraph in csutil.
00237   iObjectRegistry* object_reg;
00238 #endif
00239 
00243   virtual void RegisterClasses (iDocument* metadata,
00244     const char* context = 0) = 0;
00245 
00251   virtual void RegisterClasses (char const* xml,
00252     const char* context = 0) = 0;
00253 
00257   virtual void RegisterClasses (const char* pluginPath,
00258     iDocument* metadata, const char* context = 0) = 0;
00259 
00266   virtual bool ClassRegistered (const char *iClassID) = 0;
00267 
00279   virtual iBase *CreateInstance (const char *iClassID) = 0;
00280 
00286   virtual const char *GetClassDescription (const char *iClassID) = 0;
00287 
00293   virtual const char *GetClassDependencies (const char *iClassID) = 0;
00294 
00321   virtual csRef<iDocument> GetPluginMetadata (char const *iClassID) = 0;
00322 
00329   virtual void UnloadUnusedModules () = 0;
00330 
00341   virtual bool RegisterClass (const char *iClassID,
00342     const char *iLibraryName, const char *iFactoryClass,
00343     const char *Description, const char *Dependencies = 0,
00344     const char* context = 0) = 0;
00345 
00352   virtual bool RegisterClass (scfFactoryFunc, const char *iClassID,
00353     const char *Description, const char *Dependencies = 0,
00354     const char* context = 0) = 0;
00355 
00363   virtual bool RegisterFactoryFunc (scfFactoryFunc, const char *FactClass) = 0;
00364 
00371   virtual bool UnregisterClass (const char *iClassID) = 0;
00372 
00377   virtual char const* GetInterfaceName (scfInterfaceID) const = 0;
00378 
00384   virtual scfInterfaceID GetInterfaceID (const char *iInterface) = 0;
00385 
00392   virtual void Finish () = 0;
00393 
00404   virtual csRef<iStringArray> QueryClassList (char const* pattern) = 0;
00405 
00409   virtual void ScanPluginsPath (const char* path, bool recursive = false,
00410     const char* context = 0) = 0;
00411 
00421   virtual bool RegisterPlugin (const char* path) = 0;
00422 };
00423 
00424 
00425 //-- Interface traits
00426 
00436 template <typename Interface> 
00437 class scfInterfaceTraits
00438 {
00439 public:
00440   typedef typename Interface::InterfaceTraits::InterfaceType 
00441     InterfaceType;
00442 
00446   CS_FORCEINLINE_TEMPLATEMETHOD static scfInterfaceVersion GetVersion ()
00447   {
00448     return Interface::InterfaceTraits::GetVersion ();
00449   }
00450 
00458   CS_FORCEINLINE_TEMPLATEMETHOD static scfInterfaceID GetID ()
00459   {
00460     scfInterfaceID& ID = GetMyID ();
00461     if (ID == (scfInterfaceID)(-1))
00462     {
00463       ID = iSCF::SCF->GetInterfaceID (GetName ());
00464       csStaticVarCleanup (CleanupID);
00465     }
00466     return ID;
00467   }
00468 
00472   CS_FORCEINLINE_TEMPLATEMETHOD static char const* GetName ()
00473   { 
00474     return Interface::InterfaceTraits::GetName ();
00475   }
00476 
00477 private:
00478   // This idiom is a Meyers singleton
00479   CS_FORCEINLINE_TEMPLATEMETHOD static scfInterfaceID& GetMyID ()
00480   {
00481     static scfInterfaceID ID = (scfInterfaceID)-1;
00482     return ID;
00483   }
00484   static void CleanupID ()
00485   {
00486     GetMyID () = (scfInterfaceID)-1;
00487   }
00488 };
00489 
00503 #define SCF_VERSION(Name,Major,Minor,Micro)                \
00504 struct Name;                                               \
00505 template<>                                                 \
00506 class scfInterfaceTraits<Name>                             \
00507 {                                                          \
00508 public:                                                    \
00509   typedef Name InterfaceType;                              \
00510   static scfInterfaceVersion GetVersion()                  \
00511   { return SCF_CONSTRUCT_VERSION(Major, Minor, Micro); }   \
00512   static char const* GetName ()                            \
00513   { return #Name; }                                        \
00514   static scfInterfaceID GetID ()                           \
00515   { scfInterfaceID& ID = GetMyID ();                       \
00516     if (ID == (scfInterfaceID)(-1))                        \
00517     { ID = iSCF::SCF->GetInterfaceID (GetName ());         \
00518       csStaticVarCleanup (CleanupID);    }                 \
00519     return ID;                                             \
00520   }                                                        \
00521 private:                                                   \
00522   static scfInterfaceID& GetMyID ()                        \
00523   { static scfInterfaceID ID = (scfInterfaceID)-1; return ID; } \
00524   static void CleanupID ()                                 \
00525   { GetMyID () = (scfInterfaceID)-1; }                     \
00526 }
00527 
00530 #endif
00531 

Generated for Crystal Space 2.0 by doxygen 1.7.6.1