# 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         {
    00056             OGRE_SET_AUTO_SHARED_MUTEX_NULL
    00057         }
    00058
    00059         explicit SharedPtr(T* rep) : pRep(rep), pUseCount(new unsigned int(1))
    00060         {
    00061             OGRE_SET_AUTO_SHARED_MUTEX_NULL
    00062             OGRE_NEW_AUTO_SHARED_MUTEX
    00063         }
    00064         SharedPtr(const SharedPtr& r)
    00065             : pRep(0), pUseCount(0)
    00066         {
    00067             // lock & copy other mutex pointer
    00068
    00069             OGRE_SET_AUTO_SHARED_MUTEX_NULL
    00070             OGRE_MUTEX_CONDITIONAL(r.OGRE_AUTO_MUTEX_NAME)
    00071             {
    00072                 OGRE_LOCK_MUTEX(*r.OGRE_AUTO_MUTEX_NAME)
    00073                 OGRE_COPY_AUTO_SHARED_MUTEX(r.OGRE_AUTO_MUTEX_NAME)
    00074                 pRep = r.pRep;
    00075                 pUseCount = r.pUseCount;
    00076                 // Handle zero pointer gracefully to manage STL containers
    00077                 if(pUseCount)
    00078                 {
    00079                     ++(*pUseCount);
    00080                 }
    00081             }
    00082         }
    00083         SharedPtr& operator=(const SharedPtr& r) {
    00084             if (pRep == r.pRep)
    00085                 return *this;
    00086             release();
    00087             // lock & copy other mutex pointer
    00088             OGRE_MUTEX_CONDITIONAL(r.OGRE_AUTO_MUTEX_NAME)
    00089             {
    00090                 OGRE_LOCK_MUTEX(*r.OGRE_AUTO_MUTEX_NAME)
    00091                 OGRE_COPY_AUTO_SHARED_MUTEX(r.OGRE_AUTO_MUTEX_NAME)
    00092                 pRep = r.pRep;
    00093                 pUseCount = r.pUseCount;
    00094                 if (pUseCount)
    00095                 {
    00096                     ++(*pUseCount);
    00097                 }
    00098             }
    00099             return *this;
    00100         }
    00101         virtual ~SharedPtr() {
    00102             release();
    00103         }
    00104
    00105
    00106         inline T& operator*() const { assert(pRep); return *pRep; }
    00107         inline T* operator->() const { assert(pRep); return pRep; }
    00108         inline T* get() const { return pRep; }
    00109
    00114         void bind(T* rep) {
    00115             assert(!pRep && !pUseCount);
    00116             OGRE_NEW_AUTO_SHARED_MUTEX
    00117             OGRE_LOCK_AUTO_SHARED_MUTEX
    00118             pUseCount = new unsigned int(1);
    00119             pRep = rep;
    00120         }
    00121
    00122         inline bool unique() const { OGRE_LOCK_AUTO_SHARED_MUTEX assert(pUseCount); return *pUseCount == 1; }
    00123         inline unsigned int useCount() const { OGRE_LOCK_AUTO_SHARED_MUTEX assert(pUseCount); return *pUseCount; }
    00124         inline unsigned int* useCountPointer() const { return pUseCount; }
    00125
    00126         inline T* getPointer() const { return pRep; }
    00127
    00128         inline bool isNull(void) const { return pRep == 0; }
    00129
    00130         inline void setNull(void) {
    00131             if (pRep)
    00132             {
    00133                 // can't scope lock mutex before release incase deleted
    00134                 release();
    00135                 pRep = 0;
    00136                 pUseCount = 0;
    00137             }
    00138         }
    00139
    00140     protected:
    00141
    00142         inline void release(void)
    00143         {
    00144             bool destroyThis = false;
    00145
    00146             /* If the mutex is not initialized to a non-zero value, then
    00147                neither is pUseCount nor pRep.
    00148              */
    00149
    00150             OGRE_MUTEX_CONDITIONAL(OGRE_AUTO_MUTEX_NAME)
    00151             {
    00152                 // lock own mutex in limited scope (must unlock before destroy)
    00153                 OGRE_LOCK_AUTO_SHARED_MUTEX
    00154                 if (pUseCount)
    00155                 {
    00156                     if (--(*pUseCount) == 0)
    00157                     {
    00158                         destroyThis = true;
    00159                     }
    00160                 }
    00161             }
    00162             if (destroyThis)
    00163                 destroy();
    00164
    00165             OGRE_SET_AUTO_SHARED_MUTEX_NULL
    00166         }
    00167
    00168         virtual void destroy(void)
    00169         {
    00170             // IF YOU GET A CRASH HERE, YOU FORGOT TO FREE UP POINTERS
    00171             // BEFORE SHUTTING OGRE DOWN
    00172             // Use setNull() before shutdown or make sure your pointer goes
    00173             // out of scope before OGRE shuts down to avoid this.
    00174             delete pRep;
    00175             delete pUseCount;
    00176             OGRE_DELETE_AUTO_SHARED_MUTEX
    00177         }
    00178     };
    00179
    00180     template<class T, class U> inline bool operator==(SharedPtr<T> const& a, SharedPtr<U> const& b)
    00181     {
    00182         return a.get() == b.get();
    00183     }
    00184
    00185     template<class T, class U> inline bool operator!=(SharedPtr<T> const& a, SharedPtr<U> const& b)
    00186     {
    00187         return a.get() != b.get();
    00188     }
    00189 }
    00190
    00191
    00192
    00193 #endif

Copyright © 2000-2005 by The OGRE Team
This work is licensed under a Creative Commons Attribution-ShareAlike 2.5 License.
Last modified Sun Sep 17 15:39:12 2006