source: OGRE/trunk/ogrenew/OgreMain/include/OgreSharedPtr.h @ 692

Revision 692, 5.2 KB checked in by mattausch, 19 years ago (diff)

adding ogre 1.2 and dependencies

RevLine 
[692]1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4    (Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.ogre3d.org/
6
7Copyright (c) 2000-2005 The OGRE Team
8Also see acknowledgements in Readme.html
9
10This program is free software; you can redistribute it and/or modify it under
11the terms of the GNU Lesser General Public License as published by the Free Software
12Foundation; either version 2 of the License, or (at your option) any later
13version.
14
15This program is distributed in the hope that it will be useful, but WITHOUT
16ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
18
19You should have received a copy of the GNU Lesser General Public License along with
20this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21Place - Suite 330, Boston, MA 02111-1307, USA, or go to
22http://www.gnu.org/copyleft/lesser.txt.
23-----------------------------------------------------------------------------
24*/
25#ifndef __SharedPtr_H__
26#define __SharedPtr_H__
27
28#include "OgrePrerequisites.h"
29
30namespace Ogre {
31
32        /** Reference-counted shared pointer, used for objects where implicit destruction is
33        required.
34    @remarks
35        This is a standard shared pointer implementation which uses a reference
36        count to work out when to delete the object. OGRE does not use this class
37        very often, because it is usually more efficient to make the destruction
38        of objects more intentional (in blocks, say). However in some cases you
39        really cannot tell how many people are using an object, and this approach is
40        worthwhile (e.g. ControllerValue)
41        @par
42                If OGRE_THREAD_SUPPORT is defined to be 1, use of this class is thread-safe.
43    */
44    template<class T> class SharedPtr {
45        protected:
46                T* pRep;
47                unsigned int* pUseCount;
48        public:
49                OGRE_AUTO_SHARED_MUTEX // public to allow external locking
50                /** Constructor, does not initialise the SharedPtr.
51                        @remarks
52                                <b>Dangerous!</b> You have to call bind() before using the SharedPtr.
53                */
54                SharedPtr() : pRep(0), pUseCount(0) {}
55                explicit SharedPtr(T* rep) : pRep(rep), pUseCount(new unsigned int(1))
56                {
57                        OGRE_NEW_AUTO_SHARED_MUTEX
58                }
59                SharedPtr(const SharedPtr& r)
60                {
61                        // lock & copy other mutex pointer
62                        OGRE_LOCK_MUTEX(*r.OGRE_AUTO_MUTEX_NAME)
63                        OGRE_COPY_AUTO_SHARED_MUTEX(r.OGRE_AUTO_MUTEX_NAME)
64                        pRep = r.pRep;
65                        pUseCount = r.pUseCount;
66                        // Handle zero pointer gracefully to manage STL containers
67                        if(pUseCount)
68                        {
69                                ++(*pUseCount);
70                        }
71                }
72                SharedPtr& operator=(const SharedPtr& r) {
73                        if (pRep == r.pRep)
74                                return *this;
75                        release();
76                        // lock & copy other mutex pointer
77                        OGRE_LOCK_MUTEX(*r.OGRE_AUTO_MUTEX_NAME)
78                        OGRE_COPY_AUTO_SHARED_MUTEX(r.OGRE_AUTO_MUTEX_NAME)
79                        pRep = r.pRep;
80                        pUseCount = r.pUseCount;
81                        if (pUseCount)
82                        {
83                                ++(*pUseCount);
84                        }
85                        return *this;
86                }
87                virtual ~SharedPtr() {
88            release();
89                }
90
91
92                inline T& operator*() const { assert(pRep); return *pRep; }
93                inline T* operator->() const { assert(pRep); return pRep; }
94                inline T* get() const { return pRep; }
95
96                /** Binds rep to the SharedPtr.
97                        @remarks
98                                Assumes that the SharedPtr is uninitialised!
99                */
100                void bind(T* rep) {
101                        assert(!pRep && !pUseCount);
102                        OGRE_NEW_AUTO_SHARED_MUTEX
103                        OGRE_LOCK_AUTO_SHARED_MUTEX
104                        pUseCount = new unsigned int(1);
105                        pRep = rep;
106                }
107
108                inline bool unique() const { assert(pUseCount); OGRE_LOCK_AUTO_SHARED_MUTEX return *pUseCount == 1; }
109                inline unsigned int useCount() const { assert(pUseCount); OGRE_LOCK_AUTO_SHARED_MUTEX return *pUseCount; }
110                inline unsigned int* useCountPointer() const { return pUseCount; }
111
112                inline T* getPointer() const { return pRep; }
113
114                inline bool isNull(void) const { return pRep == 0; }
115
116        inline void setNull(void) {
117                        if (pRep)
118                        {
119                                // can't scope lock mutex before release incase deleted
120                                release();
121                                pRep = 0;
122                                pUseCount = 0;
123                                OGRE_COPY_AUTO_SHARED_MUTEX(0)
124                        }
125        }
126
127    protected:
128
129        inline void release(void) {
130                        bool destroyThis = false;
131                        {
132                                // lock own mutex in limited scope (must unlock before destroy)
133                                OGRE_LOCK_AUTO_SHARED_MUTEX
134                                if (pUseCount)
135                                {
136                                        if (--(*pUseCount) == 0)
137                                        {
138                                                destroyThis = true;
139                        }
140                                }
141            }
142                        if (destroyThis)
143                                destroy();
144        }
145
146        virtual void destroy(void)
147        {
148            // IF YOU GET A CRASH HERE, YOU FORGOT TO FREE UP POINTERS
149            // BEFORE SHUTTING OGRE DOWN
150            // Use setNull() before shutdown or make sure your pointer goes
151            // out of scope before OGRE shuts down to avoid this.
152            delete pRep;
153            delete pUseCount;
154                        OGRE_DELETE_AUTO_SHARED_MUTEX
155        }
156        };
157
158        template<class T, class U> inline bool operator==(SharedPtr<T> const& a, SharedPtr<U> const& b)
159        {
160                return a.get() == b.get();
161        }
162
163        template<class T, class U> inline bool operator!=(SharedPtr<T> const& a, SharedPtr<U> const& b)
164        {
165                return a.get() != b.get();
166        }
167
168}
169
170#endif
Note: See TracBrowser for help on using the repository browser.