WinRTVector.h 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. #pragma once
  2. // This class was copied from Unity's source code and modified to not depend on Unity's MemoryManager
  3. #include "ReferenceCounter.h"
  4. #include <vector>
  5. #include <Windows.Foundation.Collections.h>
  6. #include <wrl.h>
  7. namespace Internal
  8. {
  9. template<typename T>
  10. inline void AddItemRef(T& value)
  11. {
  12. il2cpp::winrt::ReferenceCounter<T>::AddRef(value);
  13. }
  14. template<typename T>
  15. inline void ReleaseItem(T& value)
  16. {
  17. il2cpp::winrt::ReferenceCounter<T>::Release(value);
  18. value = T();
  19. }
  20. }
  21. namespace il2cpp
  22. {
  23. namespace winrt
  24. {
  25. template<typename T>
  26. struct Vector :
  27. public Microsoft::WRL::RuntimeClass<Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::WinRtClassicComMix>,
  28. Microsoft::WRL::FtmBase,
  29. ABI::Windows::Foundation::Collections::IVector<T>,
  30. ABI::Windows::Foundation::Collections::IVectorView<T>,
  31. ABI::Windows::Foundation::Collections::IIterable<T> >
  32. {
  33. private:
  34. struct Iterator :
  35. public Microsoft::WRL::RuntimeClass<Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::WinRtClassicComMix>, Microsoft::WRL::FtmBase, ABI::Windows::Foundation::Collections::IIterator<T> >
  36. {
  37. private:
  38. Microsoft::WRL::ComPtr<Vector<T> > m_Vector;
  39. size_t m_Position;
  40. public:
  41. Iterator(Vector<T>* vector) :
  42. m_Vector(vector), m_Position(0)
  43. {
  44. }
  45. virtual HRESULT STDCALL get_Current(T* current) override
  46. {
  47. if (m_Position >= m_Vector->m_Vector.size())
  48. {
  49. return E_BOUNDS;
  50. }
  51. *current = m_Vector->m_Vector[m_Position];
  52. ::Internal::AddItemRef(*current);
  53. return S_OK;
  54. }
  55. virtual HRESULT STDCALL get_HasCurrent(boolean* hasCurrent) override
  56. {
  57. *hasCurrent = m_Position < m_Vector->m_Vector.size();
  58. return S_OK;
  59. }
  60. virtual HRESULT STDCALL MoveNext(boolean* hasCurrent) override
  61. {
  62. if (m_Position < m_Vector->m_Vector.size())
  63. {
  64. m_Position++;
  65. *hasCurrent = m_Position < m_Vector->m_Vector.size();
  66. }
  67. else
  68. {
  69. *hasCurrent = false;
  70. }
  71. return S_OK;
  72. }
  73. virtual HRESULT STDCALL GetMany(uint32_t capacity, T* dest, uint32_t* actualCount) override
  74. {
  75. return m_Vector->GetMany(0, capacity, dest, actualCount);
  76. }
  77. };
  78. friend struct Iterator;
  79. std::vector<T> m_Vector;
  80. inline void ClearInternal()
  81. {
  82. for (size_t i = 0; i < m_Vector.size(); i++)
  83. ::Internal::ReleaseItem(m_Vector[i]);
  84. m_Vector.clear();
  85. }
  86. public:
  87. Vector()
  88. {
  89. }
  90. virtual ~Vector()
  91. {
  92. ClearInternal();
  93. }
  94. virtual HRESULT STDCALL GetAt(uint32_t index, T* item) override
  95. {
  96. *item = m_Vector[index];
  97. ::Internal::AddItemRef(*item);
  98. return S_OK;
  99. }
  100. virtual HRESULT STDCALL GetMany(uint32_t startIndex, uint32_t capacity, T* dest, uint32_t* actualCount) override
  101. {
  102. ZeroMemory(dest, sizeof(T) * capacity);
  103. if (startIndex > m_Vector.size())
  104. return E_BOUNDS;
  105. uint32_t count = static_cast<uint32_t>(m_Vector.size()) - startIndex;
  106. if (count > capacity)
  107. count = capacity;
  108. for (uint32_t i = 0; i < count; i++)
  109. {
  110. dest[i] = m_Vector[i + startIndex];
  111. ::Internal::AddItemRef(dest[i]);
  112. }
  113. *actualCount = count;
  114. return S_OK;
  115. }
  116. virtual HRESULT STDCALL get_Size(uint32_t* size) override
  117. {
  118. *size = static_cast<unsigned>(m_Vector.size());
  119. return S_OK;
  120. }
  121. virtual HRESULT STDCALL GetView(ABI::Windows::Foundation::Collections::IVectorView<T>** view) override
  122. {
  123. AddRef();
  124. *view = this;
  125. return S_OK;
  126. }
  127. virtual HRESULT STDCALL IndexOf(T value, uint32_t* index, boolean* found) override
  128. {
  129. *found = false;
  130. for (*index = 0; *index < m_Vector.size(); (*index)++)
  131. {
  132. if (value == m_Vector[*index])
  133. {
  134. *found = true;
  135. break;
  136. }
  137. }
  138. return S_OK;
  139. }
  140. virtual HRESULT STDCALL SetAt(uint32_t index, T item) override
  141. {
  142. ::Internal::ReleaseItem(m_Vector[index]);
  143. m_Vector[index] = item;
  144. ::Internal::AddItemRef(m_Vector[index]);
  145. return S_OK;
  146. }
  147. virtual HRESULT STDCALL InsertAt(uint32_t index, T item) override
  148. {
  149. m_Vector.insert(m_Vector.begin() + index, item);
  150. ::Internal::AddItemRef(m_Vector[index]);
  151. return S_OK;
  152. }
  153. virtual HRESULT STDCALL RemoveAt(uint32_t index) override
  154. {
  155. if (m_Vector.size() <= index)
  156. return E_FAIL;
  157. ::Internal::ReleaseItem(m_Vector[index]);
  158. m_Vector.erase(m_Vector.begin() + index);
  159. return S_OK;
  160. }
  161. virtual HRESULT STDCALL Append(T item) override
  162. {
  163. m_Vector.push_back(item);
  164. ::Internal::AddItemRef(m_Vector.back());
  165. return S_OK;
  166. }
  167. virtual HRESULT STDCALL RemoveAtEnd() override
  168. {
  169. if (m_Vector.empty())
  170. return E_FAIL;
  171. ::Internal::ReleaseItem(m_Vector.back());
  172. m_Vector.pop_back();
  173. return S_OK;
  174. }
  175. virtual HRESULT STDCALL ReplaceAll(uint32_t count, T* values) override
  176. {
  177. ClearInternal();
  178. m_Vector.reserve(count);
  179. for (uint32_t i = 0; i < count; i++)
  180. {
  181. m_Vector.push_back(values[i]);
  182. ::Internal::AddItemRef(m_Vector.back());
  183. }
  184. return S_OK;
  185. }
  186. virtual HRESULT STDCALL Clear() override
  187. {
  188. ClearInternal();
  189. return S_OK;
  190. }
  191. virtual HRESULT STDCALL First(ABI::Windows::Foundation::Collections::IIterator<T>** first) override
  192. {
  193. *first = Microsoft::WRL::Make<Iterator>(this).Detach();
  194. return S_OK;
  195. }
  196. void Reserve(size_t count)
  197. {
  198. m_Vector.reserve(count);
  199. }
  200. };
  201. }
  202. }