00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #ifndef _cvcl__include__smartcdo_h_
00031 #define _cvcl__include__smartcdo_h_
00032
00033 #include "cdo.h"
00034
00035 namespace CVCL {
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 template <class T>
00060 class SmartCDO {
00061
00062 template <class U>
00063 class RefCDO {
00064 friend class SmartCDO;
00065 int d_refCount;
00066 CDO<U> d_cdo;
00067 bool d_delay;
00068
00069 class RefNotifyObj : public ContextNotifyObj {
00070 friend class RefCDO<U>;
00071 RefCDO<U>* d_ref;
00072
00073 RefNotifyObj(RefCDO<U>* ref, Context* context)
00074 : ContextNotifyObj(context), d_ref(ref) { }
00075 void notifyPre() { d_ref->d_delay = true; }
00076 void notify() {
00077 d_ref->d_delay = false;
00078 d_ref->kill();
00079 }
00080 };
00081
00082 RefNotifyObj* d_notifyObj;
00083
00084 friend class RefNotifyObj;
00085
00086 RefCDO(Context* context): d_refCount(0), d_cdo(context), d_delay(false),
00087 d_notifyObj(new RefNotifyObj(this, context)) {}
00088
00089 RefCDO(Context* context, const U& cdo, int scope = -1)
00090 : d_refCount(0), d_cdo(context, cdo, scope), d_delay(false),
00091 d_notifyObj(new RefNotifyObj(this, context)) {}
00092
00093 ~RefCDO() { delete d_notifyObj; }
00094
00095 void kill() { if(d_refCount==0 && !d_delay) delete this; }
00096 };
00097
00098 RefCDO<T>* d_data;
00099
00100 public:
00101
00102 bool isNull() const { return (d_data==NULL); }
00103
00104 SmartCDO(): d_data(NULL) { }
00105
00106 SmartCDO(Context* context)
00107 { d_data = new RefCDO<T>(context); d_data->d_refCount++; }
00108
00109 SmartCDO(Context* context, const T& data, int scope = -1)
00110 { d_data = new RefCDO<T>(context, data, scope); d_data->d_refCount++; }
00111
00112 ~SmartCDO()
00113 { if (isNull()) return;
00114 if (--d_data->d_refCount == 0) d_data->kill(); }
00115
00116 SmartCDO(const SmartCDO<T>& cdo) : d_data(cdo.d_data)
00117 { if (!isNull()) d_data->d_refCount++; }
00118
00119 SmartCDO<T>& operator=(const SmartCDO<T>& cdo)
00120 {
00121 if (this == &cdo) return *this;
00122 if (!isNull() && --(d_data->d_refCount)) d_data->kill();
00123 d_data = cdo.d_data;
00124 if (!isNull()) ++(d_data->d_refCount);
00125 return *this;
00126 }
00127
00128 void set(const T& data, int scope=-1) const {
00129 DebugAssert(!isNull(), "SmartCDO::set: we are Null");
00130 d_data->d_cdo.set(data, scope);
00131 }
00132 const T& get() const {
00133 DebugAssert(!isNull(), "SmartCDO::get: we are Null");
00134 return d_data->d_cdo.get();
00135 }
00136 operator T() const { return get(); }
00137 const SmartCDO<T>& operator=(const T& data) const {set(data); return *this;}
00138 };
00139
00140 }
00141
00142 #endif