CrystalSpace

Public API Reference

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

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 
00031 class csPluginPaths;
00032 
00033 #include "csutil/ref.h"
00034 #include "csutil/array.h"
00035 
00039 typedef unsigned long scfInterfaceID;
00040 
00045 #ifdef SCF_DEBUG
00046 #  define SCF_TRACE(x)                                                  \
00047    {                                                                    \
00048      printf ("SCF [%s:%d]:\n", __FILE__, __LINE__);                     \
00049      printf x; SCF_PRINT_CALL_ADDRESS                                   \
00050    }
00051 #else
00052 #  define SCF_TRACE(x)
00053 #endif
00054 
00059 #if (__GNUC__ >= 3) || ((__GNUC__ >= 2) && (__GNUC_MINOR__ >= 8))
00060 #  define SCF_PRINT_CALL_ADDRESS                                        \
00061    printf ("  Called from address %p\n", __builtin_return_address (0));
00062 #else
00063 #  define SCF_PRINT_CALL_ADDRESS
00064 #endif
00065 
00067 #define SCF_CONSTRUCT_VERSION(Major,Minor,Micro)                        \
00068   ((Major << 24) | (Minor << 16) | Micro)
00069 
00075 struct iBase
00076 {
00078   virtual void IncRef () = 0;
00080   virtual void DecRef () = 0;
00082   virtual int GetRefCount () = 0;
00084   virtual void *QueryInterface (scfInterfaceID iInterfaceID, int iVersion) = 0;
00089   static void* QueryInterfaceSafe (iBase* ibase, scfInterfaceID iInterfaceID,
00090         int iVersion)
00091   {
00092     if (ibase == 0) return 0;
00093     else return ibase->QueryInterface (iInterfaceID, iVersion);
00094   }
00095 };
00096 
00098 #define SCF_INC_REF(ptr) {if (ptr) {ptr->IncRef();}}
00099 
00101 #define SCF_DEC_REF(ptr) {if (ptr) {ptr->DecRef();}}
00102 
00108 #define SCF_SET_REF(var,ref) \
00109   { \
00110     if (ref) ref->IncRef (); \
00111     if (var) var->DecRef (); \
00112     var = ref; \
00113   }
00114 
00119 #define SCF_DECLARE_IBASE                                               \
00120   int scfRefCount;              /* Reference counter */                 \
00121   SCF_DECLARE_EMBEDDED_IBASE (iBase)
00122 
00129 #define SCF_DECLARE_IBASE_WEAK(Class)                                   \
00130   csArray<Class**> weak_ref_owners;                                     \
00131   virtual void AddRefOwner (Class** ref_owner);                         \
00132   virtual void RemoveRefOwner (Class** ref_owner);                      \
00133   virtual void RemoveRefOwners ();                                      \
00134   SCF_DECLARE_IBASE
00135 
00140 #define SCF_DECLARE_EMBEDDED_IBASE(OuterClass)                          \
00141 public:                                                                 \
00142   OuterClass *scfParent;        /* The parent object */                 \
00143   virtual void IncRef ();                                               \
00144   virtual void DecRef ();                                               \
00145   virtual int GetRefCount ();                                           \
00146   virtual void *QueryInterface (scfInterfaceID iInterfaceID, int iVersion)
00147 
00156 #define SCF_CONSTRUCT_IBASE(Parent)                                     \
00157   scfRefCount = 1; scfParent = Parent; if (scfParent) scfParent->IncRef();
00158 
00166 #define SCF_CONSTRUCT_EMBEDDED_IBASE(Interface)                         \
00167   Interface.scfParent = this;
00168 
00174 #define SCF_IMPLEMENT_IBASE_INCREF(Class)                               \
00175 void Class::IncRef ()                                                   \
00176 {                                                                       \
00177   SCF_TRACE (("  (%s *)%p->IncRef (%d)\n", #Class, this, scfRefCount + 1));\
00178   scfRefCount++;                                                        \
00179 }
00180 
00189 #define SCF_IMPLEMENT_IBASE_DECREF(Class)                               \
00190 void Class::DecRef ()                                                   \
00191 {                                                                       \
00192   if (scfRefCount == 1)                                                 \
00193   {                                                                     \
00194     SCF_TRACE ((" delete (%s *)%p\n", #Class, this));                   \
00195     if (scfParent)                                                      \
00196       scfParent->DecRef ();                                             \
00197     delete this;                                                        \
00198     return;                                                             \
00199   }                                                                     \
00200   scfRefCount--;                                                        \
00201 }
00202 
00210 #define SCF_IMPLEMENT_IBASE_WEAK_DECREF(Class)                          \
00211 void Class::DecRef ()                                                   \
00212 {                                                                       \
00213   if (scfRefCount == 1)                                                 \
00214   {                                                                     \
00215     RemoveRefOwners ();                                                 \
00216     SCF_TRACE ((" delete (%s *)%p\n", #Class, this));                   \
00217     if (scfParent)                                                      \
00218       scfParent->DecRef ();                                             \
00219     delete this;                                                        \
00220     return;                                                             \
00221   }                                                                     \
00222   scfRefCount--;                                                        \
00223 }                                                                       \
00224 void Class::RemoveRefOwners ()                                          \
00225 {                                                                       \
00226   for (int i = 0 ; i < weak_ref_owners.Length () ; i++)                 \
00227   {                                                                     \
00228     Class** p = weak_ref_owners[i];                                     \
00229     *p = 0;                                                             \
00230   }                                                                     \
00231   weak_ref_owners.DeleteAll ();                                         \
00232 }
00233 
00238 #define SCF_IMPLEMENT_IBASE_WEAK_REFOWNER(Class)                        \
00239 void Class::AddRefOwner (Class** ref_owner)                             \
00240 {                                                                       \
00241   weak_ref_owners.Push (ref_owner);                                     \
00242 }                                                                       \
00243 void Class::RemoveRefOwner (Class** ref_owner)                          \
00244 {                                                                       \
00245   weak_ref_owners.Delete (ref_owner);                                   \
00246 }
00247 
00252 #define SCF_IMPLEMENT_IBASE_GETREFCOUNT(Class)                          \
00253 int Class::GetRefCount ()                                               \
00254 {                                                                       \
00255   return scfRefCount;                                                   \
00256 }
00257 
00264 #define SCF_IMPLEMENT_IBASE_QUERY(Class)                                \
00265 void *Class::QueryInterface (scfInterfaceID iInterfaceID, int iVersion) \
00266 {                                                                       \
00267   SCF_TRACE (("  (%s *)%p->QueryInterface (%u, %08X)\n",                \
00268     #Class, this, iInterfaceID, iVersion));
00269 
00276 #define SCF_IMPLEMENT_IBASE_QUERY_END                                   \
00277   return scfParent ?                                                    \
00278     scfParent->QueryInterface (iInterfaceID, iVersion) : 0;             \
00279 }
00280 
00286 #define SCF_IMPLEMENT_IBASE(Class)                                      \
00287   SCF_IMPLEMENT_IBASE_INCREF(Class)                                     \
00288   SCF_IMPLEMENT_IBASE_DECREF(Class)                                     \
00289   SCF_IMPLEMENT_IBASE_GETREFCOUNT(Class)                                \
00290   SCF_IMPLEMENT_IBASE_QUERY(Class)
00291 
00298 #define SCF_IMPLEMENT_IBASE_WEAK(Class)                                 \
00299   SCF_IMPLEMENT_IBASE_INCREF(Class)                                     \
00300   SCF_IMPLEMENT_IBASE_WEAK_DECREF(Class)                                \
00301   SCF_IMPLEMENT_IBASE_WEAK_REFOWNER(Class)                              \
00302   SCF_IMPLEMENT_IBASE_GETREFCOUNT(Class)                                \
00303   SCF_IMPLEMENT_IBASE_QUERY(Class)
00304 
00309 #define SCF_IMPLEMENT_IBASE_END                                         \
00310   SCF_IMPLEMENT_IBASE_QUERY_END
00311 
00316 #define SCF_IMPLEMENT_IBASE_WEAK_END                                    \
00317   SCF_IMPLEMENT_IBASE_QUERY_END
00318 
00325 #define SCF_IMPLEMENT_EMBEDDED_IBASE_INCREF(Class)                      \
00326 void Class::IncRef ()                                                   \
00327 {                                                                       \
00328   SCF_TRACE (("  (%s *)%p->IncRef (%d)\n", #Class, this,                \
00329     scfParent->GetRefCount () + 1));                                    \
00330   scfParent->IncRef ();                                                 \
00331 }
00332 
00339 #define SCF_IMPLEMENT_EMBEDDED_IBASE_DECREF(Class)                      \
00340 void Class::DecRef ()                                                   \
00341 {                                                                       \
00342   SCF_TRACE (("  (%s *)%p->DecRef (%d)\n", #Class, this,                \
00343               scfParent->GetRefCount ()-1));                            \
00344   scfParent->DecRef ();                                                 \
00345 }
00346 
00351 #define SCF_IMPLEMENT_EMBEDDED_IBASE_GETREFCOUNT(Class)                 \
00352 int Class::GetRefCount ()                                               \
00353 {                                                                       \
00354   return scfParent->GetRefCount ();                                     \
00355 }
00356 
00363 #define SCF_IMPLEMENT_EMBEDDED_IBASE_QUERY(Class)                       \
00364 void *Class::QueryInterface (scfInterfaceID iInterfaceID, int iVersion) \
00365 {                                                                       \
00366   SCF_TRACE (("  (%s *)%p->QueryInterface (%u, %08X)\n",                \
00367     #Class, this, iInterfaceID, iVersion));
00368 
00375 #define SCF_IMPLEMENT_EMBEDDED_IBASE_QUERY_END                          \
00376   return scfParent->QueryInterface (iInterfaceID, iVersion);            \
00377 }
00378 
00385 #define SCF_IMPLEMENT_EMBEDDED_IBASE(Class)                             \
00386   SCF_IMPLEMENT_EMBEDDED_IBASE_INCREF(Class)                            \
00387   SCF_IMPLEMENT_EMBEDDED_IBASE_DECREF(Class)                            \
00388   SCF_IMPLEMENT_EMBEDDED_IBASE_GETREFCOUNT(Class)                       \
00389   SCF_IMPLEMENT_EMBEDDED_IBASE_QUERY(Class)
00390 
00395 #define SCF_IMPLEMENT_EMBEDDED_IBASE_END                                \
00396   SCF_IMPLEMENT_EMBEDDED_IBASE_QUERY_END
00397 
00404 #define SCF_IMPLEMENTS_INTERFACE(Interface)                             \
00405   SCF_IMPLEMENTS_INTERFACE_COMMON (Interface, this)
00406 
00411 #define SCF_IMPLEMENTS_EMBEDDED_INTERFACE(Interface)                    \
00412   SCF_IMPLEMENTS_INTERFACE_COMMON (Interface, (&scf##Interface))
00413 
00417 #define SCF_IMPLEMENTS_INTERFACE_COMMON(Interface,Object)               \
00418   static scfInterfaceID Interface##_scfID = (scfInterfaceID)-1;         \
00419   if (Interface##_scfID == (scfInterfaceID)-1)                          \
00420     Interface##_scfID = iSCF::SCF->GetInterfaceID (#Interface);         \
00421   if (iInterfaceID == Interface##_scfID &&                              \
00422     scfCompatibleVersion (iVersion, Interface##_VERSION))               \
00423   {                                                                     \
00424     (Object)->IncRef ();                                                \
00425     return STATIC_CAST(Interface*, Object);                             \
00426   }
00427 
00438 #define SCF_DECLARE_IBASE_EXT(ParentClass)                              \
00439   typedef ParentClass __scf_superclass;                                 \
00440   virtual void IncRef ();                                               \
00441   virtual void DecRef ();                                               \
00442   virtual int GetRefCount ();                                           \
00443   virtual void *QueryInterface (scfInterfaceID iInterfaceID, int iVersion)
00444 
00451 #define SCF_IMPLEMENT_IBASE_EXT_INCREF(Class)                           \
00452 void Class::IncRef ()                                                   \
00453 {                                                                       \
00454   __scf_superclass::IncRef ();                                          \
00455 }
00456 
00463 #define SCF_IMPLEMENT_IBASE_EXT_DECREF(Class)                           \
00464 void Class::DecRef ()                                                   \
00465 {                                                                       \
00466   __scf_superclass::DecRef ();                                          \
00467 }
00468 
00475 #define SCF_IMPLEMENT_IBASE_EXT_GETREFCOUNT(Class)                      \
00476 int Class::GetRefCount ()                                               \
00477 {                                                                       \
00478   return __scf_superclass::GetRefCount ();                              \
00479 }
00480 
00487 #define SCF_IMPLEMENT_IBASE_EXT_QUERY(Class)                            \
00488 void *Class::QueryInterface (scfInterfaceID iInterfaceID, int iVersion) \
00489 {
00490 
00497 #define SCF_IMPLEMENT_IBASE_EXT_QUERY_END                               \
00498   return __scf_superclass::QueryInterface (iInterfaceID, iVersion);     \
00499 }
00500 
00505 #define SCF_IMPLEMENT_IBASE_EXT(Class)                                  \
00506   SCF_IMPLEMENT_IBASE_EXT_INCREF(Class)                                 \
00507   SCF_IMPLEMENT_IBASE_EXT_DECREF(Class)                                 \
00508   SCF_IMPLEMENT_IBASE_EXT_GETREFCOUNT(Class)                            \
00509   SCF_IMPLEMENT_IBASE_EXT_QUERY(Class)
00510 
00515 #define SCF_IMPLEMENT_IBASE_EXT_END                                     \
00516   SCF_IMPLEMENT_IBASE_EXT_QUERY_END
00517 
00533 #define SCF_IMPLEMENT_FACTORY_INIT(Class)                               \
00534 static inline void Class ## _scfUnitInitialize(iSCF* SCF)               \
00535 { iSCF::SCF = SCF; }                                                    \
00536 CS_EXPORTED_FUNCTION                                                    \
00537 void CS_EXPORTED_NAME(Class,_scfInitialize)(iSCF* SCF)                  \
00538 { Class ## _scfUnitInitialize(SCF); }
00539 
00545 #define SCF_IMPLEMENT_FACTORY_FINIS(Class)                              \
00546 CS_DECLARE_STATIC_VARIABLE_CLEANUP                                      \
00547 CS_EXPORTED_FUNCTION                                                    \
00548 void CS_EXPORTED_NAME(Class,_scfFinalize)()                             \
00549 {                                                                       \
00550 CS_STATIC_VARIABLE_CLEANUP                                              \
00551 iSCF::SCF = 0;                                                          \
00552 }
00553 
00560 #define SCF_IMPLEMENT_FACTORY_CREATE(Class)                             \
00561 CS_EXPORTED_FUNCTION                                                    \
00562 void* CS_EXPORTED_NAME(Class,_Create)(iBase *iParent)                   \
00563 {                                                                       \
00564   void *ret = new Class (iParent);                                      \
00565   SCF_TRACE (("  %p = new %s ()\n", ret, #Class));                      \
00566   return ret;                                                           \
00567 }
00568 
00575 #define SCF_IMPLEMENT_FACTORY(Class)                                    \
00576   SCF_IMPLEMENT_FACTORY_INIT(Class)                                     \
00577   SCF_IMPLEMENT_FACTORY_FINIS(Class)                                    \
00578   SCF_IMPLEMENT_FACTORY_CREATE(Class)
00579 
00580 #define SCF_STATIC_CLASS_CONTEXT      "*static*"
00581 
00590 #define SCF_REGISTER_STATIC_CLASS(Class,Ident,Desc,Dep)                 \
00591   CS_EXPORTED_FUNCTION void* CS_EXPORTED_NAME(Class,_Create)(iBase*);   \
00592   class Class##_StaticInit__                                            \
00593   {                                                                     \
00594   public:                                                               \
00595     Class##_StaticInit__()                                              \
00596     {                                                                   \
00597       scfInitialize(0);                                                 \
00598       iSCF::SCF->RegisterClass(                                         \
00599         CS_EXPORTED_NAME(Class,_Create), Ident, Desc, Dep,              \
00600         SCF_STATIC_CLASS_CONTEXT);                                      \
00601     }                                                                   \
00602   } Class##_static_init__;
00603 
00608 #define SCF_REGISTER_STATIC_LIBRARY(Module, MetaInfo)                   \
00609   class Module##_StaticInit                                             \
00610   {                                                                     \
00611   public:                                                               \
00612     Module##_StaticInit()                                               \
00613     {                                                                   \
00614       scfInitialize(0);                                                 \
00615       iSCF::SCF->RegisterClasses(MetaInfo, SCF_STATIC_CLASS_CONTEXT);   \
00616     }                                                                   \
00617   } Module##_static_init__;
00618 
00627 #define SCF_REGISTER_FACTORY_FUNC(Class)                                \
00628   CS_EXPORTED_FUNCTION void* CS_EXPORTED_NAME(Class,_Create)(iBase*);   \
00629   class Class##_StaticInit                                              \
00630   {                                                                     \
00631   public:                                                               \
00632     Class##_StaticInit()                                                \
00633     {                                                                   \
00634       scfInitialize(0);                                                 \
00635       iSCF::SCF->RegisterFactoryFunc(CS_EXPORTED_NAME(Class,_Create),#Class); \
00636     }                                                                   \
00637   } Class##_static_init__;
00638 
00639 //--------------------------------------------- Class factory interface -----//
00640 
00654 struct iFactory : public iBase
00655 {
00657   virtual void *CreateInstance () = 0;
00659   virtual void TryUnload () = 0;
00661   virtual const char *QueryDescription () = 0;
00663   virtual const char *QueryDependencies () = 0;
00665   virtual const char *QueryClassID () = 0;
00666 };
00667 
00668 //----------------------------------------------- Client-side functions -----//
00669 
00670 struct iDocument;
00671 struct iStringArray;
00672 
00674 typedef void* (*scfFactoryFunc)(iBase*);
00675 
00680 #define SCF_CREATE_INSTANCE(ClassID,Interface)                          \
00681   (Interface *)iSCF::SCF->CreateInstance (                              \
00682   ClassID, #Interface, Interface##_VERSION)
00683 
00696 #define SCF_VERSION(Name,Major,Minor,Micro)                             \
00697   const int Name##_VERSION = SCF_CONSTRUCT_VERSION (Major, Minor, Micro); \
00698 inline static scfInterfaceID Name##_scfGetID ()                         \
00699 {                                                                       \
00700   static scfInterfaceID ID = (scfInterfaceID)-1;                        \
00701   if (ID == (scfInterfaceID)(-1))                                       \
00702     ID = iSCF::SCF->GetInterfaceID (#Name);                             \
00703   return ID;                                                            \
00704 }
00705 
00710 #define SCF_QUERY_INTERFACE(Object,Interface)                           \
00711   csPtr<Interface> ((Interface *)(Object)->QueryInterface (             \
00712   Interface##_scfGetID (), Interface##_VERSION))
00713 
00719 #define SCF_QUERY_INTERFACE_SAFE(Object,Interface)                      \
00720   csPtr<Interface> ((Interface *)(iBase::QueryInterfaceSafe ((Object),  \
00721   Interface##_scfGetID (), Interface##_VERSION)))
00722 
00736 extern void scfInitialize (csPluginPaths* pluginPaths);
00737 
00742 extern void scfInitialize (int argc, const char* const argv[]);
00743 
00750 static inline bool scfCompatibleVersion (int iVersion, int iItfVersion)
00751 {
00752   return ((iVersion & 0xff000000) == (iItfVersion & 0xff000000))
00753       && ((iVersion & 0x00ffffff) <= (iItfVersion & 0x00ffffff));
00754 }
00755 
00756 #ifdef CS_DEBUG
00757   struct iObjectRegistry;
00758 #endif
00759 
00766 struct iSCF : public iBase
00767 {
00773   static iSCF* SCF;
00774 
00775 #ifdef CS_DEBUG
00776   // This is EXTREMELY dirty but I see no other solution for now.
00777   // For debugging reasons I must have a global (global over the application
00778   // and all plugins)pointer to the object registry. I have no other
00779   // global object to tag this pointer on that except for iSCF.
00780   // This pointer is only here in debug mode though. That ensures that it
00781   // cannot be misused in real code.
00782   // If you know another solution for this problem? This global pointer
00783   // will be used by csDebuggingGraph in csutil.
00784   iObjectRegistry* object_reg;
00785 #endif
00786 
00790   virtual void RegisterClasses (iDocument* metadata,
00791     const char* context = 0) = 0;
00792 
00798   virtual void RegisterClasses (char const* xml,
00799     const char* context = 0) = 0;
00800 
00804   virtual void RegisterClasses (const char* pluginPath, 
00805     iDocument* metadata, const char* context = 0) = 0;
00806 
00813   virtual bool ClassRegistered (const char *iClassID) = 0;
00814 
00830   virtual void *CreateInstance (const char *iClassID,
00831         const char *iInterface, int iVersion) = 0;
00832 
00838   virtual const char *GetClassDescription (const char *iClassID) = 0;
00839 
00845   virtual const char *GetClassDependencies (const char *iClassID) = 0;
00846 
00853   virtual void UnloadUnusedModules () = 0;
00854 
00865   virtual bool RegisterClass (const char *iClassID,
00866         const char *iLibraryName, const char *iFactoryClass,
00867         const char *Description, const char *Dependencies = 0,
00868         const char* context = 0) = 0;
00869 
00876   virtual bool RegisterClass (scfFactoryFunc, const char *iClassID,
00877         const char *Description, const char *Dependencies = 0,
00878         const char* context = 0) = 0;
00879 
00887   virtual bool RegisterFactoryFunc (scfFactoryFunc, const char *FactClass) = 0;
00888 
00895   virtual bool UnregisterClass (const char *iClassID) = 0;
00896 
00902   virtual scfInterfaceID GetInterfaceID (const char *iInterface) = 0;
00903 
00910   virtual void Finish () = 0;
00911 
00922   virtual iStringArray* QueryClassList (char const* pattern) = 0;
00923 
00927   virtual void ScanPluginsPath (const char* path, bool recursive = false,
00928     const char* context = 0) = 0;
00929     
00939   virtual bool RegisterPlugin (const char* path) = 0;
00940 };
00941 
00942 SCF_VERSION (iFactory, 0, 0, 1);
00943 SCF_VERSION (iBase, 0, 1, 0);
00944 SCF_VERSION (iSCF, 0, 2, 0);
00945 
00946 /* @} */
00947 
00948 #endif // __CSSCF_H__

Generated for Crystal Space by doxygen 1.2.14