Visualization Library

A lightweight C++ OpenGL middleware for 2D/3D graphics
[Home] [Tutorials] [All Classes] [Grouped Classes]

X:/dropbox/visualizationlibrary/src/vlCore/Object.hpp

Go to the documentation of this file.
00001 /**************************************************************************************/
00002 /*                                                                                    */
00003 /*  Visualization Library                                                             */
00004 /*  http://www.visualizationlibrary.org                                               */
00005 /*                                                                                    */
00006 /*  Copyright (c) 2005-2010, Michele Bosi                                             */
00007 /*  All rights reserved.                                                              */
00008 /*                                                                                    */
00009 /*  Redistribution and use in source and binary forms, with or without modification,  */
00010 /*  are permitted provided that the following conditions are met:                     */
00011 /*                                                                                    */
00012 /*  - Redistributions of source code must retain the above copyright notice, this     */
00013 /*  list of conditions and the following disclaimer.                                  */
00014 /*                                                                                    */
00015 /*  - Redistributions in binary form must reproduce the above copyright notice, this  */
00016 /*  list of conditions and the following disclaimer in the documentation and/or       */
00017 /*  other materials provided with the distribution.                                   */
00018 /*                                                                                    */
00019 /*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND   */
00020 /*  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED     */
00021 /*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE            */
00022 /*  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR  */
00023 /*  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    */
00024 /*  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;      */
00025 /*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON    */
00026 /*  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT           */
00027 /*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS     */
00028 /*  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                      */
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   // Object
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       // user data
00068       #if VL_OBJECT_USER_DATA
00069         mUserData = NULL;
00070       #endif
00071       #if VL_DEBUG_LIVING_OBJECTS
00072         debug_living_objects()->insert(this);
00073         // mDebug_LivingObjects.insert(this);
00074       #endif
00075     }
00076 
00078     Object(const Object& other)
00079     {
00080       // copy the name, the ref count mutex and the user data.
00081       mObjectName = other.mObjectName;
00082       mRefCountMutex = other.mRefCountMutex;
00083       #if VL_OBJECT_USER_DATA
00084         mUserData = other.mUserData;
00085       #endif
00086 
00087       // mReferenceCount and mAutomaticDelete are not copiable.
00088       mReferenceCount  = 0;
00089       mAutomaticDelete = true;
00090 
00091       // debug living object
00092       #if VL_DEBUG_LIVING_OBJECTS
00093         debug_living_objects()->insert(this);
00094       #endif
00095     }
00096 
00098     Object& operator=(const Object& other) 
00099     { 
00100       // copy the name, the ref count mutex and the user data.
00101       mObjectName = other.mObjectName;
00102       mRefCountMutex = other.mRefCountMutex;
00103       #if VL_OBJECT_USER_DATA
00104         mUserData = other.mUserData;
00105       #endif
00106 
00107       // mReferenceCount and mAutomaticDelete are not copiable.
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       // Lock mutex
00138       if (refCountMutex())
00139         const_cast<IMutex*>(refCountMutex())->lock();
00140 
00141       ++mReferenceCount;
00142       
00143       // Unlock mutex
00144       if(refCountMutex())
00145         const_cast<IMutex*>(refCountMutex())->unlock();
00146     }
00147 
00149     void decReference()
00150     {
00151       // Save local copy in case of deletion.
00152       IMutex* mutex = mRefCountMutex;
00153 
00154       // Lock mutex.
00155       if (mutex)
00156         mutex->lock();
00157 
00158       VL_CHECK(mReferenceCount)
00159       --mReferenceCount;
00160       if (mReferenceCount == 0 && automaticDelete())
00161         delete this;
00162 
00163       // Unlock mutex.
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   // debugging facilities
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   // ref
00215   //------------------------------------------------------------------------------
00221   template<class T>
00222   class ref
00223   {
00224   public:
00225     // 'const' is required as the copy constructor must have this signature.
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     // 'const' is required because operator= must have this signature.
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     // 'const' is required because operator= must have this signature.
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     // 'const' is required because operator= must have this signature.
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   // interaction with the other types
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

Visualization Library 2011.09.1160 Reference Documentation
Copyright 2005-2011 Michele Bosi. All rights reserved.
Updated on Thu May 2 2013 13:40:30.
Permission is granted to use this page to write and publish articles regarding Visualization Library.