Ref.hpp 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. #ifndef REF_H
  2. #define REF_H
  3. #include "Variant.hpp"
  4. namespace godot {
  5. template<class T>
  6. class Ref {
  7. T *reference;
  8. void ref(const Ref &from)
  9. {
  10. if (from.reference == reference) return;
  11. unref();
  12. reference = from.reference;
  13. if (reference) reference->reference();
  14. }
  15. void ref_pointer(T *r)
  16. {
  17. if (!r) return;
  18. if (r->init_ref()) reference = r;
  19. }
  20. public:
  21. inline bool operator==(const Ref<T> &r) const
  22. {
  23. return reference == r.reference;
  24. }
  25. inline bool operator!=(const Ref<T> &r) const
  26. {
  27. return reference != r.reference;
  28. }
  29. inline T *operator->()
  30. {
  31. return reference;
  32. }
  33. inline T *operator*()
  34. {
  35. return reference;
  36. }
  37. inline T *ptr()
  38. {
  39. return reference;
  40. }
  41. inline const T *operator->() const
  42. {
  43. return reference;
  44. }
  45. inline const T *operator*() const
  46. {
  47. return reference;
  48. }
  49. inline const T *ptr() const
  50. {
  51. return reference;
  52. }
  53. void operator=(const Ref &from)
  54. {
  55. ref(from);
  56. }
  57. template<class T_Other>
  58. void operator=(const Ref<T_Other> &from)
  59. {
  60. Ref<T> n((T *) from.ptr());
  61. ref(n);
  62. }
  63. void operator=(const Variant &variant)
  64. {
  65. T *r = (T *) (Object *) variant;
  66. if (!r) {
  67. unref();
  68. return;
  69. }
  70. Ref re;
  71. re.reference = r;
  72. ref(re);
  73. re.reference = nullptr;
  74. }
  75. operator Variant() const
  76. {
  77. return Variant((Object *) reference);
  78. }
  79. template<class T_Other>
  80. Ref(const Ref<T_Other> &from)
  81. {
  82. if (from.ptr())
  83. ref_pointer((T *) from.ptr());
  84. else
  85. reference = nullptr;
  86. }
  87. Ref(const Ref &from)
  88. {
  89. reference = nullptr;
  90. ref(from);
  91. }
  92. Ref(T *r)
  93. {
  94. r->reference();
  95. reference = r;
  96. }
  97. template<class T_Other>
  98. Ref(T_Other *r) : Ref((T *) r) {}
  99. Ref(const Variant &variant)
  100. {
  101. reference = nullptr;
  102. T *r = (T *) (Object *) variant;
  103. if (!r) {
  104. unref();
  105. return;
  106. }
  107. Ref re;
  108. re.reference = r;
  109. ref(re);
  110. re.reference = nullptr;
  111. }
  112. template<class T_Other>
  113. static Ref<T> __internal_constructor(T_Other *r)
  114. {
  115. Ref<T> ref;
  116. ref.reference = (T *) r;
  117. return ref;
  118. }
  119. inline bool is_valid() const { return reference != nullptr; }
  120. inline bool is_null() const { return reference == nullptr; }
  121. void unref()
  122. {
  123. if (reference && reference->unreference()) {
  124. godot_object_destroy((godot_object *) reference);
  125. }
  126. reference = nullptr;
  127. }
  128. Ref()
  129. {
  130. reference = nullptr;
  131. }
  132. ~Ref()
  133. {
  134. unref();
  135. }
  136. };
  137. }
  138. #endif