#pragma once #include uint32 coreinit_allocFromSysArea(uint32 size, uint32 alignment); class SysAllocatorBase; class SysAllocatorContainer { public: void Initialize(); void PushSysAllocator(SysAllocatorBase* base); static SysAllocatorContainer& GetInstance(); private: std::vector m_sysAllocList; }; class SysAllocatorBase { friend class SysAllocatorContainer; public: SysAllocatorBase(); virtual ~SysAllocatorBase() = default; private: virtual void Initialize() = 0; }; template class SysAllocator : public SysAllocatorBase { public: SysAllocator() { m_tempData.resize(count); } SysAllocator(std::initializer_list l) { m_tempData.reserve(count); m_tempData.insert(m_tempData.begin(), l); if (count > l.size()) m_tempData.insert(m_tempData.end(), count - l.size(), T()); } constexpr uint32 GetCount() const { return count; } constexpr size_t GetByteSize() const { return count * sizeof(T); } T* GetPtr() const { return m_sysMem.GetPtr(); } uint32 GetMPTR() const { return m_sysMem.GetMPTR(); } T& operator*() { return *GetPtr(); } operator T*() { return GetPtr(); } SysAllocator operator+(const SysAllocator& ptr) { return SysAllocator(this->GetMPTR() + ptr.GetMPTR()); } SysAllocator operator-(const SysAllocator& ptr) { return SysAllocator(this->GetMPTR() - ptr.GetMPTR()); } T* operator+(sint32 v) { return this->GetPtr() + v; } T* operator-(sint32 v) { return this->GetPtr() - v; } operator void*() { return m_sysMem->GetPtr(); } // for all arrays except bool template typename std::enable_if< count != 1 && !std::is_same::value, Q >::type& operator[](int index) { // return tmp data until we allocated in sys mem if (m_sysMem.GetMPTR() == 0) { return m_tempData[index]; } return m_sysMem[index]; } private: SysAllocator(uint32 memptr) : m_sysMem(memptr) {} void Initialize() override { if (m_sysMem.GetMPTR() != 0) return; // alloc mem m_sysMem = { coreinit_allocFromSysArea(sizeof(T) * count, alignment) }; // copy temp buffer to mem and clear it memcpy(m_sysMem.GetPtr(), m_tempData.data(), sizeof(T)*count); m_tempData.clear(); } MEMPTR m_sysMem; std::vector m_tempData; }; template class SysAllocator : public SysAllocatorBase { public: SysAllocator() { m_tempData = {}; } SysAllocator(const T& value) { m_tempData = value; } SysAllocator& operator=(const T& value) { *m_sysMem = value; return *this; } operator T() { return *GetPtr(); } operator T*() { return GetPtr(); } T* GetPtr() const { return m_sysMem.GetPtr(); } uint32 GetMPTR() const { return m_sysMem.GetMPTR(); } T* operator&() { return (T*)m_sysMem.GetPtr(); } T* operator->() const { return this->GetPtr(); } private: void Initialize() override { if (m_sysMem.GetMPTR() != 0) return; // alloc mem m_sysMem = { coreinit_allocFromSysArea(sizeof(T), 8) }; // copy temp buffer to mem and clear it *m_sysMem = m_tempData; } MEMPTR m_sysMem; T m_tempData; };