ReferenceCounted.h 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  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 ReferenceCountedObject
  37. {
  38. public:
  39. ReferenceCountedObject()
  40. {
  41. ptr = new (std::nothrow) ReferenceCounted<t>;
  42. };
  43. ~ReferenceCountedObject()
  44. {
  45. if (ptr)
  46. ptr->Release();
  47. }
  48. operator t *()
  49. {
  50. return ptr;
  51. }
  52. t *operator ->()
  53. {
  54. return ptr;
  55. }
  56. t *ptr;
  57. };
  58. template <class t>
  59. class ReferenceCountedPointer
  60. {
  61. public:
  62. ReferenceCountedPointer()
  63. {
  64. ptr = 0;
  65. };
  66. ReferenceCountedPointer(t *new_ptr)
  67. {
  68. ptr = new_ptr;
  69. };
  70. ~ReferenceCountedPointer()
  71. {
  72. if (ptr)
  73. ptr->Release();
  74. }
  75. operator t *()
  76. {
  77. return ptr;
  78. }
  79. t *operator ->()
  80. {
  81. return ptr;
  82. }
  83. t **operator &()
  84. {
  85. // if there's something already in here, we need to release it first
  86. if (ptr)
  87. ptr->Release();
  88. ptr=0;
  89. return &ptr;
  90. }
  91. t *operator =(t *new_ptr)
  92. {
  93. if (ptr)
  94. ptr->Release();
  95. ptr=0;
  96. ptr = new_ptr;
  97. return ptr;
  98. }
  99. t *ptr;
  100. };
  101. class ReferenceCountedNXString
  102. {
  103. public:
  104. ReferenceCountedNXString()
  105. {
  106. ptr = 0;
  107. };
  108. ~ReferenceCountedNXString()
  109. {
  110. NXStringRelease(ptr);
  111. }
  112. operator nx_string_t()
  113. {
  114. return ptr;
  115. }
  116. nx_string_t *operator &()
  117. {
  118. // if there's something already in here, we need to release it first
  119. if (ptr)
  120. NXStringRelease(ptr);
  121. ptr=0;
  122. return &ptr;
  123. }
  124. nx_string_t operator ->()
  125. {
  126. return ptr;
  127. }
  128. nx_string_t ptr;
  129. };
  130. class ReferenceCountedNXURI
  131. {
  132. public:
  133. ReferenceCountedNXURI()
  134. {
  135. ptr = 0;
  136. };
  137. ~ReferenceCountedNXURI()
  138. {
  139. NXURIRelease(ptr);
  140. }
  141. operator nx_uri_t()
  142. {
  143. return ptr;
  144. }
  145. nx_uri_t *operator &()
  146. {
  147. // if there's something already in here, we need to release it first
  148. if (ptr)
  149. NXURIRelease(ptr);
  150. ptr=0;
  151. return &ptr;
  152. }
  153. nx_uri_t operator ->()
  154. {
  155. return ptr;
  156. }
  157. nx_uri_t ptr;
  158. };