From 5b22de1e8f0c018728d368b267344de0b8b96a70 Mon Sep 17 00:00:00 2001 From: Edo Date: Sat, 28 Jan 2023 12:31:48 +0000 Subject: [PATCH] [Menus]: Cure my memory drip *gone right* (#740) --- src/Components/Modules/Menus.cpp | 74 +++++++++++++++++++------------- src/Components/Modules/Menus.hpp | 4 +- src/Game/Functions.cpp | 2 + src/Game/Functions.hpp | 4 ++ 4 files changed, 53 insertions(+), 31 deletions(-) diff --git a/src/Components/Modules/Menus.cpp b/src/Components/Modules/Menus.cpp index d0dfa97f..7119a712 100644 --- a/src/Components/Modules/Menus.cpp +++ b/src/Components/Modules/Menus.cpp @@ -1,6 +1,9 @@ #include #include "Party.hpp" +#define MAX_SOURCEFILES 64 +#define DEFINEHASHSIZE 1024 + namespace Components { std::vector Menus::CustomMenus; @@ -35,15 +38,21 @@ namespace Components int Menus::ReserveSourceHandle() { // Check if a free slot is available - int i = 1; - for (; i < MAX_SOURCEFILES; ++i) + auto i = 1; + while (i < MAX_SOURCEFILES) { if (!Game::sourceFiles[i]) + { break; + } + + ++i; } if (i >= MAX_SOURCEFILES) + { return 0; + } // Reserve it, if yes Game::sourceFiles[i] = reinterpret_cast(1); @@ -81,37 +90,28 @@ namespace Components int Menus::LoadMenuSource(const std::string& name, const std::string& buffer) { - Utils::Memory::Allocator* allocator = Utils::Memory::GetAllocator(); - const auto handle = ReserveSourceHandle(); if (!IsValidSourceHandle(handle)) return 0; // No free source slot! auto* script = LoadMenuScript(name, buffer); - if (!script) { Game::sourceFiles[handle] = nullptr; // Free reserved slot return 0; } - auto* source = allocator->allocate(); - if (!source) - { - Game::FreeMemory(script); - return 0; - } - + auto* source = static_cast(Game::GetMemory(sizeof(Game::source_s))); std::memset(source, 0, sizeof(Game::source_s)); script->next = nullptr; - strncpy_s(source->filename, "string", _TRUNCATE); + strncpy_s(source->filename, name.data(), _TRUNCATE); source->scriptstack = script; source->tokens = nullptr; source->defines = nullptr; source->indentstack = nullptr; source->skip = 0; - source->definehash = static_cast(Game::GetClearedMemory(1024 * sizeof(Game::define_s*))); + source->definehash = static_cast(Game::GetClearedMemory(DEFINEHASHSIZE * sizeof(Game::define_s*))); Game::sourceFiles[handle] = source; @@ -434,7 +434,7 @@ namespace Components } newList->name = allocator->duplicateString(menuList->name); - newList->menuCount = size; + newList->menuCount = static_cast(size); // Copy new menus for (unsigned int i = 0; i < menus.size(); ++i) @@ -448,45 +448,61 @@ namespace Components return newList; } + void Menus::FreeScript(Game::script_s* script) + { + if (script->punctuationtable) + { + Game::FreeMemory(script->punctuationtable); + } + + Game::FreeMemory(script); + } + void Menus::FreeMenuSource(int handle) { - Utils::Memory::Allocator* allocator = Utils::Memory::GetAllocator(); - if (!IsValidSourceHandle(handle)) return; - Game::source_t* source = Game::sourceFiles[handle]; + auto* source = Game::sourceFiles[handle]; while (source->scriptstack) { - Game::script_t* script = source->scriptstack; + auto* script = source->scriptstack; source->scriptstack = source->scriptstack->next; - Game::FreeMemory(script); + FreeScript(script); } while (source->tokens) { - Game::token_t* token = source->tokens; + auto* token = source->tokens; source->tokens = source->tokens->next; + Game::FreeMemory(token); + --*Game::numtokens; } - while (source->defines) + for (auto i = 0; i < DEFINEHASHSIZE; ++i) { - Game::define_t* define = source->defines; - source->defines = source->defines->next; - Game::FreeMemory(define); + while (source->definehash[i]) + { + auto* define = source->definehash[i]; + source->definehash[i] = source->definehash[i]->hashnext; + Game::PC_FreeDefine(define); + } } while (source->indentstack) { - Game::indent_t* indent = source->indentstack; + auto* indent = source->indentstack; source->indentstack = source->indentstack->next; - allocator->free(indent); + Game::FreeMemory(indent); } - if (source->definehash) allocator->free(source->definehash); + if (source->definehash) + { + Game::FreeMemory(source->definehash); + } - allocator->free(source); + Game::FreeMemory(source); Game::sourceFiles[handle] = nullptr; } diff --git a/src/Components/Modules/Menus.hpp b/src/Components/Modules/Menus.hpp index 45ff1639..ecf7afdd 100644 --- a/src/Components/Modules/Menus.hpp +++ b/src/Components/Modules/Menus.hpp @@ -1,6 +1,5 @@ #pragma once -#define MAX_SOURCEFILES 64 #undef LoadMenu namespace Components @@ -17,7 +16,7 @@ namespace Components static Game::MenuList* LoadCustomMenuList(const std::string& menu, Utils::Memory::Allocator* allocator); static std::vector> LoadMenu(Game::menuDef_t* menudef); - static std::vector> LoadMenu(const std::string& file); + static std::vector> LoadMenu(const std::string& menu); private: static std::unordered_map MenuList; @@ -40,6 +39,7 @@ namespace Components static Game::menuDef_t* ParseMenu(int handle); + static void FreeScript(Game::script_s* script); static void FreeMenuSource(int handle); static void FreeMenuList(Game::MenuList* menuList); diff --git a/src/Game/Functions.cpp b/src/Game/Functions.cpp index fecd3d34..bd97f394 100644 --- a/src/Game/Functions.cpp +++ b/src/Game/Functions.cpp @@ -130,6 +130,7 @@ namespace Game Scr_AddSourceBuffer_t Scr_AddSourceBuffer = Scr_AddSourceBuffer_t(0x61ABC0); + PC_FreeDefine_t PC_FreeDefine = PC_FreeDefine_t(0x4E0D60); PC_ReadToken_t PC_ReadToken = PC_ReadToken_t(0x4ACCD0); PC_ReadTokenHandle_t PC_ReadTokenHandle = PC_ReadTokenHandle_t(0x4D2060); PC_SourceError_t PC_SourceError = PC_SourceError_t(0x467A00); @@ -392,6 +393,7 @@ namespace Game int* ui_arenaBufPos = reinterpret_cast(0x62D278C); punctuation_s* default_punctuations = reinterpret_cast(0x797F80); + int* numtokens = reinterpret_cast(0x7C4BA0); bool* s_havePlaylists = reinterpret_cast(0x1AD3680); diff --git a/src/Game/Functions.hpp b/src/Game/Functions.hpp index c88aa549..4081eafe 100644 --- a/src/Game/Functions.hpp +++ b/src/Game/Functions.hpp @@ -320,6 +320,9 @@ namespace Game typedef char*(*Scr_AddSourceBuffer_t)(const char* filename, const char* extFilename, const char* codePos, bool archive); extern Scr_AddSourceBuffer_t Scr_AddSourceBuffer; + typedef void(*PC_FreeDefine_t)(define_s* define); + extern PC_FreeDefine_t PC_FreeDefine; + typedef int(*PC_ReadToken_t)(source_t*, token_t*); extern PC_ReadToken_t PC_ReadToken; @@ -736,6 +739,7 @@ namespace Game extern int* ui_arenaBufPos; extern punctuation_s* default_punctuations; + extern int* numtokens; extern bool* s_havePlaylists;