- 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.
This commit is contained in:
Christoph Oelckers 2022-10-20 16:48:18 +02:00
parent 936e89e3d4
commit b6c5232fea
6 changed files with 12 additions and 11 deletions

View file

@ -1069,7 +1069,7 @@ static void G_FullConsole()
primaryLevel->Music = "";
S_Start();
S_StopMusic(true);
P_FreeLevelData();
P_FreeLevelData(false);
}
}

View file

@ -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);

View file

@ -279,7 +279,7 @@ void FLevelLocals::ClearPortals()
//
//==========================================================================
void FLevelLocals::ClearLevelData()
void FLevelLocals::ClearLevelData(bool fullgc)
{
{
auto it = GetThinkerIterator<AActor>(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();
}

View file

@ -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);

View file

@ -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");
}
}

View file

@ -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);