diff --git a/cdcSys/CMakeLists.txt b/cdcSys/CMakeLists.txt index 815a455..a3a0cbc 100644 --- a/cdcSys/CMakeLists.txt +++ b/cdcSys/CMakeLists.txt @@ -2,4 +2,5 @@ target_sources(dxhr PRIVATE Allocator.cpp Assert.cpp GameHeapAllocator.cpp + RCObject.cpp ThreadSafeMemHeapAllocator.cpp) diff --git a/cdcSys/RCObject.cpp b/cdcSys/RCObject.cpp new file mode 100644 index 0000000..000efce --- /dev/null +++ b/cdcSys/RCObject.cpp @@ -0,0 +1,52 @@ +#include "RCObject.h" + +namespace cdc { + +HandleData *HandleData::s_handles = nullptr; +HandleData *HandleData::s_free = nullptr; + +void InitHandlePool(uint32_t count) { // 13 + if (HandleData::s_handles) + return; + HandleData::s_handles = new HandleData[count]; + HandleData::s_free = HandleData::s_handles + 1; + // index 0 is reserved + // index 1 is free, m_object points to next free (2) + // index 2 is free, m_object points to next free (3) + // etc. + for (uint32_t i=0; im_object; + HandleData::s_handles[x].m_object = object; + return x; +} + +RCObject::~RCObject() { // 88 + // this will call dtor of m_handleOwner +} + +void RCObject::Remove() { // 93 + delete this; +} + +} diff --git a/cdcSys/RCObject.h b/cdcSys/RCObject.h new file mode 100644 index 0000000..99e7a67 --- /dev/null +++ b/cdcSys/RCObject.h @@ -0,0 +1,255 @@ +#pragma once +#include + +namespace cdc { + +class HandleData; + +class HandleOwner { // line 43 + uint16_t m_handle; // line 73 +public: + HandleOwner(); // line 48 + ~HandleOwner(); // line 51 + bool IsInitialized() const { return m_handle != 0; } // line 55 + void CreateHandle(void *object); // line 59 + operator HandleData*() const; // line 63 +private: + HandleOwner(HandleOwner const&); // line 69 + HandleOwner& operator=(HandleOwner const&); // line 70 +}; + +template +class Handle { // line 88 + HandleData *m_handle; // line 113 +public: + Handle(); // line 572 + Handle(T*); // line 581 + Handle(Handle const&); // line 596 + ~Handle(); // line 589 + T& operator=(Handle const&); // line 604 + T& operator=(T const*); // line 615 + T *Get() const; // line 631 + operator T*() const; // line 647 + T *operator->() const; // line 653 + T *operator*() const; // line 660 +}; + +class RCObject { // line 141 + uint16_t m_refCount; + HandleOwner m_handleOwner; + +protected: + RCObject() : m_refCount(0) {} // line 386 +public: + RCObject(RCObject const&); // line 391 + HandleData *GetHandleData(); // line 403 + uint32_t GetRefCount(); // line 410 + void AddReference(); // line 415 + void RemReference(); // line 426 + + virtual ~RCObject(); // line 88 + virtual void Remove(); // line 93 +}; + +template +class RCPtr { // line 210 + T *m_object; + +public: + RCPtr(T *t); // line 444 + RCPtr(const RCPtr& other); // line 452 + ~RCPtr(); // line 469 + RCPtr& operator=(T* other) const; // line 487 + RCPtr& operator=(const RCPtr& other) const; // line 512 + T* Get() const; // line 525 + operator T*() const; // line 531 + T *operator->() const; // line 537 +}; + +void InitHandlePool(uint32_t count); // line 280 +void FreeHandlePool(); +bool IsHandlePoolValid(); // line 282 +uint32_t GetHandleCount(); + +class HandleData { // line 277, isn't that impossible? +public: + void *Get() const { // line 289 + // guessed + return m_object; + } + + void AddReference() { // line 292 + m_refCount++; + } + +private: + friend class HandleOwner; + friend void InitHandlePool(uint32_t count); + friend bool IsHandlePoolValid(); + + HandleData() : m_object(nullptr), m_refCount(9) {} // line 297 + HandleData(HandleData const&); // line 298 + HandleData& operator=(HandleData const&); // line 299 + + static uint16_t Create(void *); // line 301 + static void Destroy(HandleData*); // line 302 + + void *m_object; // line 305 + int32_t m_refCount; // line 308 + static HandleData *s_handles; // line 311 + static HandleData *s_free; // line 312 + +public: + void RemReference() { // line 355 + m_object = nullptr; // possible bug, TR2013 doesn't do this + if (--m_refCount == 0) { + m_object = (void*)s_free; + s_free = this; + } + } + +}; + +// ------------------------------------------------------------------------- // + +inline HandleOwner::HandleOwner() : m_handle(0) {} // line 345 + +inline HandleOwner::~HandleOwner() { // ? + if (m_handle) + HandleData::s_handles[m_handle].RemReference(); +} + +inline void HandleOwner::CreateHandle(void *object) { // line 364 + m_handle = HandleData::Create(object); + HandleData::s_handles[m_handle].AddReference(); +} + +inline HandleOwner::operator HandleData*() const { // line 377 + // can't determine if there should be a null-check here or not + if (m_handle) + return &HandleData::s_handles[m_handle]; + return nullptr; +} + +// ------------------------------------------------------------------------- // + +// inline RCObject::RCObject(); // line 386 + +// inline RCObject::RCObject(RCObject const&); // line 391 + +inline HandleData *RCObject::GetHandleData() { // line 403 + if (!m_handleOwner.IsInitialized()) // line 405 + m_handleOwner.CreateHandle(this); // line 406 + + return (HandleData*)m_handleOwner; +} + +inline uint32_t RCObject::GetRefCount() { // line 410 + // guess + return m_refCount; +} + +inline void RCObject::AddReference() { // line 415 + m_refCount++; +} + +inline void RCObject::RemReference() { // line 426 + if (--m_refCount == 0) + Remove(); +} + +// ------------------------------------------------------------------------- // + +template +inline RCPtr::RCPtr(T *t) : m_object(t) { // line 444 + m_object->AddReference(); +} + +template +inline RCPtr::RCPtr(const RCPtr& other) : m_object(other.Get()) { // line 452 + m_object->AddReference(); +} + +template +inline RCPtr::~RCPtr() { // line 469 + if (m_object) + m_object->RemReference(); // line 479 +} + +template +inline RCPtr& RCPtr::operator=(T* other) const { // line 487 + if (other) + other->AddReference(); // line 502 + if (m_object) + m_object->RemReference(); // line 506 +} + +template +inline RCPtr& RCPtr::operator=(const RCPtr& other) const { // line 512 + *this = other.Get(); +} + +template +inline T* RCPtr::Get() const { return m_object; } // line 525 + +template +inline RCPtr::operator T*() const { return m_object; } // line 531 + +template +inline T *RCPtr::operator->() const { return m_object; } // line 537 + +// ------------------------------------------------------------------------- // + +// template +// inline Handle::Handle(); // line 572 + +template +inline Handle::Handle(T *t) { // line 581 + HandleData *hd = nullptr; + if (t) + hd = static_cast(t)->GetHandleData(); + + m_handle = hd; + if (hd) + hd->AddReference(); +} + +template +inline Handle::~Handle() { // line 589 + if (m_handle) + m_handle->RemReference(); +} + +// template +// inline Handle::Handle(Handle const&); // line 596 + +// template +// inline T& Handle::operator=(Handle const&); // line 604 + +// template +// inline T& Handle::operator=(T const*); // line 615 + +template +inline T *Handle::Get() const { // line 631 + return reinterpret_cast(m_handle->Get()); +} + +template +inline Handle::operator T*() const { // line 647 + // guess + return Get(); +} + +template +inline T *Handle::operator->() const { // line 653 + // guess + return Get(); +} + +template +inline T *Handle::operator*() const { // line 660 + // guess + return Get(); +} + +}