diff --git a/lib/hkStubs/CMakeLists.txt b/lib/hkStubs/CMakeLists.txt index 06f6380f..62d5a7d9 100644 --- a/lib/hkStubs/CMakeLists.txt +++ b/lib/hkStubs/CMakeLists.txt @@ -5,6 +5,7 @@ add_library(hkStubs OBJECT Havok/Common/Base/Container/hkContainerAllocators.h Havok/Common/Base/Container/Array/hkArray.h + Havok/Common/Base/Container/Array/hkArrayUtil.h Havok/Common/Base/Container/String/hkStringPtr.h Havok/Common/Base/Math/hkMath.h diff --git a/lib/hkStubs/Havok/Common/Base/Container/Array/hkArray.h b/lib/hkStubs/Havok/Common/Base/Container/Array/hkArray.h index 8e7e9001..0c78dbe8 100644 --- a/lib/hkStubs/Havok/Common/Base/Container/Array/hkArray.h +++ b/lib/hkStubs/Havok/Common/Base/Container/Array/hkArray.h @@ -1,8 +1,10 @@ #pragma once +#include #include #include #include +#include /// Base class for hkArray (a std::vector-like container). // FIXME: incomplete @@ -18,6 +20,7 @@ public: }; HK_FORCE_INLINE hkArrayBase(); + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init) explicit hkArrayBase(hkFinishLoadedObjectFlag f) {} HK_FORCE_INLINE ~hkArrayBase(); @@ -25,6 +28,14 @@ public: hkArrayBase(const hkArrayBase&) = delete; auto operator=(const hkArrayBase&) = delete; + HK_FORCE_INLINE int getSize() const; + HK_FORCE_INLINE int getCapacity() const; + HK_FORCE_INLINE int getCapacityAndFlags() const; + HK_FORCE_INLINE hkBool isEmpty() const; + + HK_FORCE_INLINE void clear(); + HK_FORCE_INLINE void _clearAndDeallocate(hkMemoryAllocator& allocator); + protected: T* m_data; int m_size; @@ -41,11 +52,13 @@ public: HK_FORCE_INLINE hkArray() = default; explicit hkArray(hkFinishLoadedObjectFlag f) : hkArrayBase(f) {} - HK_FORCE_INLINE ~hkArray(); + HK_FORCE_INLINE ~hkArray() { clearAndDeallocate(); } HK_FORCE_INLINE hkArray& operator=(const hkArrayBase& other); HK_FORCE_INLINE hkArray& operator=(const hkArray& other); + HK_FORCE_INLINE void clearAndDeallocate(); + protected: HK_FORCE_INLINE hkArray(const hkArray& other); }; @@ -58,3 +71,47 @@ template inline hkArrayBase::~hkArrayBase() { // Assert non-POD element destruction } + +template +inline int hkArrayBase::getSize() const { + return m_size; +} + +template +inline int hkArrayBase::getCapacity() const { + return m_capacityAndFlags & static_cast(CAPACITY_MASK); +} + +template +inline int hkArrayBase::getCapacityAndFlags() const { + return m_capacityAndFlags; +} + +template +inline hkBool hkArrayBase::isEmpty() const { + return m_size == 0; +} + +template +inline void hkArrayBase::clear() { + hkArrayUtil::destruct(m_data, m_size); + m_size = 0; +} + +template +inline void hkArrayBase::_clearAndDeallocate(hkMemoryAllocator& allocator) { + clear(); + if ((m_capacityAndFlags & DONT_DEALLOCATE_FLAG) == 0) { + const int SIZE_ELEM = hkSizeOfTypeOrVoid::val; + int numBytes = getCapacity() * SIZE_ELEM; + void* storage = const_cast*>(m_data); + allocator.bufFree(storage, numBytes); + } + m_data = nullptr; + m_capacityAndFlags = DONT_DEALLOCATE_FLAG; +} + +template +inline void hkArray::clearAndDeallocate() { + this->_clearAndDeallocate(AllocatorType().get()); +} diff --git a/lib/hkStubs/Havok/Common/Base/Container/Array/hkArrayUtil.h b/lib/hkStubs/Havok/Common/Base/Container/Array/hkArrayUtil.h new file mode 100644 index 00000000..8a5c8241 --- /dev/null +++ b/lib/hkStubs/Havok/Common/Base/Container/Array/hkArrayUtil.h @@ -0,0 +1,51 @@ +#pragma once + +#include + +class hkArrayUtil { +public: + template + static HK_FORCE_INLINE void construct(T* t, int n); + + template + static HK_FORCE_INLINE void constructWithCopy(T* t, int n, const T& tcopy); + + template + static HK_FORCE_INLINE void constructWithArray(T* t, int n, const T* tcopy); + + template + static HK_FORCE_INLINE void destruct(T* t, int n); + + static hkResult _reserve(hkMemoryAllocator& a, void*, int reqElem, int sizeElem); + static void _reserveMore(hkMemoryAllocator& a, void* array, int sizeElem); + static void _reduce(hkMemoryAllocator& a, void* array, int sizeElem, char* inplaceMem, + int requestedCapacity); +}; + +template +inline void hkArrayUtil::construct(T* t, int n) { + for (int i = 0; i < n; ++i) { + ::new (static_cast(t + i)) T; + } +} + +template +inline void hkArrayUtil::constructWithCopy(T* t, int n, const T& tcopy) { + for (int i = 0; i < n; ++i) { + ::new (static_cast(t + i)) T(tcopy); + } +} + +template +inline void hkArrayUtil::constructWithArray(T* t, int n, const T* tcopy) { + for (int i = 0; i < n; ++i) { + ::new (static_cast(t + i)) T(tcopy[i]); + } +} + +template +inline void hkArrayUtil::destruct(T* t, int n) { + for (int i = n - 1; i >= 0; --i) { + static_cast(t)[i].~T(); + } +}