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
00025
00026
00027
00028
00029
00030
00031
00032 #ifndef Object_INCLUDE_ONCE
00033 #define Object_INCLUDE_ONCE
00034
00035 #include <vlCore/checks.hpp>
00036 #include <vlCore/IMutex.hpp>
00037 #include <vlCore/TypeInfo.hpp>
00038 #include <string>
00039
00040 #if VL_DEBUG_LIVING_OBJECTS
00041 #include <set>
00042 #endif
00043
00044 namespace vl
00045 {
00046 template<class T> class ref;
00047
00048
00049
00050
00055 class VLCORE_EXPORT Object
00056 {
00057 VL_INSTRUMENT_BASE_CLASS(vl::Object)
00058
00059 public:
00061 Object()
00062 {
00063 VL_DEBUG_SET_OBJECT_NAME()
00064 mRefCountMutex = NULL;
00065 mReferenceCount = 0;
00066 mAutomaticDelete = true;
00067
00068 #if VL_OBJECT_USER_DATA
00069 mUserData = NULL;
00070 #endif
00071 #if VL_DEBUG_LIVING_OBJECTS
00072 debug_living_objects()->insert(this);
00073
00074 #endif
00075 }
00076
00078 Object(const Object& other)
00079 {
00080
00081 mObjectName = other.mObjectName;
00082 mRefCountMutex = other.mRefCountMutex;
00083 #if VL_OBJECT_USER_DATA
00084 mUserData = other.mUserData;
00085 #endif
00086
00087
00088 mReferenceCount = 0;
00089 mAutomaticDelete = true;
00090
00091
00092 #if VL_DEBUG_LIVING_OBJECTS
00093 debug_living_objects()->insert(this);
00094 #endif
00095 }
00096
00098 Object& operator=(const Object& other)
00099 {
00100
00101 mObjectName = other.mObjectName;
00102 mRefCountMutex = other.mRefCountMutex;
00103 #if VL_OBJECT_USER_DATA
00104 mUserData = other.mUserData;
00105 #endif
00106
00107
00108
00109
00110 return *this;
00111 }
00112
00114 const std::string& objectName() const { return mObjectName; }
00115
00117 void setObjectName(const char* name) { mObjectName = name; }
00118
00120 void setRefCountMutex(IMutex* mutex) { mRefCountMutex = mutex; }
00121
00123 IMutex* refCountMutex() { return mRefCountMutex; }
00124
00126 const IMutex* refCountMutex() const { return mRefCountMutex; }
00127
00129 int referenceCount() const
00130 {
00131 return mReferenceCount;
00132 }
00133
00135 void incReference() const
00136 {
00137
00138 if (refCountMutex())
00139 const_cast<IMutex*>(refCountMutex())->lock();
00140
00141 ++mReferenceCount;
00142
00143
00144 if(refCountMutex())
00145 const_cast<IMutex*>(refCountMutex())->unlock();
00146 }
00147
00149 void decReference()
00150 {
00151
00152 IMutex* mutex = mRefCountMutex;
00153
00154
00155 if (mutex)
00156 mutex->lock();
00157
00158 VL_CHECK(mReferenceCount)
00159 --mReferenceCount;
00160 if (mReferenceCount == 0 && automaticDelete())
00161 delete this;
00162
00163
00164 if (mutex)
00165 mutex->unlock();
00166 }
00167
00169 void setAutomaticDelete(bool autodel_on) { mAutomaticDelete = autodel_on; }
00170
00172 bool automaticDelete() const { return mAutomaticDelete; }
00173
00175 template<class T>
00176 T* as() { return cast<T>(this); }
00177
00179 template<class T>
00180 const T* as() const { return cast<const T>(this); }
00181
00182 #if VL_OBJECT_USER_DATA
00183 public:
00184 void* userData() { return mUserData; }
00185 const void* userData() const { return mUserData; }
00186 void setUserData(void* user_data) { mUserData = user_data; }
00187
00188 private:
00189 void* mUserData;
00190 #endif
00191
00192 protected:
00193 virtual ~Object();
00194 std::string mObjectName;
00195
00196 IMutex* mRefCountMutex;
00197 mutable int mReferenceCount;
00198 bool mAutomaticDelete;
00199
00200
00201
00202 public:
00203 #if VL_DEBUG_LIVING_OBJECTS
00204 static std::set< Object* >* mDebug_LivingObjects;
00205 static std::set< Object* >* debug_living_objects()
00206 {
00207 if (!mDebug_LivingObjects)
00208 mDebug_LivingObjects = new std::set< Object* >;
00209 return mDebug_LivingObjects;
00210 }
00211 #endif
00212 };
00213
00214
00215
00221 template<class T>
00222 class ref
00223 {
00224 public:
00225
00226 ref(const ref& other)
00227 {
00228 mObject = NULL;
00229 *this = other;
00230 }
00231
00232 ref(const T* object=NULL)
00233 {
00234 mObject = const_cast<T*>(object);
00235 if (mObject)
00236 mObject->incReference();
00237 }
00238
00239 template<class T2> ref(const ref<T2>& other)
00240 {
00241 mObject = NULL;
00242 *this = other;
00243 }
00244
00245 ~ref()
00246 {
00247 if (mObject)
00248 mObject->decReference();
00249 mObject = NULL;
00250 }
00251
00252
00253 ref& operator=(const ref& other)
00254 {
00255 if (other)
00256 other->incReference();
00257 if (mObject)
00258 mObject->decReference();
00259 mObject = const_cast<T*>(other.get());
00260 return *this;
00261 }
00262
00263
00264 ref& operator=(const T* other)
00265 {
00266 if (other)
00267 other->incReference();
00268 if (mObject)
00269 mObject->decReference();
00270 mObject = const_cast<T*>(other);
00271 return *this;
00272 }
00273
00274
00275 template<class T2> ref& operator=(const ref<T2>& other)
00276 {
00277 if (other)
00278 other->incReference();
00279 if (mObject)
00280 mObject->decReference();
00281 mObject = const_cast<T2*>(other.get());
00282 return *this;
00283 }
00284
00285 void swap(ref& other)
00286 {
00287 T* tmp = other.mObject;
00288 other = mObject;
00289 mObject = tmp;
00290 }
00291
00293 T* get_writable() const { return mObject; }
00294
00295 const T* get() const { return mObject; }
00296 const T* operator->() const { VL_CHECK(mObject); return mObject; }
00297 const T& operator*() const { VL_CHECK(mObject); return *mObject; }
00298
00299 T* get() { return mObject; }
00300 T* operator->() { VL_CHECK(mObject); return mObject; }
00301 T& operator*() { VL_CHECK(mObject); return *mObject; }
00302
00303 bool operator<(const ref& other) const { return mObject < other.mObject; }
00304
00305 operator bool() const { return mObject != NULL; }
00306
00307 protected:
00308 T* mObject;
00309 };
00310
00311 template<class T1, class T2> inline bool operator==(const ref<T1> & o1, const ref<T2> & o2) { return o1.get() == o2.get(); }
00312 template<class T1, class T2> inline bool operator!=(const ref<T1> & o1, const ref<T2> & o2) { return o1.get() != o2.get(); }
00313 template<class T1, class T2> inline bool operator==(const ref<T1> & o1, T2 * o2) { return o1.get() == o2; }
00314 template<class T1, class T2> inline bool operator!=(const ref<T1> & o1, T2 * o2) { return o1.get() != o2; }
00315 template<class T1, class T2> inline bool operator==(T1 * o1, const ref<T2> & o2) { return o1 == o2.get(); }
00316 template<class T1, class T2> inline bool operator!=(T1 * o1, const ref<T2> & o2) { return o1 != o2.get(); }
00317 }
00318
00319 #endif