Permalink
Browse files

- moved the SectorMarker handling into the level itself.

  • Loading branch information...
coelckers committed Jan 10, 2019
1 parent 8cc563b commit 9506b0e33755c6c7352c2400ec54b3552c85578e
Showing with 118 additions and 105 deletions.
  1. +4 −105 src/dobjgc.cpp
  2. +112 −0 src/g_level.cpp
  3. +2 −0 src/g_levellocals.h
@@ -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)
{
SectorMarker = Create<DSectorMarker>();
}
else if (level.sectors.Size() == 0)

ForAllLevels([](FLevelLocals *Level)
{
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
@@ -1973,13 +1973,125 @@ 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;
}

//==========================================================================
//
//
//==========================================================================

void FLevelLocals::Mark()
{
if (SectorMarker == nullptr && (sectors.Size() > 0 || Polyobjects.Size() > 0 || sides.Size() > 0))
{
SectorMarker = Create<DSectorMarker>(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);
@@ -56,6 +56,7 @@ class DFraggleThinker;
class DSpotState;
class DSeqNode;
struct FStrifeDialogueNode;
class DSectorMarker;

typedef TMap<int, int> FDialogueIDMap; // maps dialogue IDs to dialogue array index (for ACS)
typedef TMap<FName, int> 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

0 comments on commit 9506b0e

Please sign in to comment.