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
This work is licensed under a Creative Commons Attribution-ShareAlike 2.5 License.
Last modified Sun Sep 30 10:50:57 2007