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