CrystalSpace

Public API Reference

Main Page   Modules   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

scf.h

Go to the documentation of this file.
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 
00027 /*
00028     PLEASE USE 8-SPACE TAB WIDTH WHEN EDITING THIS FILE!
00029 */
00030 
00035 #include "csutil/ref.h"
00036 
00040 typedef uint32 scfInterfaceID;
00041 
00046 #ifdef SCF_DEBUG
00047 #  define SCF_TRACE(x)                                                  \
00048    {                                                                    \
00049      printf ("SCF [%s:%d]:\n", __FILE__, __LINE__);                     \
00050      printf x; SCF_PRINT_CALL_ADDRESS                                   \
00051    }
00052 #else
00053 #  define SCF_TRACE(x)
00054 #endif
00055 
00060 #if (__GNUC__ >= 2) && (__GNUC_MINOR__ >= 8)
00061 #  define SCF_PRINT_CALL_ADDRESS                                        \
00062    printf ("  Called from address %p\n", __builtin_return_address (0));
00063 #else
00064 #  define SCF_PRINT_CALL_ADDRESS
00065 #endif
00066 
00068 #define SCF_CONSTRUCT_VERSION(Major,Minor,Micro)                        \
00069   ((Major << 24) | (Minor << 16) | Micro)
00070 
00076 struct iBase
00077 {
00079   virtual void IncRef () = 0;
00081   virtual void DecRef () = 0;
00083   virtual int GetRefCount () = 0;
00085   virtual void *QueryInterface (scfInterfaceID iInterfaceID, int iVersion) = 0;
00090   static void* QueryInterfaceSafe (iBase* ibase, scfInterfaceID iInterfaceID,
00091         int iVersion)
00092   {
00093     if (ibase == NULL) return NULL;
00094     else return ibase->QueryInterface (iInterfaceID, iVersion);
00095   }
00096 };
00097 
00099 #define SCF_INC_REF(ptr) {if (ptr) {ptr->IncRef();}}
00100 
00102 #define SCF_DEC_REF(ptr) {if (ptr) {ptr->DecRef();}}
00103 
00109 #define SCF_SET_REF(var,ref) \
00110   { \
00111     if (ref) ref->IncRef (); \
00112     if (var) var->DecRef (); \
00113     var = ref; \
00114   }
00115 
00120 #define SCF_DECLARE_IBASE                                               \
00121   int scfRefCount;              /* Reference counter */                 \
00122   SCF_DECLARE_EMBEDDED_IBASE (iBase)
00123 
00128 #define SCF_DECLARE_EMBEDDED_IBASE(OuterClass)                          \
00129 public:                                                                 \
00130   OuterClass *scfParent;        /* The parent object */                 \
00131   virtual void IncRef ();                                               \
00132   virtual void DecRef ();                                               \
00133   virtual int GetRefCount ();                                           \
00134   virtual void *QueryInterface (scfInterfaceID iInterfaceID, int iVersion)
00135 
00144 #define SCF_CONSTRUCT_IBASE(Parent)                                     \
00145   scfRefCount = 1; scfParent = Parent; if (scfParent) scfParent->IncRef();
00146 
00154 #define SCF_CONSTRUCT_EMBEDDED_IBASE(Interface)                         \
00155   Interface.scfParent = this;
00156 
00162 #define SCF_IMPLEMENT_IBASE_INCREF(Class)                               \
00163 void Class::IncRef ()                                                   \
00164 {                                                                       \
00165   SCF_TRACE (("  (%s *)%p->IncRef (%d)\n", #Class, this, scfRefCount + 1));\
00166   scfRefCount++;                                                        \
00167 }
00168 
00174 // A note to the implementation: We do the "if" before the "scRefCount--"
00175 // to make sure that calling Inc/DecRef doesn't result in a 2nd delete
00176 #define SCF_IMPLEMENT_IBASE_DECREF(Class)                               \
00177 void Class::DecRef ()                                                   \
00178 {                                                                       \
00179   if (scfRefCount == 1)                                                 \
00180   {                                                                     \
00181     SCF_TRACE ((" delete (%s *)%p\n", #Class, this));                   \
00182     if (scfParent)                                                      \
00183       scfParent->DecRef ();                                             \
00184     delete this;                                                        \
00185     return;                                                             \
00186   }                                                                     \
00187   scfRefCount--;                                                        \
00188 }
00189 
00194 #define SCF_IMPLEMENT_IBASE_GETREFCOUNT(Class)                          \
00195 int Class::GetRefCount ()                                               \
00196 {                                                                       \
00197   return scfRefCount;                                                   \
00198 }
00199 
00206 #define SCF_IMPLEMENT_IBASE_QUERY(Class)                                \
00207 void *Class::QueryInterface (scfInterfaceID iInterfaceID, int iVersion) \
00208 {                                                                       \
00209   SCF_TRACE (("  (%s *)%p->QueryInterface (%u, %08X)\n",                \
00210     #Class, this, iInterfaceID, iVersion));
00211 
00218 #define SCF_IMPLEMENT_IBASE_QUERY_END                                   \
00219   return scfParent ?                                                    \
00220     scfParent->QueryInterface (iInterfaceID, iVersion) : NULL;          \
00221 }
00222 
00228 #define SCF_IMPLEMENT_IBASE(Class)                                      \
00229   SCF_IMPLEMENT_IBASE_INCREF(Class)                                     \
00230   SCF_IMPLEMENT_IBASE_DECREF(Class)                                     \
00231   SCF_IMPLEMENT_IBASE_GETREFCOUNT(Class)                                \
00232   SCF_IMPLEMENT_IBASE_QUERY(Class)
00233 
00238 #define SCF_IMPLEMENT_IBASE_END                                         \
00239   SCF_IMPLEMENT_IBASE_QUERY_END
00240 
00247 #define SCF_IMPLEMENT_EMBEDDED_IBASE_INCREF(Class)                      \
00248 void Class::IncRef ()                                                   \
00249 {                                                                       \
00250   SCF_TRACE (("  (%s *)%p->IncRef (%d)\n", #Class, this,                \
00251     scfParent->GetRefCount () + 1));                                    \
00252   scfParent->IncRef ();                                                 \
00253 }
00254 
00261 #define SCF_IMPLEMENT_EMBEDDED_IBASE_DECREF(Class)                      \
00262 void Class::DecRef ()                                                   \
00263 {                                                                       \
00264   SCF_TRACE (("  (%s *)%p->DecRef (%d)\n", #Class, this,                \
00265               scfParent->GetRefCount ()-1));                            \
00266   scfParent->DecRef ();                                                 \
00267 }
00268 
00273 #define SCF_IMPLEMENT_EMBEDDED_IBASE_GETREFCOUNT(Class)                 \
00274 int Class::GetRefCount ()                                               \
00275 {                                                                       \
00276   return scfParent->GetRefCount ();                                     \
00277 }
00278 
00285 #define SCF_IMPLEMENT_EMBEDDED_IBASE_QUERY(Class)                       \
00286 void *Class::QueryInterface (scfInterfaceID iInterfaceID, int iVersion) \
00287 {                                                                       \
00288   SCF_TRACE (("  (%s *)%p->QueryInterface (%u, %08X)\n",                \
00289     #Class, this, iInterfaceID, iVersion));
00290 
00297 #define SCF_IMPLEMENT_EMBEDDED_IBASE_QUERY_END                          \
00298   return scfParent->QueryInterface (iInterfaceID, iVersion);            \
00299 }
00300 
00307 #define SCF_IMPLEMENT_EMBEDDED_IBASE(Class)                             \
00308   SCF_IMPLEMENT_EMBEDDED_IBASE_INCREF(Class)                            \
00309   SCF_IMPLEMENT_EMBEDDED_IBASE_DECREF(Class)                            \
00310   SCF_IMPLEMENT_EMBEDDED_IBASE_GETREFCOUNT(Class)                       \
00311   SCF_IMPLEMENT_EMBEDDED_IBASE_QUERY(Class)
00312 
00317 #define SCF_IMPLEMENT_EMBEDDED_IBASE_END                                \
00318   SCF_IMPLEMENT_EMBEDDED_IBASE_QUERY_END
00319 
00326 #define SCF_IMPLEMENTS_INTERFACE(Interface)                             \
00327   SCF_IMPLEMENTS_INTERFACE_COMMON (Interface, this)
00328 
00333 #define SCF_IMPLEMENTS_EMBEDDED_INTERFACE(Interface)                    \
00334   SCF_IMPLEMENTS_INTERFACE_COMMON (Interface, (&scf##Interface))
00335 
00339 #define SCF_IMPLEMENTS_INTERFACE_COMMON(Interface,Object)               \
00340   static scfInterfaceID Interface##_scfID = (scfInterfaceID)-1;         \
00341   if (Interface##_scfID == (scfInterfaceID)-1)                          \
00342     Interface##_scfID = iSCF::SCF->GetInterfaceID (#Interface);         \
00343   if (iInterfaceID == Interface##_scfID &&                              \
00344     scfCompatibleVersion (iVersion, Interface##_VERSION))               \
00345   {                                                                     \
00346     (Object)->IncRef ();                                                \
00347     return STATIC_CAST(Interface*, Object);                             \
00348   }
00349 
00360 #define SCF_DECLARE_IBASE_EXT(ParentClass)                              \
00361   typedef ParentClass __scf_superclass;                                 \
00362   virtual void IncRef ();                                               \
00363   virtual void DecRef ();                                               \
00364   virtual int GetRefCount ();                                           \
00365   virtual void *QueryInterface (scfInterfaceID iInterfaceID, int iVersion)
00366 
00373 #define SCF_IMPLEMENT_IBASE_EXT_INCREF(Class)                           \
00374 void Class::IncRef ()                                                   \
00375 {                                                                       \
00376   __scf_superclass::IncRef ();                                          \
00377 }
00378 
00385 #define SCF_IMPLEMENT_IBASE_EXT_DECREF(Class)                           \
00386 void Class::DecRef ()                                                   \
00387 {                                                                       \
00388   __scf_superclass::DecRef ();                                          \
00389 }
00390 
00397 #define SCF_IMPLEMENT_IBASE_EXT_GETREFCOUNT(Class)                      \
00398 int Class::GetRefCount ()                                               \
00399 {                                                                       \
00400   return __scf_superclass::GetRefCount ();                              \
00401 }
00402 
00409 #define SCF_IMPLEMENT_IBASE_EXT_QUERY(Class)                            \
00410 void *Class::QueryInterface (scfInterfaceID iInterfaceID, int iVersion) \
00411 {
00412 
00419 #define SCF_IMPLEMENT_IBASE_EXT_QUERY_END                               \
00420   return __scf_superclass::QueryInterface (iInterfaceID, iVersion);     \
00421 }
00422 
00427 #define SCF_IMPLEMENT_IBASE_EXT(Class)                                  \
00428   SCF_IMPLEMENT_IBASE_EXT_INCREF(Class)                                 \
00429   SCF_IMPLEMENT_IBASE_EXT_DECREF(Class)                                 \
00430   SCF_IMPLEMENT_IBASE_EXT_GETREFCOUNT(Class)                            \
00431   SCF_IMPLEMENT_IBASE_EXT_QUERY(Class)
00432 
00437 #define SCF_IMPLEMENT_IBASE_EXT_END                                     \
00438   SCF_IMPLEMENT_IBASE_EXT_QUERY_END
00439 
00446 #define SCF_IMPLEMENT_FACTORY(Class)                                    \
00447 void *Class##_Create (iBase *iParent)                                   \
00448 {                                                                       \
00449   void *ret = new Class (iParent);                                      \
00450   SCF_TRACE (("  %p = new %s ()\n", ret, #Class));                      \
00451   return ret;                                                           \
00452 }
00453 
00458 #define SCF_DECLARE_FACTORY(Class)  void* Class##_Create (iBase *iParent);
00459 
00465 struct scfClassInfo
00466 {
00468   char *ClassID;
00470   char *Description;
00476   char *Dependencies;
00478   void *(*Factory) (iBase *iParent);
00479 };
00480 
00481 /*
00482  * The following set of macros are used to define the table that contains
00483  * information about all classes exported from a shared library. This table
00484  * is used with both static and dynamic class linking.
00485  */
00486 
00502 // extern CS_DECLARE_STATIC_VARIABLE_CLEANUP 
00503 #define SCF_EXPORT_CLASS_TABLE(LibraryName)                             \
00504 CS_DECLARE_STATIC_VARIABLE_CLEANUP                                      \
00505 CS_EXPORTED_FUNCTION void                                               \
00506 CS_EXPORTED_NAME(LibraryName,_scfFinalize)()                            \
00507 { CS_STATIC_VARIABLE_CLEANUP }                                          \
00508 static inline void                                                      \
00509 CS_EXPORTED_NAME(LibraryName,_scfUnitInitialize)(iSCF *SCF)             \
00510 { iSCF::SCF = SCF; }                                                    \
00511 CS_EXPORTED_FUNCTION scfClassInfo*                                      \
00512 CS_EXPORTED_NAME(LibraryName,_scfInitialize)(iSCF *SCF)                 \
00513 {                                                                       \
00514   CS_EXPORTED_NAME(LibraryName,_scfUnitInitialize)(SCF);                \
00515   static scfClassInfo ExportClassTable [] =                             \
00516   {
00517 
00519 #define SCF_EXPORT_CLASS(Class, ClassID, Description)                   \
00520     { ClassID, Description, NULL, Class##_Create },
00521 
00523 #define SCF_EXPORT_CLASS_DEP(Class, ClassID, Description, Dependencies) \
00524     { ClassID, Description, Dependencies, Class##_Create },
00525 
00527 #define SCF_EXPORT_CLASS_TABLE_END                                      \
00528     { 0, 0, 0, 0 }                                                      \
00529   };                                                                    \
00530   return ExportClassTable;                                              \
00531 }
00532 
00540 #define SCF_REGISTER_STATIC_LIBRARY(LibraryName)                        \
00541   extern "C" scfClassInfo *LibraryName##_scfInitialize (iSCF*);         \
00542   class __##LibraryName##_Init                                          \
00543   {                                                                     \
00544   public:                                                               \
00545     __##LibraryName##_Init ()                                           \
00546     { if (!iSCF::SCF) scfInitialize ();                                 \
00547       iSCF::SCF->RegisterClassList(LibraryName##_scfInitialize(iSCF::SCF)); }\
00548   } __##LibraryName##_dummy;
00549 
00555 #define SCF_REGISTER_STATIC_CLASS(Class,ClassID,Description)            \
00556   SCF_REGISTER_STATIC_CLASS_DEP (Class,ClassID,Description,NULL);
00557 
00562 #define SCF_REGISTER_STATIC_CLASS_DEP(Class,ClassID,Description,Dependency)\
00563   extern void *Class##_Create (iBase *);                                \
00564   static scfClassInfo Class##_ClassInfo =                               \
00565   { ClassID, Description, Dependency, Class##_Create };                 \
00566   class Class##_Init__                                          \
00567   {                                                                     \
00568   public:                                                               \
00569     Class##_Init__ ()                                                   \
00570     { if (!iSCF::SCF) scfInitialize ();                                 \
00571       iSCF::SCF->RegisterStaticClass (&Class##_ClassInfo); }            \
00572   } Class##_dummy__;
00573 
00574 //--------------------------------------------- Class factory interface -----//
00575 
00588 struct iFactory : public iBase
00589 {
00591   virtual void *CreateInstance () = 0;
00593   virtual void TryUnload () = 0;
00595   virtual const char *QueryDescription () = 0;
00597   virtual const char *QueryDependencies () = 0;
00599   virtual const char *QueryClassID () = 0;
00600 };
00601 
00602 //----------------------------------------------- Client-side functions -----//
00603 
00604 struct iConfigFile;
00605 struct iStrVector;
00606 
00611 #define SCF_CREATE_INSTANCE(ClassID,Interface)                          \
00612   (Interface *)iSCF::SCF->CreateInstance (                              \
00613   ClassID, #Interface, Interface##_VERSION)
00614 
00627 #define SCF_VERSION(Name,Major,Minor,Micro)                             \
00628   const int Name##_VERSION = SCF_CONSTRUCT_VERSION (Major, Minor, Micro); \
00629 inline static scfInterfaceID Name##_scfGetID ()                         \
00630 {                                                                       \
00631   static scfInterfaceID ID = (scfInterfaceID)-1;                        \
00632   if (ID == (scfInterfaceID)(-1))                                       \
00633     ID = iSCF::SCF->GetInterfaceID (#Name);                             \
00634   return ID;                                                            \
00635 }
00636 
00641 #define SCF_QUERY_INTERFACE(Object,Interface)                           \
00642   csPtr<Interface> ((Interface *)(Object)->QueryInterface (             \
00643   Interface##_scfGetID (), Interface##_VERSION))
00644 
00650 #define SCF_QUERY_INTERFACE_SAFE(Object,Interface)                      \
00651   csPtr<Interface> ((Interface *)(iBase::QueryInterfaceSafe ((Object),  \
00652   Interface##_scfGetID (), Interface##_VERSION)))
00653 
00661 extern void scfInitialize (iConfigFile *iConfig = 0);
00662 
00669 static inline bool scfCompatibleVersion (int iVersion, int iItfVersion)
00670 {
00671   return ((iVersion & 0xff000000) == (iItfVersion & 0xff000000))
00672       && ((iVersion & 0x00ffffff) <= (iItfVersion & 0x00ffffff));
00673 }
00674 
00675 #ifdef CS_DEBUG
00676   struct iObjectRegistry;
00677 #endif
00678 
00685 struct iSCF : public iBase
00686 {
00688   static iSCF *SCF;
00689 
00690 #ifdef CS_DEBUG
00691   // This is EXTREMELY dirty but I see no other solution for now.
00692   // For debugging reasons I must have a global (global over the application
00693   // and all plugins)pointer to the object registry. I have no other
00694   // global object to tag this pointer on that except for iSCF.
00695   // This pointer is only here in debug mode though. That ensures that it
00696   // cannot be misused in real code.
00697   // If you know another solution for this problem? This global pointer
00698   // will be used by csDebuggingGraph in csutil.
00699   iObjectRegistry* object_reg;
00700 #endif
00701 
00706   virtual void RegisterConfigClassList (iConfigFile *Config) = 0;
00707 
00714   virtual bool ClassRegistered (const char *iClassID) = 0;
00715 
00731   virtual void *CreateInstance (const char *iClassID,
00732         const char *iInterface, int iVersion) = 0;
00733 
00739   virtual const char *GetClassDescription (const char *iClassID) = 0;
00740 
00746   virtual const char *GetClassDependencies (const char *iClassID) = 0;
00747 
00754   virtual void UnloadUnusedModules () = 0;
00755 
00763   virtual bool RegisterClass (const char *iClassID,
00764         const char *iLibraryName, const char *Dependencies = NULL) = 0;
00765 
00772   virtual bool RegisterStaticClass (scfClassInfo *iClassInfo) = 0;
00773 
00782   virtual bool RegisterClassList (scfClassInfo *iClassInfo) = 0;
00783 
00790   virtual bool UnregisterClass (const char *iClassID) = 0;
00791 
00797   virtual scfInterfaceID GetInterfaceID (const char *iInterface) = 0;
00798 
00805   virtual void Finish () = 0;
00806 
00817   virtual iStrVector* QueryClassList (char const* pattern) = 0;
00818 };
00819 
00820 SCF_VERSION (iFactory, 0, 0, 1);
00821 SCF_VERSION (iBase, 0, 1, 0);
00822 SCF_VERSION (iSCF, 0, 0, 1);
00823 
00824 
00825 /* @} */
00826 
00827 #endif // __CSSCF_H__

Generated for Crystal Space by doxygen 1.2.14