Google

Main Page   Class Hierarchy   Compound List   File List   Compound Members  

scf.h

00001 /*
00002     Crystal Space Shared Class Facility (SCF)
00003     Copyright (C) 1999 by Andrew Zabolotny
00004 
00005     This library is free software; you can redistribute it and/or
00006     modify it under the terms of the GNU Library General Public
00007     License as published by the Free Software Foundation; either
00008     version 2 of the License, or (at your option) any later version.
00009 
00010     This library is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013     Library General Public License for more details.
00014 
00015     You should have received a copy of the GNU Library General Public
00016     License along with this library; if not, write to the Free
00017     Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00018 */
00019 
00020 #ifndef __CSSCF_H__
00021 #define __CSSCF_H__
00022 
00023 /*
00024     PLEASE USE 8-SPACE TAB WIDTH WHEN EDITING THIS FILE!
00025 */
00026 
00030 typedef uint32 scfInterfaceID;
00031 
00036 #ifdef SCF_DEBUG
00037 #  define SCF_TRACE(x)                                                  \
00038    {                                                                    \
00039      printf ("SCF [%s:%d]:\n", __FILE__, __LINE__);                     \
00040      printf x; SCF_PRINT_CALL_ADDRESS                                   \
00041    }
00042 #else
00043 #  define SCF_TRACE(x)
00044 #endif
00045 
00050 #if (__GNUC__ >= 2) && (__GNUC_MINOR__ >= 8)
00051 #  define SCF_PRINT_CALL_ADDRESS                                        \
00052    printf ("  Called from address %p\n", __builtin_return_address (0));
00053 #else
00054 #  define SCF_PRINT_CALL_ADDRESS
00055 #endif
00056 
00058 #define SCF_CONSTRUCT_VERSION(Major,Minor,Micro)                        \
00059   ((Major << 24) | (Minor << 16) | Micro)
00060 
00073 #define SCF_VERSION(Name,Major,Minor,Micro)                             \
00074   const int VERSION_##Name = SCF_CONSTRUCT_VERSION (Major, Minor, Micro)
00075 
00076 SCF_VERSION (iBase, 0, 1, 0);
00077 
00083 struct iBase
00084 {
00086   virtual void IncRef () = 0;
00088   virtual void DecRef () = 0;
00090   virtual int GetRefCount () = 0;
00092   virtual void *QueryInterface (scfInterfaceID iInterfaceID, int iVersion) = 0;
00097   static void* QueryInterfaceSafe (iBase* ibase, scfInterfaceID iInterfaceID,
00098         int iVersion)
00099   {
00100     if (ibase == NULL) return NULL;
00101     else return ibase->QueryInterface (iInterfaceID, iVersion);
00102   }
00103 };
00104 
00106 #define SCF_INC_REF(ptr) {if (ptr) {ptr->IncRef();}}
00107 
00109 #define SCF_DEC_REF(ptr) {if (ptr) {ptr->DecRef();}}
00110 
00116 #define SCF_SET_REF(var,ref) \
00117   { \
00118     if (ref) ref->IncRef (); \
00119     if (var) var->DecRef (); \
00120     var = ref; \
00121   }
00122 
00127 #define SCF_DECLARE_IBASE                                               \
00128   int scfRefCount;              /* Reference counter */                 \
00129   SCF_DECLARE_EMBEDDED_IBASE (iBase)
00130 
00135 #define SCF_DECLARE_EMBEDDED_IBASE(OuterClass)                          \
00136 public:                                                                 \
00137   OuterClass *scfParent;        /* The parent object */                 \
00138   virtual void IncRef ();                                               \
00139   virtual void DecRef ();                                               \
00140   virtual int GetRefCount ();                                           \
00141   virtual void *QueryInterface (scfInterfaceID iInterfaceID, int iVersion)
00142 
00151 #define SCF_CONSTRUCT_IBASE(Parent)                                     \
00152   scfRefCount = 1; scfParent = Parent; if (scfParent) scfParent->IncRef();
00153 
00161 #define SCF_CONSTRUCT_EMBEDDED_IBASE(Interface)                         \
00162   Interface.scfParent = this;
00163 
00169 #define SCF_IMPLEMENT_IBASE_INCREF(Class)                               \
00170 void Class::IncRef ()                                                   \
00171 {                                                                       \
00172   SCF_TRACE (("  (%s *)%p->IncRef (%d)\n", #Class, this, scfRefCount + 1));\
00173   scfRefCount++;                                                        \
00174 }
00175 
00181 #define SCF_IMPLEMENT_IBASE_DECREF(Class)                               \
00182 void Class::DecRef ()                                                   \
00183 {                                                                       \
00184   scfRefCount--;                                                        \
00185   if (scfRefCount <= 0)                                                 \
00186   {                                                                     \
00187     SCF_TRACE (("  delete (%s *)%p\n", #Class, this));                  \
00188     if (scfParent)                                                      \
00189       scfParent->DecRef ();                                             \
00190     delete this;                                                        \
00191   }                                                                     \
00192   else                                                                  \
00193     SCF_TRACE (("  (%s *)%p->DecRef (%d)\n", #Class, this, scfRefCount));\
00194 }
00195 
00200 #define SCF_IMPLEMENT_IBASE_GETREFCOUNT(Class)                          \
00201 int Class::GetRefCount ()                                               \
00202 {                                                                       \
00203   return scfRefCount;                                                   \
00204 }
00205 
00212 #define SCF_IMPLEMENT_IBASE_QUERY(Class)                                \
00213 void *Class::QueryInterface (scfInterfaceID iInterfaceID, int iVersion) \
00214 {                                                                       \
00215   SCF_TRACE (("  (%s *)%p->QueryInterface (%u, %08X)\n",                \
00216     #Class, this, iInterfaceID, iVersion));
00217 
00224 #define SCF_IMPLEMENT_IBASE_QUERY_END                                   \
00225   return scfParent ?                                                    \
00226     scfParent->QueryInterface (iInterfaceID, iVersion) : NULL;          \
00227 }
00228 
00234 #define SCF_IMPLEMENT_IBASE(Class)                                      \
00235   SCF_IMPLEMENT_IBASE_INCREF(Class)                                     \
00236   SCF_IMPLEMENT_IBASE_DECREF(Class)                                     \
00237   SCF_IMPLEMENT_IBASE_GETREFCOUNT(Class)                                \
00238   SCF_IMPLEMENT_IBASE_QUERY(Class)
00239 
00244 #define SCF_IMPLEMENT_IBASE_END                                         \
00245   SCF_IMPLEMENT_IBASE_QUERY_END
00246 
00253 #define SCF_IMPLEMENT_EMBEDDED_IBASE_INCREF(Class)                      \
00254 void Class::IncRef ()                                                   \
00255 {                                                                       \
00256   SCF_TRACE (("  (%s *)%p->IncRef (%d)\n", #Class, this,                \
00257     scfParent->GetRefCount () + 1));                                    \
00258   scfParent->IncRef ();                                                 \
00259 }
00260 
00267 #define SCF_IMPLEMENT_EMBEDDED_IBASE_DECREF(Class)                      \
00268 void Class::DecRef ()                                                   \
00269 {                                                                       \
00270   SCF_TRACE (("  (%s *)%p->DecRef (%d)\n", #Class, this,                \
00271               scfParent->GetRefCount ()-1));                            \
00272   scfParent->DecRef ();                                                 \
00273 }
00274 
00279 #define SCF_IMPLEMENT_EMBEDDED_IBASE_GETREFCOUNT(Class)                 \
00280 int Class::GetRefCount ()                                               \
00281 {                                                                       \
00282   return scfParent->GetRefCount ();                                     \
00283 }
00284 
00291 #define SCF_IMPLEMENT_EMBEDDED_IBASE_QUERY(Class)                       \
00292 void *Class::QueryInterface (scfInterfaceID iInterfaceID, int iVersion) \
00293 {                                                                       \
00294   SCF_TRACE (("  (%s *)%p->QueryInterface (%u, %08X)\n",                \
00295     #Class, this, iInterfaceID, iVersion));
00296 
00303 #define SCF_IMPLEMENT_EMBEDDED_IBASE_QUERY_END                          \
00304   return scfParent->QueryInterface (iInterfaceID, iVersion);            \
00305 }
00306 
00313 #define SCF_IMPLEMENT_EMBEDDED_IBASE(Class)                             \
00314   SCF_IMPLEMENT_EMBEDDED_IBASE_INCREF(Class)                            \
00315   SCF_IMPLEMENT_EMBEDDED_IBASE_DECREF(Class)                            \
00316   SCF_IMPLEMENT_EMBEDDED_IBASE_GETREFCOUNT(Class)                       \
00317   SCF_IMPLEMENT_EMBEDDED_IBASE_QUERY(Class)
00318 
00323 #define SCF_IMPLEMENT_EMBEDDED_IBASE_END                                \
00324   SCF_IMPLEMENT_EMBEDDED_IBASE_QUERY_END
00325 
00332 #define SCF_IMPLEMENTS_INTERFACE(Interface)                             \
00333   SCF_IMPLEMENTS_INTERFACE_COMMON (Interface, this)
00334 
00339 #define SCF_IMPLEMENTS_EMBEDDED_INTERFACE(Interface)                    \
00340   SCF_IMPLEMENTS_INTERFACE_COMMON (Interface, (&scf##Interface))
00341 
00345 #define SCF_IMPLEMENTS_INTERFACE_COMMON(Interface,Object)               \
00346   static scfInterfaceID scfID_##Interface = (scfInterfaceID)-1;         \
00347   if (scfID_##Interface == (scfInterfaceID)-1)                          \
00348     scfID_##Interface = iSCF::SCF->GetInterfaceID (#Interface);         \
00349   if (iInterfaceID == scfID_##Interface &&                              \
00350     scfCompatibleVersion (iVersion, VERSION_##Interface))               \
00351   {                                                                     \
00352     (Object)->IncRef ();                                                \
00353     return STATIC_CAST(Interface*, Object);                             \
00354   }
00355 
00366 #define SCF_DECLARE_IBASE_EXT(ParentClass)                              \
00367   typedef ParentClass __scf_superclass;                                 \
00368   virtual void IncRef ();                                               \
00369   virtual void DecRef ();                                               \
00370   virtual int GetRefCount ();                                           \
00371   virtual void *QueryInterface (scfInterfaceID iInterfaceID, int iVersion)
00372 
00379 #define SCF_IMPLEMENT_IBASE_EXT_INCREF(Class)                           \
00380 void Class::IncRef ()                                                   \
00381 {                                                                       \
00382   __scf_superclass::IncRef ();                                          \
00383 }
00384 
00391 #define SCF_IMPLEMENT_IBASE_EXT_DECREF(Class)                           \
00392 void Class::DecRef ()                                                   \
00393 {                                                                       \
00394   __scf_superclass::DecRef ();                                          \
00395 }
00396 
00403 #define SCF_IMPLEMENT_IBASE_EXT_GETREFCOUNT(Class)                      \
00404 int Class::GetRefCount ()                                               \
00405 {                                                                       \
00406   return __scf_superclass::GetRefCount ();                              \
00407 }
00408 
00415 #define SCF_IMPLEMENT_IBASE_EXT_QUERY(Class)                            \
00416 void *Class::QueryInterface (scfInterfaceID iInterfaceID, int iVersion) \
00417 {
00418 
00425 #define SCF_IMPLEMENT_IBASE_EXT_QUERY_END                               \
00426   return __scf_superclass::QueryInterface (iInterfaceID, iVersion);     \
00427 }
00428 
00433 #define SCF_IMPLEMENT_IBASE_EXT(Class)                                  \
00434   SCF_IMPLEMENT_IBASE_EXT_INCREF(Class)                                 \
00435   SCF_IMPLEMENT_IBASE_EXT_DECREF(Class)                                 \
00436   SCF_IMPLEMENT_IBASE_EXT_GETREFCOUNT(Class)                            \
00437   SCF_IMPLEMENT_IBASE_EXT_QUERY(Class)
00438 
00443 #define SCF_IMPLEMENT_IBASE_EXT_END                                     \
00444   SCF_IMPLEMENT_IBASE_EXT_QUERY_END
00445 
00452 #define SCF_IMPLEMENT_FACTORY(Class)                                    \
00453 void *Create_##Class (iBase *iParent)                                   \
00454 {                                                                       \
00455   void *ret = new Class (iParent);                                      \
00456   SCF_TRACE (("  %p = new %s ()\n", ret, #Class));                      \
00457   return ret;                                                           \
00458 }
00459 
00464 #define SCF_DECLARE_FACTORY(Class)  void *Create_##Class (iBase *iParent);
00465 
00471 struct scfClassInfo
00472 {
00474   char *ClassID;
00476   char *Description;
00482   char *Dependencies;
00484   void *(*Factory) (iBase *iParent);
00485 };
00486 
00487 /*
00488  * The following set of macros are used to define the table that contains
00489  * information about all classes exported from a shared library. This table
00490  * is used with both static and dynamic class linking.
00491  */
00492 
00508 // extern CS_DECLARE_STATIC_VARIABLE_CLEANUP 
00509 #define SCF_EXPORT_CLASS_TABLE(LibraryName)                             \
00510 CS_DECLARE_STATIC_VARIABLE_CLEANUP                                      \
00511 CS_EXPORTED_FUNCTION void                                               \
00512 CS_EXPORTED_NAME(LibraryName,_scfFinalize)()                            \
00513 { CS_STATIC_VARIABLE_CLEANUP }                                          \
00514 static inline void                                                      \
00515 CS_EXPORTED_NAME(LibraryName,_scfUnitInitialize)(iSCF *SCF)             \
00516 { iSCF::SCF = SCF; }                                                    \
00517 CS_EXPORTED_FUNCTION scfClassInfo*                                      \
00518 CS_EXPORTED_NAME(LibraryName,_scfInitialize)(iSCF *SCF)                 \
00519 {                                                                       \
00520   CS_EXPORTED_NAME(LibraryName,_scfUnitInitialize)(SCF);                \
00521   static scfClassInfo ExportClassTable [] =                             \
00522   {
00523 
00525 #define SCF_EXPORT_CLASS(Class, ClassID, Description)                   \
00526     { ClassID, Description, NULL, Create_##Class },
00527 
00529 #define SCF_EXPORT_CLASS_DEP(Class, ClassID, Description, Dependencies) \
00530     { ClassID, Description, Dependencies, Create_##Class },
00531 
00533 #define SCF_EXPORT_CLASS_TABLE_END                                      \
00534     { 0, 0, 0, 0 }                                                      \
00535   };                                                                    \
00536   return ExportClassTable;                                              \
00537 }
00538 
00546 #define SCF_REGISTER_STATIC_LIBRARY(LibraryName)                        \
00547   extern "C" scfClassInfo *LibraryName##_scfInitialize (iSCF*);         \
00548   class __##LibraryName##_Init                                          \
00549   {                                                                     \
00550   public:                                                               \
00551     __##LibraryName##_Init ()                                           \
00552     { if (!iSCF::SCF) scfInitialize ();                                 \
00553       iSCF::SCF->RegisterClassList(LibraryName##_scfInitialize(iSCF::SCF)); }\
00554   } __##LibraryName##_dummy;
00555 
00561 #define SCF_REGISTER_STATIC_CLASS(Class,ClassID,Description)            \
00562   SCF_REGISTER_STATIC_CLASS_DEP (Class,ClassID,Description,NULL);
00563 
00568 #define SCF_REGISTER_STATIC_CLASS_DEP(Class,ClassID,Description,Dependency)\
00569   extern void *Create_##Class (iBase *);                                \
00570   static scfClassInfo Class##_ClassInfo =                               \
00571   { ClassID, Description, Dependency, Create_##Class };                 \
00572   class __##Class##_Init                                                \
00573   {                                                                     \
00574   public:                                                               \
00575     __##Class##_Init ()                                                 \
00576     { if (!iSCF::SCF) scfInitialize ();                                 \
00577       iSCF::SCF->RegisterStaticClass (&Class##_ClassInfo); }            \
00578   } __##Class##_dummy;
00579 
00580 //--------------------------------------------- Class factory interface -----//
00581 
00582 SCF_VERSION (iFactory, 0, 0, 1);
00583 
00596 struct iFactory : public iBase
00597 {
00599   virtual void *CreateInstance () = 0;
00601   virtual void TryUnload () = 0;
00603   virtual const char *QueryDescription () = 0;
00605   virtual const char *QueryDependencies () = 0;
00607   virtual const char *QueryClassID () = 0;
00608 };
00609 
00610 //----------------------------------------------- Client-side functions -----//
00611 
00612 struct iConfigFile;
00613 struct iStrVector;
00614 
00621 #define SCF_DECLARE_FAST_INTERFACE(Interface)                           \
00622 inline static scfInterfaceID scfGetID_##Interface ()                    \
00623 {                                                                       \
00624   static scfInterfaceID ID = (scfInterfaceID)-1;                        \
00625   if (ID == (scfInterfaceID)(-1))                                       \
00626     ID = iSCF::SCF->GetInterfaceID (#Interface);                        \
00627   return ID;                                                            \
00628 }
00629 
00634 #define SCF_CREATE_INSTANCE(ClassID,Interface)                          \
00635   (Interface *)iSCF::SCF->CreateInstance (                              \
00636   ClassID, #Interface, VERSION_##Interface)
00637 
00642 #define SCF_QUERY_INTERFACE(Object,Interface)                           \
00643   (Interface *)(Object)->QueryInterface (                               \
00644     iSCF::SCF->GetInterfaceID (#Interface), VERSION_##Interface)
00645 
00653 #define SCF_QUERY_INTERFACE_FAST(Object,Interface)                      \
00654   (Interface*)(Object)->QueryInterface (                                \
00655   scfGetID_##Interface (), VERSION_##Interface)
00656 
00662 #define SCF_QUERY_INTERFACE_SAFE(Object,Interface)                      \
00663   (Interface *)(iBase::QueryInterfaceSafe ((Object),                    \
00664     iSCF::SCF->GetInterfaceID (#Interface), VERSION_##Interface))
00665 
00673 extern void scfInitialize (iConfigFile *iConfig = 0);
00674 
00681 static inline bool scfCompatibleVersion (int iVersion, int iItfVersion)
00682 {
00683   return ((iVersion & 0xff000000) == (iItfVersion & 0xff000000))
00684       && ((iVersion & 0x00ffffff) <= (iItfVersion & 0x00ffffff));
00685 }
00686 
00687 #ifdef CS_DEBUG
00688   struct iObjectRegistry;
00689 #endif
00690 
00691 SCF_VERSION (iSCF, 0, 0, 1);
00692 
00699 struct iSCF : public iBase
00700 {
00702   static iSCF *SCF;
00703 
00704 #ifdef CS_DEBUG
00705   // This is EXTREMELY dirty but I see no other solution for now.
00706   // For debugging reasons I must have a global (global over the application
00707   // and all plugins)pointer to the object registry. I have no other
00708   // global object to tag this pointer on that except for iSCF.
00709   // This pointer is only here in debug mode though. That ensures that it
00710   // cannot be misused in real code.
00711   // If you know another solution for this problem? This global pointer
00712   // will be used by csDebuggingGraph in csutil.
00713   iObjectRegistry* object_reg;
00714 #endif
00715 
00720   virtual void RegisterConfigClassList (iConfigFile *Config) = 0;
00721 
00728   virtual bool ClassRegistered (const char *iClassID) = 0;
00729 
00745   virtual void *CreateInstance (const char *iClassID,
00746         const char *iInterface, int iVersion) = 0;
00747 
00753   virtual const char *GetClassDescription (const char *iClassID) = 0;
00754 
00760   virtual const char *GetClassDependencies (const char *iClassID) = 0;
00761 
00768   virtual void UnloadUnusedModules () = 0;
00769 
00777   virtual bool RegisterClass (const char *iClassID,
00778         const char *iLibraryName, const char *Dependencies = NULL) = 0;
00779 
00786   virtual bool RegisterStaticClass (scfClassInfo *iClassInfo) = 0;
00787 
00796   virtual bool RegisterClassList (scfClassInfo *iClassInfo) = 0;
00797 
00804   virtual bool UnregisterClass (const char *iClassID) = 0;
00805 
00811   virtual scfInterfaceID GetInterfaceID (const char *iInterface) = 0;
00812 
00819   virtual void Finish () = 0;
00820 
00831   virtual iStrVector* QueryClassList (char const* pattern) = 0;
00832 };
00833 
00834 #endif // __CSSCF_H__

Generated for Crystal Space by doxygen 1.2.5 written by Dimitri van Heesch, ©1997-2000