From b6c5232feac33499640a0959f7b5ee17800b3710 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 20 Oct 2022 16:48:18 +0200 Subject: [PATCH] - try to keep the engine stable for as long as possible if a VM exception occurs in OnDestroy while running a cleanup. This will still crash, but run long enough for the exception message to be visible. --- src/g_game.cpp | 2 +- src/g_levellocals.h | 2 +- src/p_setup.cpp | 8 ++++---- src/p_setup.h | 2 +- src/playsim/dthinker.cpp | 7 ++++--- src/playsim/dthinker.h | 2 +- 6 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/g_game.cpp b/src/g_game.cpp index 8a4db9c3fa..29884c7c16 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -1069,7 +1069,7 @@ static void G_FullConsole() primaryLevel->Music = ""; S_Start(); S_StopMusic(true); - P_FreeLevelData(); + P_FreeLevelData(false); } } diff --git a/src/g_levellocals.h b/src/g_levellocals.h index 9953a3e7de..65748470a8 100644 --- a/src/g_levellocals.h +++ b/src/g_levellocals.h @@ -130,7 +130,7 @@ struct FLevelLocals void AddScroller(int secnum); void SetInterMusic(const char *nextmap); void SetMusicVolume(float v); - void ClearLevelData(); + void ClearLevelData(bool fullgc = true); void ClearPortals(); bool CheckIfExitIsGood(AActor *self, level_info_t *newmap); void FormatMapName(FString &mapname, const char *mapnamecolor); diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 5ddef48b37..c8ac1c52e0 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -279,7 +279,7 @@ void FLevelLocals::ClearPortals() // //========================================================================== -void FLevelLocals::ClearLevelData() +void FLevelLocals::ClearLevelData(bool fullgc) { { auto it = GetThinkerIterator(NAME_None, STAT_TRAVELLING); @@ -291,7 +291,7 @@ void FLevelLocals::ClearLevelData() } interpolator.ClearInterpolations(); // [RH] Nothing to interpolate on a fresh level. - Thinkers.DestroyAllThinkers(); + Thinkers.DestroyAllThinkers(fullgc); ClearAllSubsectorLinks(); // can't be done as part of the polyobj deletion process. total_monsters = total_items = total_secrets = @@ -383,13 +383,13 @@ void FLevelLocals::ClearLevelData() // //========================================================================== -void P_FreeLevelData () +void P_FreeLevelData (bool fullgc) { R_FreePastViewers(); for (auto Level : AllLevels()) { - Level->ClearLevelData(); + Level->ClearLevelData(fullgc); } // primaryLevel->FreeSecondaryLevels(); } diff --git a/src/p_setup.h b/src/p_setup.h index 30248e90ab..27c646b5b9 100644 --- a/src/p_setup.h +++ b/src/p_setup.h @@ -143,7 +143,7 @@ bool P_CheckMapData(const char * mapname); void P_SetupLevel (FLevelLocals *Level, int position, bool newGame); void P_LoadLightmap(MapData *map); -void P_FreeLevelData(); +void P_FreeLevelData(bool fullgc = true); // Called by startup code. void P_Init (void); diff --git a/src/playsim/dthinker.cpp b/src/playsim/dthinker.cpp index 1e794dad79..e35304fb80 100644 --- a/src/playsim/dthinker.cpp +++ b/src/playsim/dthinker.cpp @@ -271,7 +271,7 @@ void FThinkerCollection::RunThinkers(FLevelLocals *Level) // //========================================================================== -void FThinkerCollection::DestroyAllThinkers() +void FThinkerCollection::DestroyAllThinkers(bool fullgc) { int i; bool error = false; @@ -285,11 +285,12 @@ void FThinkerCollection::DestroyAllThinkers() } } error |= Thinkers[MAX_STATNUM + 1].DoDestroyThinkers(); - GC::FullGC(); + if (fullgc) GC::FullGC(); if (error) { ClearGlobalVMStack(); - I_Error("DestroyAllThinkers failed"); + if (fullgc) I_Error("DestroyAllThinkers failed"); + else I_FatalError("DestroyAllThinkers failed"); } } diff --git a/src/playsim/dthinker.h b/src/playsim/dthinker.h index 680afbc9a4..78dcd1520b 100644 --- a/src/playsim/dthinker.h +++ b/src/playsim/dthinker.h @@ -79,7 +79,7 @@ struct FThinkerCollection } void RunThinkers(FLevelLocals *Level); // The level is needed to tick the lights - void DestroyAllThinkers(); + void DestroyAllThinkers(bool fullgc = true); void SerializeThinkers(FSerializer &arc, bool keepPlayers); void MarkRoots(); DThinker *FirstThinker(int statnum);