diff --git a/src/common/objects/dobjgc.cpp b/src/common/objects/dobjgc.cpp index de4614664..40b29a680 100644 --- a/src/common/objects/dobjgc.cpp +++ b/src/common/objects/dobjgc.cpp @@ -58,21 +58,9 @@ #include "dobject.h" #include "templates.h" -#include "b_bot.h" -#include "p_local.h" -#include "g_game.h" -#include "a_sharedglobal.h" -#include "sbar.h" #include "c_dispatch.h" -#include "s_sndseq.h" -#include "r_data/r_interpolate.h" -#include "doomstat.h" -#include "po_man.h" -#include "r_utility.h" #include "menu/menu.h" -#include "intermission/intermission.h" -#include "g_levellocals.h" -#include "events.h" +#include "stats.h" // MACROS ------------------------------------------------------------------ @@ -112,8 +100,6 @@ // EXTERNAL DATA DECLARATIONS ---------------------------------------------- -extern DThinker *NextToThink; - // PUBLIC DATA DEFINITIONS ------------------------------------------------- namespace GC @@ -274,26 +260,19 @@ void MarkArray(DObject **obj, size_t count) // //========================================================================== +TArray markers; +void AddMarkerFunc(GCMarkerFunc func) +{ + if (markers.Find(func) == markers.Size()) + markers.Push(func); +} + static void MarkRoot() { Gray = NULL; - Mark(StatusBar); - M_MarkMenus(); - Mark(DIntermissionController::CurrentIntermission); - Mark(staticEventManager.FirstEventHandler); - Mark(staticEventManager.LastEventHandler); - for (auto Level : AllLevels()) - Level->Mark(); - // Mark players. - for (int i = 0; i < MAXPLAYERS; i++) - { - if (playeringame[i]) - players[i].PropagateMark(); - } - - // NextToThink must not be freed while thinkers are ticking. - Mark(NextToThink); + for (auto func : markers) func(); + // Mark soft roots. if (SoftRoots != NULL) { diff --git a/src/common/objects/dobjgc.h b/src/common/objects/dobjgc.h index 5a181c736..de187db6c 100644 --- a/src/common/objects/dobjgc.h +++ b/src/common/objects/dobjgc.h @@ -154,6 +154,10 @@ namespace GC { MarkArray(&arr[0], arr.Size()); } + + using GCMarkerFunc = void(*)(); + void AddMarkerFunc(GCMarkerFunc func); + } // A template class to help with handling read barriers. It does not diff --git a/src/common/scripting/core/types.cpp b/src/common/scripting/core/types.cpp index 5211bc956..d06c08250 100644 --- a/src/common/scripting/core/types.cpp +++ b/src/common/scripting/core/types.cpp @@ -1115,7 +1115,7 @@ void PSpriteID::WriteValue(FSerializer &ar, const char *key, const void *addr) c bool PSpriteID::ReadValue(FSerializer &ar, const char *key, void *addr) const { - int32_t val; + int32_t val = 0; #ifdef GZDOOM ar.Sprite(key, val, nullptr); #endif diff --git a/src/d_main.cpp b/src/d_main.cpp index 69301e295..ee515f689 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -2748,6 +2748,27 @@ static void Doom_CastSpriteIDToString(FString* a, unsigned int b) *a = (b >= sprites.Size()) ? "TNT1" : sprites[b].name; } + +extern DThinker* NextToThink; + +static void GC_MarkGameRoots() +{ + GC::Mark(DIntermissionController::CurrentIntermission); + GC::Mark(staticEventManager.FirstEventHandler); + GC::Mark(staticEventManager.LastEventHandler); + for (auto Level : AllLevels()) + Level->Mark(); + + // Mark players. + for (int i = 0; i < MAXPLAYERS; i++) + { + if (playeringame[i]) + players[i].PropagateMark(); + } + + // NextToThink must not be freed while thinkers are ticking. + GC::Mark(NextToThink); +} //========================================================================== // // D_DoomMain @@ -2764,6 +2785,7 @@ static int D_DoomMain_Internal (void) int argcount; FIWadManager *iwad_man; + GC::AddMarkerFunc(GC_MarkGameRoots); VM_CastSpriteIDToString = Doom_CastSpriteIDToString; // Set up the button list. Mlook and Klook need a bit of extra treatment. diff --git a/src/g_statusbar/shared_sbar.cpp b/src/g_statusbar/shared_sbar.cpp index e294c716a..a8487c349 100644 --- a/src/g_statusbar/shared_sbar.cpp +++ b/src/g_statusbar/shared_sbar.cpp @@ -259,6 +259,7 @@ void ST_CreateStatusBar(bool bTitleLevel) StatusBar->Destroy(); StatusBar = NULL; } + GC::AddMarkerFunc([]() { GC::Mark(StatusBar); }); bool shouldWarn = true; diff --git a/src/menu/menu.cpp b/src/menu/menu.cpp index 5f354d934..13cb0d956 100644 --- a/src/menu/menu.cpp +++ b/src/menu/menu.cpp @@ -952,6 +952,7 @@ void M_Init (void) try { M_ParseMenuDefs(); + GC::AddMarkerFunc(M_MarkMenus); } catch (CVMAbortException &err) {