ReferenceCounted.h 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. #pragma once
  2. #include "../foundation/dispatch.h"
  3. #include "../foundation/atomics.h"
  4. #include <new>
  5. #include "../nx/nxstring.h"
  6. #include "../nx/nxuri.h"
  7. #define REFERENCE_COUNT_AS(x) size_t Retain() { return x::Retain(); } size_t Release() { return x::Release(); }
  8. template <class t>
  9. class ReferenceCounted : public t
  10. {
  11. public:
  12. ReferenceCounted() { reference_count = 1; }
  13. protected:
  14. /* Dispatchable implementation */
  15. size_t WASABICALL Dispatchable_Retain()
  16. {
  17. return nx_atomic_inc(&reference_count);
  18. }
  19. size_t WASABICALL Dispatchable_Release()
  20. {
  21. if (!reference_count)
  22. return reference_count;
  23. size_t r = nx_atomic_dec(&reference_count);
  24. if (!r)
  25. {
  26. #if defined(__ARM_ARCH_7A__)
  27. __asm__ __volatile__ ("dmb" : : : "memory");
  28. #endif
  29. delete(this);
  30. }
  31. return r;
  32. }
  33. size_t reference_count;
  34. };
  35. template <class t>
  36. class ReferenceCountedBase
  37. {
  38. public:
  39. ReferenceCountedBase() { reference_count = 1; }
  40. size_t Retain()
  41. {
  42. return nx_atomic_inc(&reference_count);
  43. }
  44. size_t Release()
  45. {
  46. if (!reference_count)
  47. return reference_count;
  48. size_t r = nx_atomic_dec(&reference_count);
  49. if (!r)
  50. {
  51. #if defined(__ARM_ARCH_7A__)
  52. __asm__ __volatile__ ("dmb" : : : "memory");
  53. #endif
  54. delete static_cast<t*>(this);
  55. }
  56. return r;
  57. }
  58. size_t reference_count;
  59. };
  60. template <class t>
  61. class ReferenceCountedObject
  62. {
  63. public:
  64. ReferenceCountedObject()
  65. {
  66. ptr = new (std::nothrow) ReferenceCounted<t>;
  67. };
  68. ~ReferenceCountedObject()
  69. {
  70. if (ptr)
  71. ptr->Release();
  72. }
  73. operator t *()
  74. {
  75. return ptr;
  76. }
  77. t *operator ->()
  78. {
  79. return ptr;
  80. }
  81. t *ptr;
  82. };
  83. template <class t>
  84. class ReferenceCountedPointer
  85. {
  86. public:
  87. ReferenceCountedPointer()
  88. {
  89. ptr = 0;
  90. };
  91. ReferenceCountedPointer(t *new_ptr)
  92. {
  93. ptr = new_ptr;
  94. };
  95. ~ReferenceCountedPointer()
  96. {
  97. if (ptr)
  98. ptr->Release();
  99. }
  100. operator t *()
  101. {
  102. return ptr;
  103. }
  104. t *operator ->()
  105. {
  106. return ptr;
  107. }
  108. t **operator &()
  109. {
  110. // if there's something already in here, we need to release it first
  111. if (ptr)
  112. ptr->Release();
  113. ptr=0;
  114. return &ptr;
  115. }
  116. t *operator =(t *new_ptr)
  117. {
  118. if (ptr)
  119. ptr->Release();
  120. ptr=0;
  121. ptr = new_ptr;
  122. return ptr;
  123. }
  124. t *ptr;
  125. };
  126. class ReferenceCountedNXString
  127. {
  128. public:
  129. ReferenceCountedNXString()
  130. {
  131. ptr = 0;
  132. }
  133. ReferenceCountedNXString(const ReferenceCountedNXString &copy)
  134. {
  135. ptr = NXStringRetain(copy.ptr);
  136. }
  137. ~ReferenceCountedNXString()
  138. {
  139. NXStringRelease(ptr);
  140. }
  141. operator nx_string_t()
  142. {
  143. return ptr;
  144. }
  145. nx_string_t *operator &()
  146. {
  147. // if there's something already in here, we need to release it first
  148. if (ptr)
  149. NXStringRelease(ptr);
  150. ptr=0;
  151. return &ptr;
  152. }
  153. nx_string_t operator =(nx_string_t new_ptr)
  154. {
  155. if (ptr)
  156. NXStringRelease(ptr);
  157. ptr = new_ptr;
  158. return ptr;
  159. }
  160. nx_string_t operator ->()
  161. {
  162. return ptr;
  163. }
  164. nx_string_t ptr;
  165. };
  166. class ReferenceCountedNXURI
  167. {
  168. public:
  169. ReferenceCountedNXURI()
  170. {
  171. ptr = 0;
  172. }
  173. ReferenceCountedNXURI(const ReferenceCountedNXURI &copy)
  174. {
  175. ptr = NXURIRetain(copy.ptr);
  176. }
  177. ~ReferenceCountedNXURI()
  178. {
  179. NXURIRelease(ptr);
  180. }
  181. operator nx_uri_t()
  182. {
  183. return ptr;
  184. }
  185. nx_uri_t *operator &()
  186. {
  187. // if there's something already in here, we need to release it first
  188. if (ptr)
  189. NXURIRelease(ptr);
  190. ptr=0;
  191. return &ptr;
  192. }
  193. nx_uri_t operator ->()
  194. {
  195. return ptr;
  196. }
  197. nx_uri_t ptr;
  198. };