lugre_smartptr.h
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef LUGRE_SMARTPTR_H
00025 #define LUGRE_SMARTPTR_H
00026
00027 #include "lugre_prefix.h"
00028 #include <list>
00029 #include <assert.h>
00030
00031
00032 namespace Lugre {
00033
00034 class cListener;
00035 template<class _T> class cSmartPtr;
00036
00037 class cListenable { public:
00038 cListenable();
00039 virtual ~cListenable();
00040 void NotifyAllListeners (const size_t eventcode = 0,void* param = 0);
00041 void RegisterListener (cListener* pListener,void* userdata = 0);
00042 void UnRegisterListener (cListener* pListener,void* userdata = 0);
00043 int CountListeners () { return mlListener.size(); }
00044 int iUsageCounter;
00045 bool bNeedsCompacting;
00046
00047 private:
00048 std::list< std::pair< cSmartPtr< cListener > *,void* > > mlListener;
00049 };
00050
00052 class cISmartPtr { public:
00053 virtual void SmartPtr_TargetDestroyed () = 0;
00054 };
00055
00060 template<class _T> class cSmartPtr : public cListenable, public cISmartPtr { public:
00061 enum { kDefaultTargetDestroyedEventCode = 255 };
00062 size_t miTargetDestroyedEventCode;
00063
00064 cSmartPtr(_T* target=0,const size_t iTargetDestroyedEventCode=kDefaultTargetDestroyedEventCode)
00065 : miTargetDestroyedEventCode(iTargetDestroyedEventCode), target(target) { PROFILE
00066 if (target) target->RegisterSmartPtr(this);
00067 }
00068
00069 virtual ~cSmartPtr() { PROFILE
00070 if (target) target->UnRegisterSmartPtr(this);
00071 target = 0;
00072 }
00073 void SmartPtr_SetTarget (_T* newtarget) { PROFILE
00074 if (target) target->UnRegisterSmartPtr(this);
00075 target = newtarget;
00076 if (target) target->RegisterSmartPtr(this);
00077 }
00078 inline const cSmartPtr<_T>& operator = (cSmartPtr<_T> othersmartptr) { PROFILE SmartPtr_SetTarget(*othersmartptr); return *this; }
00079 inline const cSmartPtr<_T>& operator = (_T* newtarget) { PROFILE SmartPtr_SetTarget(newtarget); return *this; }
00080 inline _T* operator * () { return target; }
00081
00084 void SmartPtr_TargetDestroyed () { PROFILE
00085 NotifyAllListeners(miTargetDestroyedEventCode); target = 0;
00086 }
00087
00088 private:
00089 _T* target;
00090 };
00091
00093 class cSmartPointable : public cListenable { public:
00094
00095 enum { kDefaultDeathEventCode = 255 };
00096 size_t miDeathEventCode;
00097
00098 cSmartPointable(const size_t iDeathEventCode=kDefaultDeathEventCode) : miDeathEventCode(iDeathEventCode) {}
00099 virtual ~cSmartPointable() { PROFILE
00100 ReleaseAllSmartPtr();
00101 NotifyAllListeners(miDeathEventCode);
00102 }
00103 void ReleaseAllSmartPtr () { PROFILE
00104
00105 for (std::list<cISmartPtr*>::iterator itor = mlPtr.begin();itor != mlPtr.end();++itor) {
00106 if (*itor) (*itor)->SmartPtr_TargetDestroyed();
00107 }
00108 mlPtr.clear();
00109 }
00110 void RegisterSmartPtr (cISmartPtr* ptr) { PROFILE
00111 assert(ptr);
00112 mlPtr.push_back(ptr);
00113 }
00114 void UnRegisterSmartPtr (cISmartPtr* ptr) { PROFILE
00115 assert(ptr);
00116 for (std::list<cISmartPtr*>::iterator itor = mlPtr.begin();itor != mlPtr.end();++itor)
00117 if (*itor == ptr)
00118 *itor = 0;
00119
00120
00121
00122 }
00123 int CountSmartPtrs () { return mlPtr.size(); }
00124
00125
00126 private:
00127 std::list<cISmartPtr*> mlPtr;
00128 };
00129
00130 class cListener : public cSmartPointable { public:
00131 cListener() {}
00132 virtual ~cListener() {}
00133 virtual void Listener_Notify (cListenable* pTarget,const size_t eventcode = 0,void* param = 0,void* userdata = 0) = 0;
00134 };
00135
00136 };
00137
00138 #endif