#ifndef D_HEAP_ALLOC #define D_HEAP_ALLOC #include "egg/core/eggHeap.h" class dHeapAllocatorBase { public: /* vtable at 0x00 */ dHeapAllocatorBase() : mCallbacksInitialized(0), mPreviousAllocCallback(nullptr), mPreviousAllocCallbackArg(nullptr), mPreviousFreeCallback(nullptr), mPreviousFreeCallbackArg(nullptr) {} inline void doInitCallbacks() { if (!mCallbacksInitialized) { mCallbacksInitialized = 1; EGG::Heap::AllocCallbackBundle prev = EGG::Heap::setAllocCallback(&allocCallback, this); mPreviousAllocCallback = prev.AllocCallback; mPreviousAllocCallbackArg = prev.AllocCallbackArg; EGG::Heap::FreeCallbackBundle prev2 = EGG::Heap::setFreeCallback(&freeCallback, this); mPreviousFreeCallback = prev2.FreeCallback; mPreviousFreeCallbackArg = prev2.FreeCallbackArg; } } static void allocCallback(EGG::HeapAllocArg *arg) { dHeapAllocatorBase *allocator = (dHeapAllocatorBase *)(arg->userArg); allocator->onAlloc(arg); if (allocator->mPreviousAllocCallback) { EGG::HeapAllocArg chainArg = *arg; chainArg.userArg = allocator->mPreviousAllocCallbackArg; (allocator->mPreviousAllocCallback)(&chainArg); } }; static void freeCallback(EGG::HeapFreeArg *arg) { dHeapAllocatorBase *allocator = (dHeapAllocatorBase *)(arg->userArg); EGG::HeapFreeArg chainArg; allocator->onFree(arg); if (allocator->mPreviousFreeCallback) { chainArg = *arg; chainArg.userArg = allocator->mPreviousFreeCallbackArg; (allocator->mPreviousFreeCallback)(&chainArg); } } virtual ~dHeapAllocatorBase() {} virtual void onAlloc(EGG::HeapAllocArg *arg){}; virtual void onFree(EGG::HeapFreeArg *arg){}; /* 0x04 */ bool mCallbacksInitialized; /* 0x08 */ EGG::HeapAllocCallback mPreviousAllocCallback; /* 0x0C */ void *mPreviousAllocCallbackArg; /* 0x10 */ EGG::HeapFreeCallback mPreviousFreeCallback; /* 0x14 */ void *mPreviousFreeCallbackArg; }; void *operator new(size_t size); void *operator new[](size_t size); void operator delete(void *ptr); void operator delete[](void *ptr); class dHeapAllocator : public dHeapAllocatorBase { public: dHeapAllocator() {} virtual ~dHeapAllocator() {} virtual void onAlloc(EGG::HeapAllocArg *arg); static void initCallbacks(); static dHeapAllocator sAllocator; }; #endif