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 scfParent->DecRef (); \
00271 SCF_TRACE ((" (%s *)%p->DecRef (%d)\n", #Class, this, \
00272 scfParent->GetRefCount ())); \
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 #define SCF_EXPORT_CLASS_TABLE(LibraryName) \
00509 static inline void \
00510 SCF_EXPORTED_NAME(LibraryName,_scfUnitInitialize)(iSCF *SCF) \
00511 { iSCF::SCF = SCF; } \
00512 SCF_EXPORT_FUNCTION scfClassInfo* \
00513 SCF_EXPORTED_NAME(LibraryName,_scfInitialize)(iSCF *SCF) \
00514 { \
00515 SCF_EXPORTED_NAME(LibraryName,_scfUnitInitialize)(SCF); \
00516 static scfClassInfo ExportClassTable [] = \
00517 {
00518
00520 #define SCF_EXPORT_CLASS(Class, ClassID, Description) \
00521 { ClassID, Description, NULL, Create_##Class },
00522
00524 #define SCF_EXPORT_CLASS_DEP(Class, ClassID, Description, Dependencies) \
00525 { ClassID, Description, Dependencies, Create_##Class },
00526
00528 #define SCF_EXPORT_CLASS_TABLE_END \
00529 { 0, 0, 0, 0 } \
00530 }; \
00531 return ExportClassTable; \
00532 }
00533
00541 #define SCF_REGISTER_STATIC_LIBRARY(LibraryName) \
00542 extern "C" scfClassInfo *LibraryName##_scfInitialize (iSCF*); \
00543 class __##LibraryName##_Init \
00544 { \
00545 public: \
00546 __##LibraryName##_Init () \
00547 { if (!iSCF::SCF) scfInitialize (); \
00548 iSCF::SCF->RegisterClassList(LibraryName##_scfInitialize(iSCF::SCF)); }\
00549 } __##LibraryName##_dummy;
00550
00556 #define SCF_REGISTER_STATIC_CLASS(Class,ClassID,Description) \
00557 SCF_REGISTER_STATIC_CLASS_DEP (Class,ClassID,Description,NULL);
00558
00563 #define SCF_REGISTER_STATIC_CLASS_DEP(Class,ClassID,Description,Dependency)\
00564 extern void *Create_##Class (iBase *); \
00565 static scfClassInfo Class##_ClassInfo = \
00566 { ClassID, Description, Dependency, Create_##Class }; \
00567 class __##Class##_Init \
00568 { \
00569 public: \
00570 __##Class##_Init () \
00571 { if (!iSCF::SCF) scfInitialize (); \
00572 iSCF::SCF->RegisterStaticClass (&Class##_ClassInfo); } \
00573 } __##Class##_dummy;
00574
00575
00576
00577 SCF_VERSION (iFactory, 0, 0, 1);
00578
00591 struct iFactory : public iBase
00592 {
00594 virtual void *CreateInstance () = 0;
00596 virtual void TryUnload () = 0;
00598 virtual const char *QueryDescription () = 0;
00600 virtual const char *QueryDependencies () = 0;
00602 virtual const char *QueryClassID () = 0;
00603 };
00604
00605
00606
00607 struct iConfigFile;
00608 struct iStrVector;
00609
00616 #define SCF_DECLARE_FAST_INTERFACE(Interface) \
00617 inline static scfInterfaceID scfGetID_##Interface () \
00618 { \
00619 static scfInterfaceID ID = (scfInterfaceID)-1; \
00620 if (ID == (scfInterfaceID)(-1)) \
00621 ID = iSCF::SCF->GetInterfaceID (#Interface); \
00622 return ID; \
00623 }
00624
00629 #define SCF_CREATE_INSTANCE(ClassID,Interface) \
00630 (Interface *)iSCF::SCF->CreateInstance ( \
00631 ClassID, #Interface, VERSION_##Interface)
00632
00637 #define SCF_QUERY_INTERFACE(Object,Interface) \
00638 (Interface *)(Object)->QueryInterface ( \
00639 iSCF::SCF->GetInterfaceID (#Interface), VERSION_##Interface)
00640
00648 #define SCF_QUERY_INTERFACE_FAST(Object,Interface) \
00649 (Interface*)(Object)->QueryInterface ( \
00650 scfGetID_##Interface (), VERSION_##Interface)
00651
00657 #define SCF_QUERY_INTERFACE_SAFE(Object,Interface) \
00658 (Interface *)(iBase::QueryInterfaceSafe ((Object), \
00659 iSCF::SCF->GetInterfaceID (#Interface), VERSION_##Interface))
00660
00668 extern void scfInitialize (iConfigFile *iConfig = 0);
00669
00676 static inline bool scfCompatibleVersion (int iVersion, int iItfVersion)
00677 {
00678 return ((iVersion & 0xff000000) == (iItfVersion & 0xff000000))
00679 && ((iVersion & 0x00ffffff) <= (iItfVersion & 0x00ffffff));
00680 }
00681
00682 SCF_VERSION (iSCF, 0, 0, 1);
00683
00690 struct iSCF : public iBase
00691 {
00693 static iSCF *SCF;
00694
00699 virtual void RegisterConfigClassList (iConfigFile *Config) = 0;
00700
00707 virtual bool ClassRegistered (const char *iClassID) = 0;
00708
00724 virtual void *CreateInstance (const char *iClassID,
00725 const char *iInterface, int iVersion) = 0;
00726
00732 virtual const char *GetClassDescription (const char *iClassID) = 0;
00733
00739 virtual const char *GetClassDependencies (const char *iClassID) = 0;
00740
00747 virtual void UnloadUnusedModules () = 0;
00748
00756 virtual bool RegisterClass (const char *iClassID,
00757 const char *iLibraryName, const char *Dependencies = NULL) = 0;
00758
00765 virtual bool RegisterStaticClass (scfClassInfo *iClassInfo) = 0;
00766
00775 virtual bool RegisterClassList (scfClassInfo *iClassInfo) = 0;
00776
00783 virtual bool UnregisterClass (const char *iClassID) = 0;
00784
00790 virtual scfInterfaceID GetInterfaceID (const char *iInterface) = 0;
00791
00798 virtual void Finish () = 0;
00799
00810 virtual iStrVector* QueryClassList (char const* pattern) = 0;
00811 };
00812
00813
00814
00815
00816
00817
00818
00819
00820 #if !defined(SCF_EXPORT_FUNCTION)
00821 # define SCF_EXPORT_FUNCTION extern "C"
00822 #endif
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835 #if !defined(SCF_EXPORTED_NAME)
00836 # define SCF_EXPORTED_NAME(Prefix, Suffix) Prefix ## Suffix
00837 #endif
00838
00839 #endif // __CSSCF_H__