00001
00002
00003
00004
00005 #ifndef DYNOBJ_H
00006 #define DYNOBJ_H
00007
00008
00009
00010
00011
00012 #include "DoSetup.h"
00013
00014
00015 #include "DoType.h"
00016
00017
00018 #include "DoError.h"
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #ifdef DO_MODULE
00036 #ifdef DO_MAIN
00037 #error Both DO_MODULE and DO_MAIN are defined
00038 #endif
00039 #elif defined(DO_MAIN)
00040
00041 #else
00042
00043 #endif
00044
00045 #if DO_USE_RUNTIME==1
00046 #if DO_FAT_VOBJ!=1
00047 #error DO_USE_RUNTIME requires DO_FAT_VOBJ=1 !
00048 #endif
00049 #endif
00050
00051
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077 #define TYPE_ID_MASK 0xFFFFF000 // Bits 12..31
00078
00079
00080 #define INVALID_TYPE_ID 0xFFFFF000 // Type error / non existing type
00081
00082
00083 #define SIDEBASE_TYPE_ID 0xFFFFE000 // All side bas classes have this type ID (cannot be addressed individually from outside)
00084 #define COMPOUND_TYPE_ID 0xFFFFD000 // When casting to a compound object (the container object) (string COMPOUND)
00085 #define OUTERMOST_TYPE_ID 0xFFFFC000 // When casting to the outermost object (the container object) (string OUTERMOST)
00086
00087 #define RUNTIME_TYPE_ID 0xFFFFB000 // Set type ID at run-time for this type
00088 #define UNKNOWN_TYPE_ID 0 // Not known yet.
00089
00090
00091 #define VOBJ_TYPE_ID 0x00001000
00092 #define DYNI_TYPE_ID 0x00002000
00093 #define DYNOBJ_TYPE_ID 0x00003000
00094 #define REFCOUNTI_TYPE_ID 0x00004000
00095 #define DYNSHAREDI_TYPE_ID 0x00005000
00096
00097 #define DYNDATA_TYPE_ID 0x00006000
00098 #define RTDYNSHARED_TYPE_ID 0x00008000
00099
00100 #define DORUNTIMEI_TYPE_ID 0x00010000
00101 #define DORT_TYPE_ID DORUNTIMEI_TYPE_ID
00102 #define DORTINTERNALI_TYPE_ID 0x00011000
00103 #define DOMODULEC_TYPE_ID 0x00012000
00104 #define DYNOBJLIBI_TYPE_ID 0x00013000
00105
00106 #define DYNSTR_TYPE_ID 0x00018000
00107
00108
00109 #define DYNARRCHAR_TYPE_ID 0x00020000
00110 #define DYNARRWCHART_TYPE_ID 0x00021000
00111 #define DYNARRSHORT_TYPE_ID 0x00022000
00112 #define DYNARRINT_TYPE_ID 0x00023000
00113 #define DYNARRINT64_TYPE_ID 0x00024000
00114 #define DYNARRPTR_TYPE_ID 0x00025000
00115 #define DYNARRPTRVOBJ_TYPE_ID 0x00026000
00116 #define DYNARRPTRDYNI_TYPE_ID 0x00027000
00117
00118 #define DYNARGS_TYPE_ID 0x00028000 // Wrapped up constructor args
00119
00120 #define NOTIFIERI_TYPE_ID 0x00030000
00121 #define NOTIFIABLEI_TYPE_ID 0x00031000
00122 #define NOTIFDATAI_TYPE_ID 0x00032000
00123 #define NOTIFDATAWITHPTR_TYPE_ID 0x00033000
00124
00125 #define BASE_CUSTOM_TYPE_ID 0x00400000 // Custom fix IDs goes after this
00126 #define MAX_CUSTOM_TYPE_ID 0x7FFFF000 // Custom fix IDs goes after this
00127 #define BASE_APPSPEC_TYPE_ID 0x80000000 // Custome type IDs start here
00128 #define MAX_APPSPEC_TYPE_ID 0xEFFFF000 // Custom type IDs cannot go beyond this (clash with auto id)
00129 #define BASE_AUTO_TYPE_ID 0xFFF00000 // Auto IDs start here and count down (run-time generated)
00130 #define MIN_AUTO_TYPE_ID 0xF0000000 // Auto IDs start here and count down (run-time generated)
00131
00132 #define STEP_TYPE_ID 0x00001000 // How much to increment/decrement for each type
00133
00134
00135 #if DO_NO_TYPEINFO!=1
00136
00140 template<class T>
00141 struct doTypeInfo {
00142 static int Id( ){ return UNKNOWN_TYPE_ID; }
00143 static const char* Name( ){ return NULL; }
00144
00145 };
00146
00148
00149 template<class T>
00150 struct doTypeInfo<T*> {
00151 public:
00152 static int Id( ){ return doTypeInfo<T>::Id(); }
00153 static const char* Name( ){ return doTypeInfo<T>::Name(); }
00154
00155 };
00156
00157
00158 template<class T>
00159 struct doTypeInfo<T&> {
00160 public:
00161 static int Id( ){ return doTypeInfo<T>::Id(); }
00162 static const char* Name( ){ return doTypeInfo<T>::Name(); }
00163
00164 };
00165
00166
00167 template<class T>
00168 struct doTypeInfo<const T> {
00169 public:
00170 static int Id( ){ return doTypeInfo<T>::Id(); }
00171 static const char* Name( ){ return doTypeInfo<T>::Name(); }
00172
00173 };
00174 #endif //DO_NO_TYPEINFO
00176
00177
00178
00179 #if DO_FAT_VOBJ==1
00180
00181 void* doGetObj( void* pobj, const char *type, DynObjType *self_type, doCastAlgo algo=doCastFull, DynObjType **found_type=NULL );
00182 void* doGetObj( void* pobj, int type_id, DynObjType *self_type, doCastAlgo algo=doCastFull, DynObjType **found_type=NULL );
00183 void* doGetObj( DynI* pdi, const char *type, doCastAlgo algo=doCastFull, DynObjType **found_type=NULL );
00184 void* doGetObj( DynI* pdi, int type_id, doCastAlgo algo=doCastFull, DynObjType **found_type=NULL );
00185 DynObjType* doGetType( const void* pobj );
00186 DynObjType* doGetType( const DynI* pdi );
00187 #endif
00188
00189
00199
00200 class VObj {
00201 public:
00202
00203
00204 #if DO_FAT_VOBJ==1
00205
00208
00212 DynObjType* GetType( ) const;
00213
00218 bool IsA( int type_id ) const { return IsA(type_id,NULL); }
00219
00224 bool CanBeA( int type_id ) const { return CanBeA(type_id,NULL); }
00225
00227
00228 bool IsA( const char *type ) const { return IsA(type,NULL); }
00229
00230
00232 void* GetObj( int type_id, doCastAlgo algo=doCastFull ) { return ::doGetObj(this,type_id,NULL,algo); }
00233
00235 void* GetObj( const char *type, doCastAlgo algo=doCastFull ) { return ::doGetObj(this,type,NULL,algo); }
00236
00241 const char* GetError( int* perr_code=NULL ) const;
00242
00244 void ClearError( );
00245
00247 bool SetError( const char *err_str, int err_code=-1 ) const;
00248
00250 bool IsA( int type_id, DynObjType *ptype ) const;
00252 bool CanBeA( int type_id, DynObjType *ptype ) const;
00254 bool IsA( const char *type, DynObjType *ptype ) const;
00255
00256
00258 const char *GetTypeName( ) const {
00259 DynObjType *pdt = ::doGetType(this);
00260 return pdt ? pdt->_type : NULL;
00261 }
00262
00264 bool doIsOk( ) const { return this && !GetError(); }
00266 #endif // DO_FAT_VOBJ
00267 };
00268
00269
00281
00282 class DynI : public VObj {
00283 public:
00287
00297 virtual DynObjType* docall doGetType( const DynI **pself=NULL ) const;
00298
00320 virtual void* docall doQueryI( const char *type );
00321
00330 virtual const char* docall doGetError( int* perr_code=NULL ) const;
00331
00333 virtual void docall docall doClearError( );
00335
00336 #if DO_FAT_VOBJ==1
00337
00340
00341
00342
00343 DynObjType *GetType() const { return ::doGetType(this); }
00344 bool doIsOk( ) const { return this && !doGetError(); }
00345 const char *GetTypeName( ) const { DynObjType *pdt=DI_GET_TYPE(this); return pdt ? pdt->_type : NULL; }
00346 int GetTypeId( ) const { DynObjType *pdt=DI_GET_TYPE(this); return pdt ? pdt->_type_id : -1; }
00347 int GetObjectSize( ) const { DynObjType *pdt=DI_GET_TYPE(this); return pdt ? pdt->_size : -1; }
00348
00349 bool IsA( int type_id ) const { return VObj::IsA( type_id, DI_GET_TYPE(this) ); }
00350 bool CanBeA( int type_id ) const { return VObj::CanBeA( type_id, DI_GET_TYPE(this) ); }
00351 bool IsA( const char *type ) const { return VObj::IsA( type, DI_GET_TYPE(this) ); }
00352
00353
00355 void* GetObj( int type_id, doCastAlgo algo=doCastFull ) { return ::doGetObj(this,type_id,algo); }
00356
00358 void* GetObj( const char *type, doCastAlgo algo=doCastFull ) { return ::doGetObj(this,type,algo); }
00359
00360
00361 void* doGetObj( const char* type ){ return doQueryI( type ); }
00363
00367
00368
00369
00370
00371
00372
00373 #if DO_ENABLE_OPERATOR_DELETE==1
00374 void operator delete( void *pv ){
00375 SetError( "DynObj::operator delete on a DynI", DOERR_DELETE_ON_DYNI );
00376 }
00377 #endif // DO_ENABLE_OPERATOR_DELETE
00378
00379 #endif // DO_FAT_VOBJ
00380 };
00381
00382
00383 #define DynINull (*(DynI*)(0))
00384
00391
00392 class DynObj : public DynI {
00393 public:
00397
00398
00399 virtual DynObjType* docall doGetType( const DynI **pself=0 ) const;
00400
00406 virtual void docall doDestroy( ) { };
00407
00408 protected:
00415 virtual void docall doDtor( ){ }
00417 public:
00418
00422
00423 #if DO_FAT_VOBJ==1
00424
00425 DynObj();
00426 ~DynObj();
00427 #endif // DO_FAT_VOBJ
00428
00429 #if DO_ENABLE_OPERATOR_DELETE==1
00430
00435 void operator delete( void *pv ){
00436 if( !pv ) return;
00437 if( pv!=this )
00438 SetError( "DynObj::operator delete on wrong object", DOERR_DELETE_ON_WRONG_OBJECT );
00439 else
00440 doDestroy();
00441 }
00442 #endif // DO_ENABLE_OPERATOR_DELETE
00443
00444 };
00445
00446 #if DO_USE_DYNSHARED==1
00447
00448 #include "RefCount.h"
00449
00450
00451
00474
00475 class DynSharedI : public DynObj, public RefCountI {
00476 public:
00477
00478 virtual DynObjType* docall doGetType( const DynI **pself=0 ) const;
00479
00483 virtual int docall doAddRef( ) = 0;
00484
00488 virtual int docall doRelease( ) = 0;
00489
00490
00494 virtual int docall IncRef(){ return doAddRef(); }
00495 virtual int docall DecRef(){ return doRelease(); }
00496
00497
00498
00499 };
00500
00501 #endif // DO_USE_DYNSHARED==1
00502
00503
00504 #if DO_RETURN_STRUCT_WITH_DTOR_SAFE==1
00505
00511 struct DynObjRetVal {
00512 DynObjRetVal( DynObj *pdo ) : m_pdo(pdo) { }
00513 ~DynObjRetVal(){ Free(); }
00514
00515 DynObj *Release(){ DynObj *pdo=m_pdo; m_pdo=NULL; return pdo; }
00516 DynObjRetVal& operator = (DynObjRetVal& other){ Free(); m_pdo=other.Release(); return *this; }
00517
00518
00519 protected:
00520 void Free(){ if(m_pdo) { m_pdo->doDestroy(); m_pdo=NULL; } }
00521 DynObj *m_pdo;
00522 };
00523
00524
00525 #if DO_USE_DYNSHARED==1
00526
00531 struct DynSharedRetVal {
00532 DynSharedRetVal( DynSharedI *pds ) : m_pds(pds) { }
00533 ~DynSharedRetVal(){ if(m_pds) m_pds->doRelease(); }
00534 DynSharedI *Release(){ DynSharedI *pds=m_pds; m_pds=NULL; return pds; }
00535 protected:
00536 DynSharedI *m_pds;
00537 };
00538 #endif // DO_USE_DYNSHARED==1
00539
00540 #endif // DO_RETURN_STRUCT_WITH_DTOR_SAFE==1
00541
00542
00543
00544 #if DO_NO_TYPEINFO!=1
00545
00548
00551 #define DO_DECL_TYPE_INFO(CLASS,ID) \
00552 template<> \
00553 struct doTypeInfo<CLASS> { \
00554 public: \
00555 static int Id( ){ return ID; } \
00556 static const char* Name( ){ return #CLASS; } \
00557 };
00558
00559
00560 int doLookupTypeId( const char *header, const char *type );
00561
00564 #define DO_DECL_TYPE_INFO_AUTOID(CLASS) \
00565 template<> \
00566 struct doTypeInfo<CLASS> { \
00567 public: \
00568 static int Id( ){ \
00569 static int st_id; \
00570 if( !st_id ) st_id=doLookupTypeId(__FILE__,#CLASS); \
00571 return st_id; \
00572 } \
00573 static const char* Name( ){ return #CLASS; } \
00574 };
00575
00576
00577 #else // DO_NO_TYPEINFO
00578 #define DO_DECL_TYPE_INFO(CLASS,ID)
00579 #define DO_DECL_TYPE_INFO_ALIAS(CLASS,REALCLASS)
00580 #endif // DO_NO_TYPEINFO
00581
00582
00583
00585 DO_DECL_TYPE_INFO(VObj,VOBJ_TYPE_ID);
00586 DO_DECL_TYPE_INFO(DynI,DYNI_TYPE_ID);
00587 DO_DECL_TYPE_INFO(DynObj,DYNOBJ_TYPE_ID);
00588 #if DO_USE_DYNSHARED==1
00589 DO_DECL_TYPE_INFO(RefCountI,REFCOUNTI_TYPE_ID);
00590 DO_DECL_TYPE_INFO(DynSharedI,DYNSHAREDI_TYPE_ID);
00591 #endif
00593
00594
00598 DynObjType* doGetType( const void* pobj );
00599
00603 DynObjType* doGetType( const DynI* pdi );
00604
00605
00613 void* doGetObj( void* pobj, const char *type, DynObjType *self_type, doCastAlgo algo, DynObjType **found_type );
00614
00622 void* doGetObj( void* pobj, int type_id, DynObjType *self_type, doCastAlgo algo, DynObjType **found_type );
00623
00625 void* doGetObj( DynI* pdi, const char *type, doCastAlgo algo, DynObjType **found_type );
00626
00628 void* doGetObj( DynI* pdi, int type_id, doCastAlgo algo, DynObjType **found_type );
00629
00630
00634 DynObjType *doFindType( const char *type, const char *header=NULL );
00635
00639 DynObjType *doFindType( int type_id );
00640
00643 int doIsMainObject( DynI* pdi );
00645 int doIsMainObject( const void *pobj, DynObjType *pdt=NULL );
00646
00647
00648 #ifdef DO_MAIN
00649
00656 bool doInit( const void* pmain_base=(const void*)-1 );
00657 #endif // DO_MAIN
00658
00659
00679 bool doConstruct( const void *obj, DynObjType *self_type, DynObjType *pdt_compound=NULL );
00680
00681
00690 bool doConstruct( const void *obj, const char *type, const char *header=NULL );
00692 bool doConstruct( const void *obj, int type_id, const char *header=NULL );
00693
00700 bool doConstructDelayed( const void *obj, DynObjType *self_type );
00701
00707 void doReleaseDestroy( DynObj *pdo );
00708
00716 bool doIsStatic( const void *pvo, DynObjType *type=NULL );
00717 bool doIsStatic( const DynI *pdi );
00718
00722 class DoRunTimeI;
00723 DoRunTimeI &doGetRunTime();
00724
00725
00731 bool doAddImplemented( const char *type, int type_id );
00734 const char *doGetImplemented( );
00735
00736
00737 class doUserTypeDecl {
00738 public:
00739 doUserTypeDecl( const char *type, int type_id ) {
00740 doAddImplemented(type,type_id);
00741 }
00742 };
00744
00745
00746
00747
00748
00749
00750
00753
00754
00755 class DoRunTimeI;
00756 struct doModuleData;
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00782 typedef DynObj* (*CreateDynObjFn)( const char *type, int type_id, const DynI* pdi_init );
00783
00784
00796 typedef doModuleData* (*InitDynLibFn)( DynI* pdi_init );
00797
00804 typedef bool (*ExitDynLibFn)(bool is_query);
00805
00814 typedef bool (*DestroyDynObjFn)( void *pv, DynObjType *pdt );
00815
00816 class DoModuleC;
00817
00821 struct doModuleData {
00822 doModuleData(const char *cs, const char *impl, int dt, int pf);
00823
00824 StructHeader _sh;
00826 const char *_lib_name;
00827 const char *_lib_descr;
00828 const char *_lib_author;
00830 const char *_call_str;
00831 const char *_instantiates;
00832 int _do_traits;
00834 int _platform;
00835 int _lib_major_ver;
00836 int _lib_minor_ver;
00838 DynObjType **_types;
00839 DoModuleC *_module;
00841 const char *_compiler;
00842 int _comp_major_ver;
00843 int _comp_minor_ver;
00845 int _lib_flags;
00847 int _dynobj_major_ver;
00848 int _dynobj_minor_ver;
00850 DynI *_pdi_from_init;
00851 };
00852
00853 #define DOMD_USES_RUNTIME 1
00854 #define DOMD_IS_MAIN 4
00855 #define DOMD_MAY_LOAD_MODULES 8 // May load other modules
00856 #define DOMD_MAY_OVERRIDE_TYPES 16 // May override other types (become first instantiators)
00857 #define DOMD_OBJECT_TRACKING 32 // The library supports object tracking
00858 #define DOMD_DENY_EARLY_UNLOAD 64 // The library rejects being unloaded early (may expose globals that are not trackable)
00859
00860 #ifndef DO_BUILDING_DYNOBJ
00861
00862 extern doModuleData g_do_lib_impl;
00863 #endif
00864
00865
00866
00867
00868 #define DO_PLATFORM_FLAGS ( PLATFORM_FLAGS | (PFM_INT_SIZE<<16) | (PFM_PTR_SIZE<<18) | (PFM_WCHART_SIZE<<20) )
00869
00870
00871
00872
00873 #define VOBJ_SIZE sizeof(void*)
00874
00875
00876
00877
00878 #ifdef DO_IMPLEMENT_DYNOBJ
00879
00880
00881 DynObjType g_do_vtype_VObj("VObj",(const char*)NULL,VOBJ_TYPE_ID,0,VOBJ_SIZE,NULL,NULL,__FILE__);
00882 DynObjType g_do_vtype_DynI("DynI","VObj",DYNI_TYPE_ID,0,sizeof(DynI),NULL,NULL,__FILE__);
00883 DynObjType* DynI::doGetType( const DynI **pself ) const {
00884 if(pself) *pself=(const DynI*)(const void*)this;
00885 return &g_do_vtype_DynI;
00886 }
00887 DynObjType g_do_vtype_DynObj("DynObj","DynI",DYNOBJ_TYPE_ID,0,sizeof(DynObj),NULL,NULL,__FILE__);
00888 DynObjType* DynObj::doGetType( const DynI **pself ) const {
00889 if(pself) *pself=(const DynI*)(const void*)this;
00890 return &g_do_vtype_DynObj;
00891 }
00892
00893 #if DO_USE_DYNSHARED==1
00894 DynObjType g_do_vtype_RefCountI("RefCountI","VObj",REFCOUNTI_TYPE_ID,0,sizeof(RefCountI),NULL,NULL,__FILE__);
00895 DynObjType g_do_vtype_DynSharedI("DynSharedI","DynObj",DYNSHAREDI_TYPE_ID,0,sizeof(DynSharedI),NULL,NULL,__FILE__);
00896 SideBaseDecl g_do_vtype_sbd_DynSharedI_1("DynSharedI","RefCountI",sizeof(RefCountI),sidebase_offset<DynSharedI,RefCountI>(),NULL,-1,NULL);
00897 DynObjType* DynSharedI::doGetType( const DynI **pself ) const {
00898 if(pself) *pself=(const DynI*)(const void*)this;
00899 return &g_do_vtype_DynSharedI;
00900 }
00901 #endif
00902 #endif //DO_IMPLEMENT_...
00903
00904
00905 #endif // DYNOBJ_H
00906
00907