From 556b2deef29a5f05fbbbe555ac1e732461d7c74f Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Fri, 18 Jul 2025 14:34:23 -0700 Subject: [PATCH] Fix `ViewLODList` leaks (#623) * Fix ViewLODList leaks * Add vector clear * Fix naming --- LEGO1/lego/legoomni/include/legopartpresenter.h | 12 ++++++++++++ .../lego/legoomni/src/entity/legoworldpresenter.cpp | 8 ++++++-- LEGO1/lego/legoomni/src/main/legomain.cpp | 2 ++ LEGO1/lego/legoomni/src/video/legopartpresenter.cpp | 4 ++++ 4 files changed, 24 insertions(+), 2 deletions(-) diff --git a/LEGO1/lego/legoomni/include/legopartpresenter.h b/LEGO1/lego/legoomni/include/legopartpresenter.h index 7ff7692d..3c3fc2f1 100644 --- a/LEGO1/lego/legoomni/include/legopartpresenter.h +++ b/LEGO1/lego/legoomni/include/legopartpresenter.h @@ -4,6 +4,7 @@ #include "lego1_export.h" #include "legonamedpartlist.h" #include "mxmediapresenter.h" +#include "viewmanager/viewlodlist.h" // VTABLE: LEGO1 0x100d4df0 // SIZE 0x54 @@ -50,10 +51,21 @@ class LegoPartPresenter : public MxMediaPresenter { MxResult Read(MxDSChunk& p_chunk); void Store(); + static void Release() + { + for (auto* lodList : g_lodLists) { + lodList->Release(); + } + + g_lodLists.clear(); + } + private: void Destroy(MxBool p_fromDestructor); LegoNamedPartList* m_parts; // 0x50 + + static vector g_lodLists; }; #endif // LEGOPARTPRESENTER_H diff --git a/LEGO1/lego/legoomni/src/entity/legoworldpresenter.cpp b/LEGO1/lego/legoomni/src/entity/legoworldpresenter.cpp index b3cfc365..abf6c32a 100644 --- a/LEGO1/lego/legoomni/src/entity/legoworldpresenter.cpp +++ b/LEGO1/lego/legoomni/src/entity/legoworldpresenter.cpp @@ -260,8 +260,12 @@ MxResult LegoWorldPresenter::LoadWorld(char* p_worldName, LegoWorld* p_world) ModelDbPart* part; while (cursor.Next(part)) { - if (GetViewLODListManager()->Lookup(part->m_roiName.GetData()) == NULL && - LoadWorldPart(*part, wdbFile) != SUCCESS) { + ViewLODList* lodList = GetViewLODListManager()->Lookup(part->m_roiName.GetData()); + if (lodList) { + lodList->Release(); + } + + if (lodList == NULL && LoadWorldPart(*part, wdbFile) != SUCCESS) { return FAILURE; } } diff --git a/LEGO1/lego/legoomni/src/main/legomain.cpp b/LEGO1/lego/legoomni/src/main/legomain.cpp index 0c515a1d..78ddf033 100644 --- a/LEGO1/lego/legoomni/src/main/legomain.cpp +++ b/LEGO1/lego/legoomni/src/main/legomain.cpp @@ -122,6 +122,8 @@ void LegoOmni::Destroy() m_textureContainer = NULL; } + LegoPartPresenter::Release(); + if (m_viewLODListManager) { delete m_viewLODListManager; m_viewLODListManager = NULL; diff --git a/LEGO1/lego/legoomni/src/video/legopartpresenter.cpp b/LEGO1/lego/legoomni/src/video/legopartpresenter.cpp index 4849e747..8686cb17 100644 --- a/LEGO1/lego/legoomni/src/video/legopartpresenter.cpp +++ b/LEGO1/lego/legoomni/src/video/legopartpresenter.cpp @@ -22,6 +22,8 @@ MxS32 g_partPresenterConfig1 = 1; // GLOBAL: LEGO1 0x100f7aa4 MxS32 g_partPresenterConfig2 = 100; +vector LegoPartPresenter::g_lodLists; + // FUNCTION: LEGO1 0x1007c990 void LegoPartPresenter::configureLegoPartPresenter(MxS32 p_partPresenterConfig1, MxS32 p_partPresenterConfig2) { @@ -261,6 +263,8 @@ void LegoPartPresenter::Store() lodCursor.Detach(); lodList->PushBack(lod); } + + g_lodLists.push_back(lodList); } else { lodList->Release();