Line data Source code
1 : // Copyright (C) 2002-2012 Nikolaus Gebhardt
2 : // This file is part of the "Irrlicht Engine".
3 : // For conditions of distribution and use, see copyright notice in irrlicht.h
4 :
5 : #ifndef __I_IREFERENCE_COUNTED_H_INCLUDED__
6 : #define __I_IREFERENCE_COUNTED_H_INCLUDED__
7 :
8 : #include "irrTypes.h"
9 :
10 : namespace irr
11 : {
12 :
13 : //! Base class of most objects of the Irrlicht Engine.
14 : /** This class provides reference counting through the methods grab() and drop().
15 : It also is able to store a debug string for every instance of an object.
16 : Most objects of the Irrlicht
17 : Engine are derived from IReferenceCounted, and so they are reference counted.
18 :
19 : When you create an object in the Irrlicht engine, calling a method
20 : which starts with 'create', an object is created, and you get a pointer
21 : to the new object. If you no longer need the object, you have
22 : to call drop(). This will destroy the object, if grab() was not called
23 : in another part of you program, because this part still needs the object.
24 : Note, that you only need to call drop() to the object, if you created it,
25 : and the method had a 'create' in it.
26 :
27 : A simple example:
28 :
29 : If you want to create a texture, you may want to call an imaginable method
30 : IDriver::createTexture. You call
31 : ITexture* texture = driver->createTexture(dimension2d<u32>(128, 128));
32 : If you no longer need the texture, call texture->drop().
33 :
34 : If you want to load a texture, you may want to call imaginable method
35 : IDriver::loadTexture. You do this like
36 : ITexture* texture = driver->loadTexture("example.jpg");
37 : You will not have to drop the pointer to the loaded texture, because
38 : the name of the method does not start with 'create'. The texture
39 : is stored somewhere by the driver.
40 : */
41 : class IReferenceCounted
42 : {
43 : public:
44 :
45 : //! Constructor.
46 618129 : IReferenceCounted()
47 618129 : : DebugName(0), ReferenceCounter(1)
48 : {
49 618129 : }
50 :
51 : //! Destructor.
52 623337 : virtual ~IReferenceCounted()
53 623337 : {
54 623337 : }
55 :
56 : //! Grabs the object. Increments the reference counter by one.
57 : /** Someone who calls grab() to an object, should later also
58 : call drop() to it. If an object never gets as much drop() as
59 : grab() calls, it will never be destroyed. The
60 : IReferenceCounted class provides a basic reference counting
61 : mechanism with its methods grab() and drop(). Most objects of
62 : the Irrlicht Engine are derived from IReferenceCounted, and so
63 : they are reference counted.
64 :
65 : When you create an object in the Irrlicht engine, calling a
66 : method which starts with 'create', an object is created, and
67 : you get a pointer to the new object. If you no longer need the
68 : object, you have to call drop(). This will destroy the object,
69 : if grab() was not called in another part of you program,
70 : because this part still needs the object. Note, that you only
71 : need to call drop() to the object, if you created it, and the
72 : method had a 'create' in it.
73 :
74 : A simple example:
75 :
76 : If you want to create a texture, you may want to call an
77 : imaginable method IDriver::createTexture. You call
78 : ITexture* texture = driver->createTexture(dimension2d<u32>(128, 128));
79 : If you no longer need the texture, call texture->drop().
80 : If you want to load a texture, you may want to call imaginable
81 : method IDriver::loadTexture. You do this like
82 : ITexture* texture = driver->loadTexture("example.jpg");
83 : You will not have to drop the pointer to the loaded texture,
84 : because the name of the method does not start with 'create'.
85 : The texture is stored somewhere by the driver. */
86 520571 : void grab() const { ++ReferenceCounter; }
87 :
88 : //! Drops the object. Decrements the reference counter by one.
89 : /** The IReferenceCounted class provides a basic reference
90 : counting mechanism with its methods grab() and drop(). Most
91 : objects of the Irrlicht Engine are derived from
92 : IReferenceCounted, and so they are reference counted.
93 :
94 : When you create an object in the Irrlicht engine, calling a
95 : method which starts with 'create', an object is created, and
96 : you get a pointer to the new object. If you no longer need the
97 : object, you have to call drop(). This will destroy the object,
98 : if grab() was not called in another part of you program,
99 : because this part still needs the object. Note, that you only
100 : need to call drop() to the object, if you created it, and the
101 : method had a 'create' in it.
102 :
103 : A simple example:
104 :
105 : If you want to create a texture, you may want to call an
106 : imaginable method IDriver::createTexture. You call
107 : ITexture* texture = driver->createTexture(dimension2d<u32>(128, 128));
108 : If you no longer need the texture, call texture->drop().
109 : If you want to load a texture, you may want to call imaginable
110 : method IDriver::loadTexture. You do this like
111 : ITexture* texture = driver->loadTexture("example.jpg");
112 : You will not have to drop the pointer to the loaded texture,
113 : because the name of the method does not start with 'create'.
114 : The texture is stored somewhere by the driver.
115 : \return True, if the object was deleted. */
116 1164334 : bool drop() const
117 : {
118 : // someone is doing bad reference counting.
119 : _IRR_DEBUG_BREAK_IF(ReferenceCounter <= 0)
120 :
121 1164334 : --ReferenceCounter;
122 1164334 : if (!ReferenceCounter)
123 : {
124 639899 : delete this;
125 639899 : return true;
126 : }
127 :
128 524435 : return false;
129 : }
130 :
131 : //! Get the reference count.
132 : /** \return Current value of the reference counter. */
133 20 : s32 getReferenceCount() const
134 : {
135 20 : return ReferenceCounter;
136 : }
137 :
138 : //! Returns the debug name of the object.
139 : /** The Debugname may only be set and changed by the object
140 : itself. This method should only be used in Debug mode.
141 : \return Returns a string, previously set by setDebugName(); */
142 : const c8* getDebugName() const
143 : {
144 : return DebugName;
145 : }
146 :
147 : protected:
148 :
149 : //! Sets the debug name of the object.
150 : /** The Debugname may only be set and changed by the object
151 : itself. This method should only be used in Debug mode.
152 : \param newName: New debug name to set. */
153 : void setDebugName(const c8* newName)
154 : {
155 : DebugName = newName;
156 : }
157 :
158 : private:
159 :
160 : //! The debug name.
161 : const c8* DebugName;
162 :
163 : //! The reference counter. Mutable to do reference counting on const objects.
164 : mutable s32 ReferenceCounter;
165 : };
166 :
167 : } // end namespace irr
168 :
169 : #endif
170 :
|