Object.h 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. /**
  2. * Copyright (c) 2006-2023 LOVE Development Team
  3. *
  4. * This software is provided 'as-is', without any express or implied
  5. * warranty. In no event will the authors be held liable for any damages
  6. * arising from the use of this software.
  7. *
  8. * Permission is granted to anyone to use this software for any purpose,
  9. * including commercial applications, and to alter it and redistribute it
  10. * freely, subject to the following restrictions:
  11. *
  12. * 1. The origin of this software must not be misrepresented; you must not
  13. * claim that you wrote the original software. If you use this software
  14. * in a product, an acknowledgment in the product documentation would be
  15. * appreciated but is not required.
  16. * 2. Altered source versions must be plainly marked as such, and must not be
  17. * misrepresented as being the original software.
  18. * 3. This notice may not be removed or altered from any source distribution.
  19. **/
  20. #ifndef LOVE_OBJECT_H
  21. #define LOVE_OBJECT_H
  22. #include <atomic>
  23. #include "types.h"
  24. namespace love
  25. {
  26. /**
  27. * Superclass for all object that should be able to cross the Lua/C border
  28. * (this pertains to most objects).
  29. *
  30. * This class is an alternative to using smart pointers; it contains retain/release
  31. * methods, and will delete itself with the reference count hits zero. The wrapper
  32. * code assumes that all userdata inherits from this class.
  33. **/
  34. class Object
  35. {
  36. public:
  37. static love::Type type;
  38. /**
  39. * Constructor. Sets reference count to one.
  40. **/
  41. Object();
  42. Object(const Object &other);
  43. /**
  44. * Destructor.
  45. **/
  46. virtual ~Object() = 0;
  47. /**
  48. * Gets the reference count of this Object.
  49. * @returns The reference count.
  50. **/
  51. int getReferenceCount() const;
  52. /**
  53. * Retains the Object, i.e. increases the
  54. * reference count by one.
  55. **/
  56. void retain();
  57. /**
  58. * Releases one reference to the Object, i.e. decrements the
  59. * reference count by one, and potentially deletes the Object
  60. * if there are no more references.
  61. **/
  62. void release();
  63. private:
  64. // The reference count.
  65. std::atomic<int> count;
  66. }; // Object
  67. enum class Acquire
  68. {
  69. RETAIN,
  70. NORETAIN,
  71. };
  72. template <typename T>
  73. class StrongRef
  74. {
  75. public:
  76. StrongRef()
  77. : object(nullptr)
  78. {
  79. }
  80. StrongRef(T *obj, Acquire acquire = Acquire::RETAIN)
  81. : object(obj)
  82. {
  83. if (object && acquire == Acquire::RETAIN) object->retain();
  84. }
  85. StrongRef(const StrongRef &other)
  86. : object(other.get())
  87. {
  88. if (object) object->retain();
  89. }
  90. StrongRef(StrongRef &&other)
  91. : object(other.object)
  92. {
  93. other.object = nullptr;
  94. }
  95. ~StrongRef()
  96. {
  97. if (object) object->release();
  98. }
  99. StrongRef &operator = (const StrongRef &other)
  100. {
  101. set(other.get());
  102. return *this;
  103. }
  104. T *operator->() const
  105. {
  106. return object;
  107. }
  108. explicit operator bool() const
  109. {
  110. return object != nullptr;
  111. }
  112. operator T*() const
  113. {
  114. return object;
  115. }
  116. void set(T *obj, Acquire acquire = Acquire::RETAIN)
  117. {
  118. if (obj && acquire == Acquire::RETAIN) obj->retain();
  119. if (object) object->release();
  120. object = obj;
  121. }
  122. T *get() const
  123. {
  124. return object;
  125. }
  126. private:
  127. T *object;
  128. }; // StrongRef
  129. } // love
  130. #endif // LOVE_OBJECT_H