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

Copyright © 2000-2005 by The OGRE Team
This work is licensed under a Creative Commons Attribution-ShareAlike 2.5 License.
Last modified Thu Mar 6 09:46:26 2008