244 lines
6.7 KiB
C++
244 lines
6.7 KiB
C++
#pragma once
|
|
// This class was copied from Unity's source code and modified to not depend on Unity's MemoryManager
|
|
|
|
#include "ReferenceCounter.h"
|
|
|
|
#include <vector>
|
|
|
|
#include <Windows.Foundation.Collections.h>
|
|
#include <wrl.h>
|
|
|
|
namespace Internal
|
|
{
|
|
template<typename T>
|
|
inline void AddItemRef(T& value)
|
|
{
|
|
il2cpp::winrt::ReferenceCounter<T>::AddRef(value);
|
|
}
|
|
|
|
template<typename T>
|
|
inline void ReleaseItem(T& value)
|
|
{
|
|
il2cpp::winrt::ReferenceCounter<T>::Release(value);
|
|
value = T();
|
|
}
|
|
}
|
|
|
|
namespace il2cpp
|
|
{
|
|
namespace winrt
|
|
{
|
|
template<typename T>
|
|
struct Vector :
|
|
public Microsoft::WRL::RuntimeClass<Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::WinRtClassicComMix>,
|
|
Microsoft::WRL::FtmBase,
|
|
ABI::Windows::Foundation::Collections::IVector<T>,
|
|
ABI::Windows::Foundation::Collections::IVectorView<T>,
|
|
ABI::Windows::Foundation::Collections::IIterable<T> >
|
|
{
|
|
private:
|
|
struct Iterator :
|
|
public Microsoft::WRL::RuntimeClass<Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::WinRtClassicComMix>, Microsoft::WRL::FtmBase, ABI::Windows::Foundation::Collections::IIterator<T> >
|
|
{
|
|
private:
|
|
Microsoft::WRL::ComPtr<Vector<T> > m_Vector;
|
|
size_t m_Position;
|
|
|
|
public:
|
|
Iterator(Vector<T>* vector) :
|
|
m_Vector(vector), m_Position(0)
|
|
{
|
|
}
|
|
|
|
virtual HRESULT STDCALL get_Current(T* current) override
|
|
{
|
|
if (m_Position >= m_Vector->m_Vector.size())
|
|
{
|
|
return E_BOUNDS;
|
|
}
|
|
|
|
*current = m_Vector->m_Vector[m_Position];
|
|
::Internal::AddItemRef(*current);
|
|
return S_OK;
|
|
}
|
|
|
|
virtual HRESULT STDCALL get_HasCurrent(boolean* hasCurrent) override
|
|
{
|
|
*hasCurrent = m_Position < m_Vector->m_Vector.size();
|
|
return S_OK;
|
|
}
|
|
|
|
virtual HRESULT STDCALL MoveNext(boolean* hasCurrent) override
|
|
{
|
|
if (m_Position < m_Vector->m_Vector.size())
|
|
{
|
|
m_Position++;
|
|
*hasCurrent = m_Position < m_Vector->m_Vector.size();
|
|
}
|
|
else
|
|
{
|
|
*hasCurrent = false;
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
virtual HRESULT STDCALL GetMany(uint32_t capacity, T* dest, uint32_t* actualCount) override
|
|
{
|
|
return m_Vector->GetMany(0, capacity, dest, actualCount);
|
|
}
|
|
};
|
|
|
|
friend struct Iterator;
|
|
|
|
std::vector<T> m_Vector;
|
|
|
|
inline void ClearInternal()
|
|
{
|
|
for (size_t i = 0; i < m_Vector.size(); i++)
|
|
::Internal::ReleaseItem(m_Vector[i]);
|
|
|
|
m_Vector.clear();
|
|
}
|
|
|
|
public:
|
|
Vector()
|
|
{
|
|
}
|
|
|
|
virtual ~Vector()
|
|
{
|
|
ClearInternal();
|
|
}
|
|
|
|
virtual HRESULT STDCALL GetAt(uint32_t index, T* item) override
|
|
{
|
|
*item = m_Vector[index];
|
|
::Internal::AddItemRef(*item);
|
|
return S_OK;
|
|
}
|
|
|
|
virtual HRESULT STDCALL GetMany(uint32_t startIndex, uint32_t capacity, T* dest, uint32_t* actualCount) override
|
|
{
|
|
ZeroMemory(dest, sizeof(T) * capacity);
|
|
|
|
if (startIndex > m_Vector.size())
|
|
return E_BOUNDS;
|
|
|
|
uint32_t count = std::min(capacity, static_cast<uint32_t>(m_Vector.size()) - startIndex);
|
|
|
|
for (uint32_t i = 0; i < count; i++)
|
|
{
|
|
dest[i] = m_Vector[i + startIndex];
|
|
::Internal::AddItemRef(dest[i]);
|
|
}
|
|
|
|
*actualCount = count;
|
|
return S_OK;
|
|
}
|
|
|
|
virtual HRESULT STDCALL get_Size(uint32_t* size) override
|
|
{
|
|
*size = static_cast<unsigned>(m_Vector.size());
|
|
return S_OK;
|
|
}
|
|
|
|
virtual HRESULT STDCALL GetView(ABI::Windows::Foundation::Collections::IVectorView<T>** view) override
|
|
{
|
|
AddRef();
|
|
*view = this;
|
|
return S_OK;
|
|
}
|
|
|
|
virtual HRESULT STDCALL IndexOf(T value, uint32_t* index, boolean* found) override
|
|
{
|
|
*found = false;
|
|
|
|
for (*index = 0; *index < m_Vector.size(); (*index)++)
|
|
{
|
|
if (value == m_Vector[*index])
|
|
{
|
|
*found = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
virtual HRESULT STDCALL SetAt(uint32_t index, T item) override
|
|
{
|
|
::Internal::ReleaseItem(m_Vector[index]);
|
|
m_Vector[index] = item;
|
|
::Internal::AddItemRef(m_Vector[index]);
|
|
return S_OK;
|
|
}
|
|
|
|
virtual HRESULT STDCALL InsertAt(uint32_t index, T item) override
|
|
{
|
|
m_Vector.insert(m_Vector.begin() + index, item);
|
|
::Internal::AddItemRef(m_Vector[index]);
|
|
return S_OK;
|
|
}
|
|
|
|
virtual HRESULT STDCALL RemoveAt(uint32_t index) override
|
|
{
|
|
if (m_Vector.size() <= index)
|
|
return E_FAIL;
|
|
|
|
::Internal::ReleaseItem(m_Vector[index]);
|
|
m_Vector.erase(m_Vector.begin() + index);
|
|
return S_OK;
|
|
}
|
|
|
|
virtual HRESULT STDCALL Append(T item) override
|
|
{
|
|
m_Vector.push_back(item);
|
|
::Internal::AddItemRef(m_Vector.back());
|
|
return S_OK;
|
|
}
|
|
|
|
virtual HRESULT STDCALL RemoveAtEnd() override
|
|
{
|
|
if (m_Vector.empty())
|
|
return E_FAIL;
|
|
|
|
::Internal::ReleaseItem(m_Vector.back());
|
|
m_Vector.pop_back();
|
|
return S_OK;
|
|
}
|
|
|
|
virtual HRESULT STDCALL ReplaceAll(uint32_t count, T* values) override
|
|
{
|
|
ClearInternal();
|
|
m_Vector.reserve(count);
|
|
|
|
for (uint32_t i = 0; i < count; i++)
|
|
{
|
|
m_Vector.push_back(values[i]);
|
|
::Internal::AddItemRef(m_Vector.back());
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
virtual HRESULT STDCALL Clear() override
|
|
{
|
|
ClearInternal();
|
|
return S_OK;
|
|
}
|
|
|
|
virtual HRESULT STDCALL First(ABI::Windows::Foundation::Collections::IIterator<T>** first) override
|
|
{
|
|
*first = Microsoft::WRL::Make<Iterator>(this).Detach();
|
|
return S_OK;
|
|
}
|
|
|
|
void Reserve(size_t count)
|
|
{
|
|
m_Vector.reserve(count);
|
|
}
|
|
};
|
|
}
|
|
}
|