00001
00002
00003
00004 #ifndef DO_DYN_SHARED_H
00005 #define DO_DYN_SHARED_H
00006
00007 #if DO_USE_DYNSHARED==1
00008
00009
00010
00011 #ifdef DO_IMPLEMENT_DODYNSHARED
00012 #define DO_IMPLEMENTING // If app has not defined it already
00013 #endif
00014 #include "dynobj/DynObj.h"
00015
00016
00017 #define DYNSHAREDC_TYPE_ID 0x8A1AC000
00018
00019
00020 class DynSharedC;
00021 class RTDynShared;
00022
00023
00024 DO_DECL_TYPE_INFO(DynSharedC,DYNSHAREDC_TYPE_ID);
00025 DO_DECL_TYPE_INFO(RTDynShared,RTDYNSHARED_TYPE_ID);
00026
00027
00028
00029
00030 #include "pi/Atomic.h"
00031
00036
00037 class DynSharedC : public DynSharedI {
00038 public:
00039 DynSharedC() : m_ref_cnt(1) { }
00040
00041 virtual DynObjType* docall doGetType( const DynI **pself ) const;
00042
00043
00044 virtual int docall doAddRef( ){
00045 return AtomicIncrement(&m_ref_cnt);
00046 }
00047
00048
00049 virtual int docall doRelease( ){
00050 int cnt = AtomicDecrement(&m_ref_cnt);
00051 if( !cnt )
00052 doDestroy( );
00053 return cnt;
00054 }
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069 protected:
00070 int m_ref_cnt;
00071 };
00072
00073
00083 template<class T>
00084 class ToDynShared : public DynSharedI, T {
00085 public:
00086 ToDynShared( ) : m_ref_cnt(1) { }
00087
00088 virtual int docall doAddRef( ) {
00089 return AtomicIncrement(&m_ref_cnt);
00090 }
00091
00092 virtual int docall doRelease( ) {
00093 int cnt = AtomicDecrement(&m_ref_cnt);
00094 if( !cnt )
00095 doDestroy( );
00096
00097 return cnt;
00098 }
00099
00100 virtual void docall doDestroy( ) {
00101 if( !m_ref_cnt )
00102 ::delete this;
00103 else
00104 SetError("doDestroy on non-zero refcounted object", DOERR_DYNSHARED_DESTROY_ON_NON_ZERO_REF );
00105 }
00106
00107 protected:
00108 int m_ref_cnt;
00109 };
00110
00111
00112
00113
00114
00115
00116
00117
00118
00124
00125 class RTDynShared : public DynSharedI {
00126 public:
00127 RTDynShared( DynObj *pdo=NULL ) : m_pdo(pdo), m_ref_cnt(1) { }
00128
00129 virtual DynObjType* docall doGetType( const DynI **pself ) const;
00130
00131 virtual void* docall doGetObj( const char *type ) {
00132 if( !type || (type && !strcmp(type,"DynSharedI")) ) return this;
00133
00134 return m_pdo ? m_pdo->doGetObj(type) : NULL;
00135 }
00136
00137 virtual void docall doDestroy( ) {
00138 if( !m_ref_cnt )
00139 ::delete this;
00140 else
00141 SetError("doDestroy on non-zero refcounted object", DOERR_DYNSHARED_DESTROY_ON_NON_ZERO_REF );
00142 }
00143
00144 virtual int docall doAddRef( ) {
00145 return AtomicIncrement(&m_ref_cnt);
00146 }
00147
00148 virtual int docall doRelease( ) {
00149 int cnt = AtomicDecrement(&m_ref_cnt);
00150 if( !cnt ){
00151
00152 if(m_pdo) m_pdo->doDestroy( );
00153 ::delete this;
00154 }
00155 return cnt;
00156 }
00157
00158 template<class U, int M, int N>
00159 friend struct DoCaster;
00160
00161 protected:
00162 DynObj *m_pdo;
00163 int m_ref_cnt;
00164 };
00165
00166
00167
00168
00169 #ifdef DO_IMPLEMENT_DODYNSHARED
00170
00171
00172
00173 #if DO_USE_DYNSHARED==1
00174 DynObjType g_do_vtype_DynSharedC("DynSharedC","DynSharedI",DYNSHAREDC_TYPE_ID,0,sizeof(DynSharedC),NULL,NULL,__FILE__);
00175 DynObjType* DynSharedC::doGetType( const DynI **pself ) const {
00176 if(pself) *pself=(const DynI*)(const void*)this;
00177 return &g_do_vtype_DynSharedC;
00178 }
00179 DynObjTypeI2R<RTDynShared,DynSharedI,false> g_do_vtype_RTDynShared("RTDynShared:DynSharedI",RTDYNSHARED_TYPE_ID,0,__FILE__);
00180 DynObjType* RTDynShared::doGetType( const DynI **pself ) const {
00181 if(pself) *pself=(const DynI*)(const void*)this;
00182 return &g_do_vtype_RTDynShared;
00183 }
00184 #endif
00185 #endif //DO_IMPLEMENT_...
00186
00187
00188 #endif // DO_USE_DYNSHARED==1
00189
00190 #endif // DO_DYN_SHARED_H
00191