# 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
This work is licensed under a Creative Commons Attribution-ShareAlike 2.5 License.
Last modified Sun Feb 12 12:59:52 2006