From 9506b0e33755c6c7352c2400ec54b3552c85578e Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 10 Jan 2019 02:00:58 +0100 Subject: [PATCH] - moved the SectorMarker handling into the level itself. --- src/dobjgc.cpp | 109 ++---------------------------------------- src/g_level.cpp | 112 ++++++++++++++++++++++++++++++++++++++++++++ src/g_levellocals.h | 2 + 3 files changed, 118 insertions(+), 105 deletions(-) diff --git a/src/dobjgc.cpp b/src/dobjgc.cpp index 36a8eea9aa..d36df576da 100644 --- a/src/dobjgc.cpp +++ b/src/dobjgc.cpp @@ -96,9 +96,6 @@ #define DEFAULT_GCMUL 400 // GC runs 'quadruple the speed' of memory allocation // Number of sectors to mark for each step. -#define SECTORSTEPSIZE 32 -#define POLYSTEPSIZE 120 -#define SIDEDEFSTEPSIZE 240 #define GCSTEPSIZE 1024u #define GCSWEEPMAX 40 @@ -107,22 +104,6 @@ // TYPES ------------------------------------------------------------------- -// This object is responsible for marking sectors during the propagate -// stage. In case there are many, many sectors, it lets us break them -// up instead of marking them all at once. -class DSectorMarker : public DObject -{ - DECLARE_CLASS(DSectorMarker, DObject) -public: - DSectorMarker() : SecNum(0),PolyNum(0),SideNum(0) {} - size_t PropagateMark(); - int SecNum; - int PolyNum; - int SideNum; -}; - -IMPLEMENT_CLASS(DSectorMarker, false, false) - // EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- // PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- @@ -154,8 +135,6 @@ bool FinalGC; // PRIVATE DATA DEFINITIONS ------------------------------------------------ -static DSectorMarker *SectorMarker; - // CODE -------------------------------------------------------------------- //========================================================================== @@ -306,7 +285,6 @@ static void MarkRoot() DThinker::MarkRoots(); Mark(E_FirstEventHandler); Mark(E_LastEventHandler); - level.Mark(); // Mark players. for (i = 0; i < MAXPLAYERS; i++) @@ -315,19 +293,11 @@ static void MarkRoot() players[i].PropagateMark(); } // Mark sectors. - if (SectorMarker == nullptr && level.sectors.Size() > 0) + + ForAllLevels([](FLevelLocals *Level) { - SectorMarker = Create(); - } - else if (level.sectors.Size() == 0) - { - SectorMarker = nullptr; - } - else - { - SectorMarker->SecNum = 0; - } - Mark(SectorMarker); + Level->Mark(); + }); // Mark bot stuff. Mark(bglobal.firstthing); Mark(bglobal.body1); @@ -614,77 +584,6 @@ void DelSoftRoot(DObject *obj) } -//========================================================================== -// -// DSectorMarker :: PropagateMark -// -// Propagates marks across a few sectors and reinserts itself into the -// gray list if it didn't do them all. -// -//========================================================================== - -size_t DSectorMarker::PropagateMark() -{ - int i; - int marked = 0; - bool moretodo = false; - int numsectors = level.sectors.Size(); - - for (i = 0; i < SECTORSTEPSIZE && SecNum + i < numsectors; ++i) - { - sector_t *sec = &level.sectors[SecNum + i]; - GC::Mark(sec->SoundTarget); - GC::Mark(sec->SecActTarget); - GC::Mark(sec->floordata); - GC::Mark(sec->ceilingdata); - GC::Mark(sec->lightingdata); - for(int j=0;j<4;j++) GC::Mark(sec->interpolations[j]); - } - marked += i * sizeof(sector_t); - if (SecNum + i < numsectors) - { - SecNum += i; - moretodo = true; - } - - if (!moretodo && level.Polyobjects.Size() > 0) - { - for (i = 0; i < POLYSTEPSIZE && PolyNum + i < (int)level.Polyobjects.Size(); ++i) - { - GC::Mark(level.Polyobjects[PolyNum + i].interpolation); - } - marked += i * sizeof(FPolyObj); - if (PolyNum + i < (int)level.Polyobjects.Size()) - { - PolyNum += i; - moretodo = true; - } - } - if (!moretodo && level.sides.Size() > 0) - { - for (i = 0; i < SIDEDEFSTEPSIZE && SideNum + i < (int)level.sides.Size(); ++i) - { - side_t *side = &level.sides[SideNum + i]; - for (int j = 0; j < 3; j++) GC::Mark(side->textures[j].interpolation); - } - marked += i * sizeof(side_t); - if (SideNum + i < (int)level.sides.Size()) - { - SideNum += i; - moretodo = true; - } - } - // If there are more sectors to mark, put ourself back into the gray - // list. - if (moretodo) - { - Black2Gray(); - GCNext = GC::Gray; - GC::Gray = this; - } - return marked; -} - //========================================================================== // // STAT gc diff --git a/src/g_level.cpp b/src/g_level.cpp index 0d32c77a8d..a7bad86c8d 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -1973,6 +1973,104 @@ void P_ReadACSDefereds (FSerializer &arc) } +//========================================================================== +// +// This object is responsible for marking sectors during the propagate +// stage. In case there are many, many sectors, it lets us break them +// up instead of marking them all at once. +// +//========================================================================== + +class DSectorMarker : public DObject +{ + enum + { + SECTORSTEPSIZE = 32, + POLYSTEPSIZE = 120, + SIDEDEFSTEPSIZE = 240 + }; + DECLARE_CLASS(DSectorMarker, DObject) +public: + DSectorMarker(FLevelLocals *l) : SecNum(0),PolyNum(0),SideNum(0) {} + size_t PropagateMark(); + FLevelLocals *Level; + int SecNum; + int PolyNum; + int SideNum; +}; + +IMPLEMENT_CLASS(DSectorMarker, true, false) + +//========================================================================== +// +// DSectorMarker :: PropagateMark +// +// Propagates marks across a few sectors and reinserts itself into the +// gray list if it didn't do them all. +// +//========================================================================== + +size_t DSectorMarker::PropagateMark() +{ + int i; + int marked = 0; + bool moretodo = false; + int numsectors = Level->sectors.Size(); + + for (i = 0; i < SECTORSTEPSIZE && SecNum + i < numsectors; ++i) + { + sector_t *sec = &Level->sectors[SecNum + i]; + GC::Mark(sec->SoundTarget); + GC::Mark(sec->SecActTarget); + GC::Mark(sec->floordata); + GC::Mark(sec->ceilingdata); + GC::Mark(sec->lightingdata); + for(int j = 0; j < 4; j++) GC::Mark(sec->interpolations[j]); + } + marked += i * sizeof(sector_t); + if (SecNum + i < numsectors) + { + SecNum += i; + moretodo = true; + } + + if (!moretodo && Level->Polyobjects.Size() > 0) + { + for (i = 0; i < POLYSTEPSIZE && PolyNum + i < (int)Level->Polyobjects.Size(); ++i) + { + GC::Mark(Level->Polyobjects[PolyNum + i].interpolation); + } + marked += i * sizeof(FPolyObj); + if (PolyNum + i < (int)Level->Polyobjects.Size()) + { + PolyNum += i; + moretodo = true; + } + } + if (!moretodo && Level->sides.Size() > 0) + { + for (i = 0; i < SIDEDEFSTEPSIZE && SideNum + i < (int)Level->sides.Size(); ++i) + { + side_t *side = &Level->sides[SideNum + i]; + for (int j = 0; j < 3; j++) GC::Mark(side->textures[j].interpolation); + } + marked += i * sizeof(side_t); + if (SideNum + i < (int)Level->sides.Size()) + { + SideNum += i; + moretodo = true; + } + } + // If there are more items to mark, put ourself back into the gray list. + if (moretodo) + { + Black2Gray(); + GCNext = GC::Gray; + GC::Gray = this; + } + return marked; +} + //========================================================================== // // @@ -1980,6 +2078,20 @@ void P_ReadACSDefereds (FSerializer &arc) void FLevelLocals::Mark() { + if (SectorMarker == nullptr && (sectors.Size() > 0 || Polyobjects.Size() > 0 || sides.Size() > 0)) + { + SectorMarker = Create(this); + } + else if (sectors.Size() == 0 && Polyobjects.Size() == 0 && sides.Size() == 0) + { + SectorMarker = nullptr; + } + else + { + SectorMarker->SecNum = 0; + } + + GC::Mark(SectorMarker); GC::Mark(SpotState); GC::Mark(FraggleScriptThinker); GC::Mark(ACSThinker); diff --git a/src/g_levellocals.h b/src/g_levellocals.h index 866e033efd..9dad8d01c4 100644 --- a/src/g_levellocals.h +++ b/src/g_levellocals.h @@ -56,6 +56,7 @@ class DFraggleThinker; class DSpotState; class DSeqNode; struct FStrifeDialogueNode; +class DSectorMarker; typedef TMap FDialogueIDMap; // maps dialogue IDs to dialogue array index (for ACS) typedef TMap FDialogueMap; // maps actor class names to dialogue array index @@ -154,6 +155,7 @@ struct FLevelLocals : public FLevelData memset(TIDHash, 0, sizeof(TIDHash)); } + DSectorMarker *SectorMarker; uint8_t md5[16]; // for savegame validation. If the MD5 does not match the savegame won't be loaded. int time; // time in the hub