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
00023
00024
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; \
00129 SCF_DECLARE_EMBEDDED_IBASE (iBase)
00130
00135 #define SCF_DECLARE_EMBEDDED_IBASE(OuterClass) \
00136 public: \
00137 OuterClass *scfParent; \
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
00489
00490
00491
00492
00508
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
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
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
00706
00707
00708
00709
00710
00711
00712
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__