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