IReferenceCounted.h 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  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. #pragma once
  5. #include "irrTypes.h"
  6. #include <cassert>
  7. namespace irr
  8. {
  9. //! Base class of most objects of the Irrlicht Engine.
  10. /** This class provides reference counting through the methods grab() and drop().
  11. It also is able to store a debug string for every instance of an object.
  12. Most objects of the Irrlicht
  13. Engine are derived from IReferenceCounted, and so they are reference counted.
  14. When you create an object in the Irrlicht engine, calling a method
  15. which starts with 'create', an object is created, and you get a pointer
  16. to the new object. If you no longer need the object, you have
  17. to call drop(). This will destroy the object, if grab() was not called
  18. in another part of you program, because this part still needs the object.
  19. Note, that you only need to call drop() to the object, if you created it,
  20. and the method had a 'create' in it.
  21. A simple example:
  22. If you want to create a texture, you may want to call an imaginable method
  23. IDriver::createTexture. You call
  24. ITexture* texture = driver->createTexture(dimension2d<u32>(128, 128));
  25. If you no longer need the texture, call texture->drop().
  26. If you want to load a texture, you may want to call imaginable method
  27. IDriver::loadTexture. You do this like
  28. ITexture* texture = driver->loadTexture("example.jpg");
  29. You will not have to drop the pointer to the loaded texture, because
  30. the name of the method does not start with 'create'. The texture
  31. is stored somewhere by the driver.
  32. */
  33. class IReferenceCounted
  34. {
  35. public:
  36. //! Constructor.
  37. IReferenceCounted() :
  38. ReferenceCounter(1)
  39. {
  40. }
  41. //! Destructor.
  42. virtual ~IReferenceCounted()
  43. {
  44. }
  45. // Reference counted objects can be neither copied nor moved.
  46. IReferenceCounted(const IReferenceCounted &) = delete;
  47. IReferenceCounted &operator=(const IReferenceCounted &) = delete;
  48. //! Grabs the object. Increments the reference counter by one.
  49. /** Someone who calls grab() to an object, should later also
  50. call drop() to it. If an object never gets as much drop() as
  51. grab() calls, it will never be destroyed. The
  52. IReferenceCounted class provides a basic reference counting
  53. mechanism with its methods grab() and drop(). Most objects of
  54. the Irrlicht Engine are derived from IReferenceCounted, and so
  55. they are reference counted.
  56. When you create an object in the Irrlicht engine, calling a
  57. method which starts with 'create', an object is created, and
  58. you get a pointer to the new object. If you no longer need the
  59. object, you have to call drop(). This will destroy the object,
  60. if grab() was not called in another part of you program,
  61. because this part still needs the object. Note, that you only
  62. need to call drop() to the object, if you created it, and the
  63. method had a 'create' in it.
  64. A simple example:
  65. If you want to create a texture, you may want to call an
  66. imaginable method IDriver::createTexture. You call
  67. ITexture* texture = driver->createTexture(dimension2d<u32>(128, 128));
  68. If you no longer need the texture, call texture->drop().
  69. If you want to load a texture, you may want to call imaginable
  70. method IDriver::loadTexture. You do this like
  71. ITexture* texture = driver->loadTexture("example.jpg");
  72. You will not have to drop the pointer to the loaded texture,
  73. because the name of the method does not start with 'create'.
  74. The texture is stored somewhere by the driver. */
  75. void grab() const { ++ReferenceCounter; }
  76. //! Drops the object. Decrements the reference counter by one.
  77. /** The IReferenceCounted class provides a basic reference
  78. counting mechanism with its methods grab() and drop(). Most
  79. objects of the Irrlicht Engine are derived from
  80. IReferenceCounted, and so they are reference counted.
  81. When you create an object in the Irrlicht engine, calling a
  82. method which starts with 'create', an object is created, and
  83. you get a pointer to the new object. If you no longer need the
  84. object, you have to call drop(). This will destroy the object,
  85. if grab() was not called in another part of you program,
  86. because this part still needs the object. Note, that you only
  87. need to call drop() to the object, if you created it, and the
  88. method had a 'create' in it.
  89. A simple example:
  90. If you want to create a texture, you may want to call an
  91. imaginable method IDriver::createTexture. You call
  92. ITexture* texture = driver->createTexture(dimension2d<u32>(128, 128));
  93. If you no longer need the texture, call texture->drop().
  94. If you want to load a texture, you may want to call imaginable
  95. method IDriver::loadTexture. You do this like
  96. ITexture* texture = driver->loadTexture("example.jpg");
  97. You will not have to drop the pointer to the loaded texture,
  98. because the name of the method does not start with 'create'.
  99. The texture is stored somewhere by the driver.
  100. \return True, if the object was deleted. */
  101. bool drop() const
  102. {
  103. // someone is doing bad reference counting.
  104. assert(ReferenceCounter > 0);
  105. --ReferenceCounter;
  106. if (!ReferenceCounter) {
  107. delete this;
  108. return true;
  109. }
  110. return false;
  111. }
  112. //! Get the reference count.
  113. /** \return Current value of the reference counter. */
  114. s32 getReferenceCount() const
  115. {
  116. return ReferenceCounter;
  117. }
  118. private:
  119. //! The reference counter. Mutable to do reference counting on const objects.
  120. mutable s32 ReferenceCounter;
  121. };
  122. } // end namespace irr