| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 |
- #include "Base.h"
- #include "Ref.h"
- #include "Game.h"
- namespace gameplay
- {
- #ifdef GAMEPLAY_MEM_LEAK_DETECTION
- void* trackRef(Ref* ref);
- void untrackRef(Ref* ref, void* record);
- #endif
- Ref::Ref() :
- _refCount(1)
- {
- #ifdef GAMEPLAY_MEM_LEAK_DETECTION
- __record = trackRef(this);
- #endif
- }
- Ref::Ref(const Ref& copy) :
- _refCount(1)
- {
- #ifdef GAMEPLAY_MEM_LEAK_DETECTION
- __record = trackRef(this);
- #endif
- }
- Ref::~Ref()
- {
- }
- void Ref::addRef()
- {
- ++_refCount;
- }
- void Ref::release()
- {
- if ((--_refCount) <= 0)
- {
- #ifdef GAMEPLAY_MEM_LEAK_DETECTION
- untrackRef(this, __record);
- #endif
- delete this;
- }
- }
- unsigned int Ref::getRefCount() const
- {
- return _refCount;
- }
- #ifdef GAMEPLAY_MEM_LEAK_DETECTION
- struct RefAllocationRecord
- {
- Ref* ref;
- RefAllocationRecord* next;
- RefAllocationRecord* prev;
- };
- RefAllocationRecord* __refAllocations = 0;
- int __refAllocationCount = 0;
- void Ref::printLeaks()
- {
- // Dump Ref object memory leaks
- if (__refAllocationCount == 0)
- {
- printError("[memory] All Ref objects successfully cleaned up (no leaks detected).\n");
- }
- else
- {
- printError("[memory] WARNING: %d Ref objects still active in memory.\n", __refAllocationCount);
- for (RefAllocationRecord* rec = __refAllocations; rec != NULL; rec = rec->next)
- {
- Ref* ref = rec->ref;
- const char* type = typeid(*ref).name();
- printError("[memory] LEAK: Ref object '%s' still active with reference count %d.\n", (type ? type : ""), ref->getRefCount());
- }
- }
- }
- void* trackRef(Ref* ref)
- {
- // Create memory allocation record
- RefAllocationRecord* rec = (RefAllocationRecord*)malloc(sizeof(RefAllocationRecord));
- rec->ref = ref;
- rec->next = __refAllocations;
- rec->prev = 0;
- if (__refAllocations)
- __refAllocations->prev = rec;
- __refAllocations = rec;
- ++__refAllocationCount;
- return rec;
- }
- void untrackRef(Ref* ref, void* record)
- {
- RefAllocationRecord* rec = (RefAllocationRecord*)record;
- if (rec->ref != ref)
- {
- printError("[memory] CORRUPTION: Attempting to free Ref with invalid ref tracking record.\n");
- return;
- }
- // Link this item out
- if (__refAllocations == rec)
- __refAllocations = rec->next;
- if (rec->prev)
- rec->prev->next = rec->next;
- if (rec->next)
- rec->next->prev = rec->prev;
- free((void*)rec);
- --__refAllocationCount;
- }
- #endif
- }
|