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
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; \
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; \
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
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
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
00777
00778
00779
00780
00781
00782
00783
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__