Ref.hpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. #ifndef REF_H
  2. #define REF_H
  3. #include "Variant.hpp"
  4. #include "GodotGlobal.hpp"
  5. namespace godot {
  6. class Reference;
  7. class Object;
  8. // Replicates Godot's Ref<T> behavior
  9. // Rewritten from f5234e70be7dec4930c2d5a0e829ff480d044b1d.
  10. template <class T>
  11. class Ref {
  12. T *reference = NULL;
  13. void ref(const Ref &p_from) {
  14. if (p_from.reference == reference)
  15. return;
  16. unref();
  17. reference = p_from.reference;
  18. if (reference)
  19. reference->reference();
  20. }
  21. void ref_pointer(T *p_ref) {
  22. ERR_FAIL_COND(!p_ref);
  23. if (p_ref->init_ref())
  24. reference = p_ref;
  25. }
  26. public:
  27. inline bool operator<(const Ref<T> &p_r) const {
  28. return reference < p_r.reference;
  29. }
  30. inline bool operator==(const Ref<T> &p_r) const {
  31. return reference == p_r.reference;
  32. }
  33. inline bool operator!=(const Ref<T> &p_r) const {
  34. return reference != p_r.reference;
  35. }
  36. inline T *operator->() {
  37. return reference;
  38. }
  39. inline T *operator*() {
  40. return reference;
  41. }
  42. inline const T *operator->() const {
  43. return reference;
  44. }
  45. inline const T *ptr() const {
  46. return reference;
  47. }
  48. inline T *ptr() {
  49. return reference;
  50. }
  51. inline const T *operator*() const {
  52. return reference;
  53. }
  54. operator Variant() const {
  55. // Note: the C API handles the cases where the object is a Reference,
  56. // so the Variant will be correctly constructed with a RefPtr engine-side
  57. return Variant((Object*)reference);
  58. }
  59. void operator=(const Ref &p_from) {
  60. ref(p_from);
  61. }
  62. template <class T_Other>
  63. void operator=(const Ref<T_Other> &p_from) {
  64. // TODO We need a safe cast
  65. Reference *refb = const_cast<Reference *>(static_cast<const Reference *>(p_from.ptr()));
  66. if (!refb) {
  67. unref();
  68. return;
  69. }
  70. Ref r;
  71. //r.reference = Object::cast_to<T>(refb);
  72. r.reference = (T*)refb;
  73. ref(r);
  74. r.reference = NULL;
  75. }
  76. void operator=(const Variant &p_variant) {
  77. // TODO We need a safe cast
  78. Reference *refb = (Reference *) (Object *) p_variant;
  79. if (!refb) {
  80. unref();
  81. return;
  82. }
  83. Ref r;
  84. // TODO We need a safe cast
  85. //r.reference = Object::cast_to<T>(refb);
  86. r.reference = (T *)refb;
  87. ref(r);
  88. r.reference = NULL;
  89. }
  90. Ref(const Ref &p_from) {
  91. reference = NULL;
  92. ref(p_from);
  93. }
  94. template <class T_Other>
  95. Ref(const Ref<T_Other> &p_from) {
  96. reference = NULL;
  97. // TODO We need a safe cast
  98. Reference *refb = const_cast<Reference *>(static_cast<const Reference *>(p_from.ptr()));
  99. if (!refb) {
  100. unref();
  101. return;
  102. }
  103. Ref r;
  104. // TODO We need a safe cast
  105. //r.reference = Object::cast_to<T>(refb);
  106. r.reference = (T *)refb;
  107. ref(r);
  108. r.reference = NULL;
  109. }
  110. Ref(T *p_reference) {
  111. if (p_reference)
  112. ref_pointer(p_reference);
  113. else
  114. reference = NULL;
  115. }
  116. Ref(const Variant &p_variant) {
  117. reference = NULL;
  118. // TODO We need a safe cast
  119. Reference *refb = (Reference *) (Object *) p_variant;
  120. if (!refb) {
  121. unref();
  122. return;
  123. }
  124. Ref r;
  125. // TODO We need a safe cast
  126. //r.reference = Object::cast_to<T>(refb);
  127. r.reference = (T *)refb;
  128. ref(r);
  129. r.reference = NULL;
  130. }
  131. inline bool is_valid() const { return reference != NULL; }
  132. inline bool is_null() const { return reference == NULL; }
  133. void unref() {
  134. //TODO this should be moved to mutexes, since this engine does not really
  135. // do a lot of referencing on references and stuff
  136. // mutexes will avoid more crashes?
  137. if (reference && reference->unreference()) {
  138. //memdelete(reference);
  139. delete reference;
  140. }
  141. reference = NULL;
  142. }
  143. void instance() {
  144. //ref(memnew(T));
  145. ref(new T);
  146. }
  147. Ref() {
  148. reference = NULL;
  149. }
  150. ~Ref() {
  151. unref();
  152. }
  153. // Used exclusively in the bindings to recreate the Ref Godot encapsulates in return values,
  154. // without adding to the refcount.
  155. inline static Ref<T> __internal_constructor(Object *obj)
  156. {
  157. Ref<T> r;
  158. r.reference = (T*)obj;
  159. return r;
  160. }
  161. };
  162. }
  163. #endif