00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef __CSSCF_H__
00021 #define __CSSCF_H__
00022
00027
00028
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; \
00122 SCF_DECLARE_EMBEDDED_IBASE (iBase)
00123
00128 #define SCF_DECLARE_EMBEDDED_IBASE(OuterClass) \
00129 public: \
00130 OuterClass *scfParent; \
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
00175
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
00483
00484
00485
00486
00502
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
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
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
00692
00693
00694
00695
00696
00697
00698
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__