Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

OgreSharedPtr.h

Go to the documentation of this file.
00001 /*
00002 -----------------------------------------------------------------------------
00003 This source file is part of OGRE
00004     (Object-oriented Graphics Rendering Engine)
00005 For the latest info, see http://www.ogre3d.org/
00006 
00007 Copyright (c) 2000-2006 Torus Knot Software Ltd
00008 Also see acknowledgements in Readme.html
00009 
00010 This program is free software; you can redistribute it and/or modify it under
00011 the terms of the GNU Lesser General Public License as published by the Free Software
00012 Foundation; either version 2 of the License, or (at your option) any later
00013 version.
00014 
00015 This program is distributed in the hope that it will be useful, but WITHOUT
00016 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00017 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
00018 
00019 You should have received a copy of the GNU Lesser General Public License along with
00020 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
00021 Place - Suite 330, Boston, MA 02111-1307, USA, or go to
00022 http://www.gnu.org/copyleft/lesser.txt.
00023 
00024 You may alternatively use this source under the terms of a specific version of
00025 the OGRE Unrestricted License provided you have obtained such a license from
00026 Torus Knot Software Ltd.
00027 -----------------------------------------------------------------------------
00028 */
00029 #ifndef __SharedPtr_H__
00030 #define __SharedPtr_H__
00031 
00032 #include "OgrePrerequisites.h"
00033 
00034 namespace Ogre {
00035 
00048     template<class T> class SharedPtr {
00049     protected:
00050         T* pRep;
00051         unsigned int* pUseCount;
00052     public:
00053         OGRE_AUTO_SHARED_MUTEX // public to allow external locking
00058         SharedPtr() : pRep(0), pUseCount(0)
00059         {
00060             OGRE_SET_AUTO_SHARED_MUTEX_NULL
00061         }
00062 
00063         template< class Y>
00064         explicit SharedPtr(Y* rep) : pRep(rep), pUseCount(new unsigned int(1))
00065         {
00066             OGRE_SET_AUTO_SHARED_MUTEX_NULL
00067             OGRE_NEW_AUTO_SHARED_MUTEX
00068         }
00069         SharedPtr(const SharedPtr& r)
00070             : pRep(0), pUseCount(0)
00071         {
00072             // lock & copy other mutex pointer
00073             
00074             OGRE_SET_AUTO_SHARED_MUTEX_NULL
00075             OGRE_MUTEX_CONDITIONAL(r.OGRE_AUTO_MUTEX_NAME)
00076             {
00077                 OGRE_LOCK_MUTEX(*r.OGRE_AUTO_MUTEX_NAME)
00078                 OGRE_COPY_AUTO_SHARED_MUTEX(r.OGRE_AUTO_MUTEX_NAME)
00079                 pRep = r.pRep;
00080                 pUseCount = r.pUseCount; 
00081                 // Handle zero pointer gracefully to manage STL containers
00082                 if(pUseCount)
00083                 {
00084                     ++(*pUseCount); 
00085                 }
00086             }
00087         }
00088         SharedPtr& operator=(const SharedPtr& r) {
00089             if (pRep == r.pRep)
00090                 return *this;
00091             // Swap current data into a local copy
00092             // this ensures we deal with rhs and this being dependent
00093             SharedPtr<T> tmp(r);
00094             swap(tmp);
00095             return *this;
00096         }
00097         
00098         template< class Y>
00099         SharedPtr(const SharedPtr<Y>& r)
00100             : pRep(0), pUseCount(0)
00101         {
00102             // lock & copy other mutex pointer
00103 
00104             OGRE_SET_AUTO_SHARED_MUTEX_NULL
00105             OGRE_MUTEX_CONDITIONAL(r.OGRE_AUTO_MUTEX_NAME)
00106             {
00107                 OGRE_LOCK_MUTEX(*r.OGRE_AUTO_MUTEX_NAME)
00108                 OGRE_COPY_AUTO_SHARED_MUTEX(r.OGRE_AUTO_MUTEX_NAME)
00109                 pRep = r.getPointer();
00110                 pUseCount = r.useCountPointer();
00111                 // Handle zero pointer gracefully to manage STL containers
00112                 if(pUseCount)
00113                 {
00114                     ++(*pUseCount);
00115                 }
00116             }
00117         }
00118         template< class Y>
00119         SharedPtr& operator=(const SharedPtr<Y>& r) {
00120             if (pRep == r.pRep)
00121                 return *this;
00122             // Swap current data into a local copy
00123             // this ensures we deal with rhs and this being dependent
00124             SharedPtr<T> tmp(r);
00125             swap(tmp);
00126             return *this;
00127         }
00128         virtual ~SharedPtr() {
00129             release();
00130         }
00131 
00132 
00133         inline T& operator*() const { assert(pRep); return *pRep; }
00134         inline T* operator->() const { assert(pRep); return pRep; }
00135         inline T* get() const { return pRep; }
00136 
00141         void bind(T* rep) {
00142             assert(!pRep && !pUseCount);
00143             OGRE_NEW_AUTO_SHARED_MUTEX
00144             OGRE_LOCK_AUTO_SHARED_MUTEX
00145             pUseCount = new unsigned int(1);
00146             pRep = rep;
00147         }
00148 
00149         inline bool unique() const { OGRE_LOCK_AUTO_SHARED_MUTEX assert(pUseCount); return *pUseCount == 1; }
00150         inline unsigned int useCount() const { OGRE_LOCK_AUTO_SHARED_MUTEX assert(pUseCount); return *pUseCount; }
00151         inline unsigned int* useCountPointer() const { return pUseCount; }
00152 
00153         inline T* getPointer() const { return pRep; }
00154 
00155         inline bool isNull(void) const { return pRep == 0; }
00156 
00157         inline void setNull(void) { 
00158             if (pRep)
00159             {
00160                 // can't scope lock mutex before release incase deleted
00161                 release();
00162                 pRep = 0;
00163                 pUseCount = 0;
00164             }
00165         }
00166 
00167     protected:
00168 
00169         inline void release(void)
00170         {
00171             bool destroyThis = false;
00172 
00173             /* If the mutex is not initialized to a non-zero value, then
00174                neither is pUseCount nor pRep.
00175              */
00176 
00177             OGRE_MUTEX_CONDITIONAL(OGRE_AUTO_MUTEX_NAME)
00178             {
00179                 // lock own mutex in limited scope (must unlock before destroy)
00180                 OGRE_LOCK_AUTO_SHARED_MUTEX
00181                 if (pUseCount)
00182                 {
00183                     if (--(*pUseCount) == 0) 
00184                     {
00185                         destroyThis = true;
00186                     }
00187                 }
00188             }
00189             if (destroyThis)
00190                 destroy();
00191 
00192             OGRE_SET_AUTO_SHARED_MUTEX_NULL
00193         }
00194 
00195         virtual void destroy(void)
00196         {
00197             // IF YOU GET A CRASH HERE, YOU FORGOT TO FREE UP POINTERS
00198             // BEFORE SHUTTING OGRE DOWN
00199             // Use setNull() before shutdown or make sure your pointer goes
00200             // out of scope before OGRE shuts down to avoid this.
00201             delete pRep;
00202             delete pUseCount;
00203             OGRE_DELETE_AUTO_SHARED_MUTEX
00204         }
00205 
00206         virtual void swap(SharedPtr<T> &other) 
00207         {
00208             std::swap(pRep, other.pRep);
00209             std::swap(pUseCount, other.pUseCount);
00210 #if OGRE_THREAD_SUPPORT
00211             std::swap(OGRE_AUTO_MUTEX_NAME, other.OGRE_AUTO_MUTEX_NAME);
00212 #endif
00213         }
00214     };
00215 
00216     template<class T, class U> inline bool operator==(SharedPtr<T> const& a, SharedPtr<U> const& b)
00217     {
00218         return a.get() == b.get();
00219     }
00220 
00221     template<class T, class U> inline bool operator!=(SharedPtr<T> const& a, SharedPtr<U> const& b)
00222     {
00223         return a.get() != b.get();
00224     }
00225 }
00226 
00227 
00228 
00229 #endif

Copyright © 2000-2005 by The OGRE Team
Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 2.5 License.
Last modified Mon Aug 20 13:50:48 2007