Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | 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-2005 The OGRE Team
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 */
00025 #ifndef __SharedPtr_H__
00026 #define __SharedPtr_H__
00027 
00028 #include "OgrePrerequisites.h"
00029 
00030 namespace Ogre {
00031 
00044     template<class T> class SharedPtr {
00045     protected:
00046         T* pRep;
00047         unsigned int* pUseCount;
00048     public:
00049         OGRE_AUTO_SHARED_MUTEX // public to allow external locking
00054         SharedPtr() : pRep(0), pUseCount(0) {}
00055         explicit SharedPtr(T* rep) : pRep(rep), pUseCount(new unsigned int(1)) 
00056         {
00057             OGRE_NEW_AUTO_SHARED_MUTEX
00058         }
00059         SharedPtr(const SharedPtr& r) 
00060         {
00061             // lock & copy other mutex pointer
00062             OGRE_LOCK_MUTEX(*r.OGRE_AUTO_MUTEX_NAME)
00063             OGRE_COPY_AUTO_SHARED_MUTEX(r.OGRE_AUTO_MUTEX_NAME)
00064             pRep = r.pRep;
00065             pUseCount = r.pUseCount; 
00066             // Handle zero pointer gracefully to manage STL containers
00067             if(pUseCount)
00068             {
00069                 ++(*pUseCount); 
00070             }
00071         }
00072         SharedPtr& operator=(const SharedPtr& r) {
00073             if (pRep == r.pRep)
00074                 return *this;
00075             release();
00076             // lock & copy other mutex pointer
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             if (pUseCount)
00082             {
00083                 ++(*pUseCount);
00084             }
00085             return *this;
00086         }
00087         virtual ~SharedPtr() {
00088             release();
00089         }
00090 
00091 
00092         inline T& operator*() const { assert(pRep); return *pRep; }
00093         inline T* operator->() const { assert(pRep); return pRep; }
00094         inline T* get() const { return pRep; }
00095 
00100         void bind(T* rep) {
00101             assert(!pRep && !pUseCount);
00102             OGRE_NEW_AUTO_SHARED_MUTEX
00103             OGRE_LOCK_AUTO_SHARED_MUTEX
00104             pUseCount = new unsigned int(1);
00105             pRep = rep;
00106         }
00107 
00108         inline bool unique() const { assert(pUseCount); OGRE_LOCK_AUTO_SHARED_MUTEX return *pUseCount == 1; }
00109         inline unsigned int useCount() const { assert(pUseCount); OGRE_LOCK_AUTO_SHARED_MUTEX return *pUseCount; }
00110         inline unsigned int* useCountPointer() const { return pUseCount; }
00111 
00112         inline T* getPointer() const { return pRep; }
00113 
00114         inline bool isNull(void) const { return pRep == 0; }
00115 
00116         inline void setNull(void) { 
00117             if (pRep)
00118             {
00119                 // can't scope lock mutex before release incase deleted
00120                 release();
00121                 pRep = 0;
00122                 pUseCount = 0;
00123                 OGRE_COPY_AUTO_SHARED_MUTEX(0)
00124             }
00125         }
00126 
00127     protected:
00128 
00129         inline void release(void) {
00130             bool destroyThis = false;
00131             {
00132                 // lock own mutex in limited scope (must unlock before destroy)
00133                 OGRE_LOCK_AUTO_SHARED_MUTEX
00134                 if (pUseCount)
00135                 {
00136                     if (--(*pUseCount) == 0) 
00137                     {
00138                         destroyThis = true;
00139                     }
00140                 }
00141             }
00142             if (destroyThis)
00143                 destroy();
00144         }
00145 
00146         virtual void destroy(void)
00147         {
00148             // IF YOU GET A CRASH HERE, YOU FORGOT TO FREE UP POINTERS
00149             // BEFORE SHUTTING OGRE DOWN
00150             // Use setNull() before shutdown or make sure your pointer goes
00151             // out of scope before OGRE shuts down to avoid this.
00152             delete pRep;
00153             delete pUseCount;
00154             OGRE_DELETE_AUTO_SHARED_MUTEX
00155         }
00156     };
00157 
00158     template<class T, class U> inline bool operator==(SharedPtr<T> const& a, SharedPtr<U> const& b)
00159     {
00160         return a.get() == b.get();
00161     }
00162 
00163     template<class T, class U> inline bool operator!=(SharedPtr<T> const& a, SharedPtr<U> const& b)
00164     {
00165         return a.get() != b.get();
00166     }
00167 
00168 }
00169 
00170 #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 Sun Feb 12 12:59:52 2006