diff --git a/src/app/core/platform/memory_tracker.h b/src/app/core/platform/memory_tracker.h new file mode 100644 index 00000000..281626df --- /dev/null +++ b/src/app/core/platform/memory_tracker.h @@ -0,0 +1,78 @@ +#ifndef YAZE_APP_CORE_PLATFORM_MEMORY_TRACKER_H +#define YAZE_APP_CORE_PLATFORM_MEMORY_TRACKER_H + +#include + +#include +#include +#include +#include + +namespace yaze { +namespace core { + +class MemoryTracker { + public: + static MemoryTracker& GetInstance() { + static MemoryTracker instance; + return instance; + } + + void TrackAllocation(const void* ptr, size_t size, const char* type) { + std::lock_guard lock(mutex_); + allocations_[ptr] = {size, type}; + total_allocated_ += size; + } + + void TrackDeallocation(const void* ptr) { + std::lock_guard lock(mutex_); + auto it = allocations_.find(ptr); + if (it != allocations_.end()) { + total_allocated_ -= it->second.size; + allocations_.erase(it); + } + } + + size_t GetTotalAllocated() const { + std::lock_guard lock(mutex_); + return total_allocated_; + } + + void DumpAllocations() const { + std::lock_guard lock(mutex_); + SDL_Log("Memory allocations: %zu bytes in %zu allocations", + total_allocated_, allocations_.size()); + + std::unordered_map type_counts; + for (const auto& pair : allocations_) { + type_counts[pair.second.type] += pair.second.size; + } + + for (const auto& pair : type_counts) { + SDL_Log(" %s: %zu bytes", pair.first.c_str(), pair.second); + } + } + + // Check if the memory was freed by another reference + bool IsFreed(const void* ptr) const { + std::lock_guard lock(mutex_); + return allocations_.find(ptr) == allocations_.end(); + } + + private: + MemoryTracker() = default; + + struct AllocationInfo { + size_t size; + const char* type; + }; + + std::unordered_map allocations_; + size_t total_allocated_ = 0; + mutable std::mutex mutex_; +}; + +} // namespace core +} // namespace yaze + +#endif // YAZE_APP_CORE_PLATFORM_MEMORY_TRACKER_H diff --git a/src/app/core/platform/sdl_deleter.h b/src/app/core/platform/sdl_deleter.h index fb0f7383..34ec9798 100644 --- a/src/app/core/platform/sdl_deleter.h +++ b/src/app/core/platform/sdl_deleter.h @@ -3,6 +3,8 @@ #include +#include "app/core/platform/memory_tracker.h" + namespace yaze { namespace core { @@ -10,22 +12,28 @@ namespace core { * @brief Deleter for SDL_Window and SDL_Renderer. */ struct SDL_Deleter { - void operator()(SDL_Window *p) const { SDL_DestroyWindow(p); } - void operator()(SDL_Renderer *p) const { SDL_DestroyRenderer(p); } + void operator()(SDL_Window* p) const { SDL_DestroyWindow(p); } + void operator()(SDL_Renderer* p) const { SDL_DestroyRenderer(p); } }; -/** - * @brief Deleter for SDL_Texture. - */ -struct SDL_Texture_Deleter { - void operator()(SDL_Texture *p) const { SDL_DestroyTexture(p); } -}; - -/** - * @brief Deleter for SDL_Surface. - */ +// Custom deleter for SDL_Surface struct SDL_Surface_Deleter { - void operator()(SDL_Surface *p) const { SDL_FreeSurface(p); } + void operator()(SDL_Surface* p) const { + if (p && !MemoryTracker::GetInstance().IsFreed(p)) { + MemoryTracker::GetInstance().TrackDeallocation(p); + SDL_FreeSurface(p); + } + } +}; + +// Custom deleter for SDL_Texture +struct SDL_Texture_Deleter { + void operator()(SDL_Texture* p) const { + if (p && !MemoryTracker::GetInstance().IsFreed(p)) { + MemoryTracker::GetInstance().TrackDeallocation(p); + SDL_DestroyTexture(p); + } + } }; } // namespace core