mirror of
https://github.com/ZDoom/qzdoom.git
synced 2025-02-28 14:51:23 +00:00
- refactored the thinker list.
This was an unorganized set of static members in DThinker but has now been regrouped into something more structured.
This commit is contained in:
parent
e30f116faf
commit
3b4ded5694
11 changed files with 543 additions and 505 deletions
|
@ -2724,7 +2724,7 @@ void D_DoomMain (void)
|
||||||
// clean up game state
|
// clean up game state
|
||||||
ST_Clear();
|
ST_Clear();
|
||||||
D_ErrorCleanup ();
|
D_ErrorCleanup ();
|
||||||
DThinker::DestroyThinkersInList(STAT_STATIC);
|
Thinkers.DestroyThinkersInList(STAT_STATIC);
|
||||||
E_Shutdown(false);
|
E_Shutdown(false);
|
||||||
P_FreeLevelData();
|
P_FreeLevelData();
|
||||||
|
|
||||||
|
|
|
@ -112,8 +112,6 @@
|
||||||
|
|
||||||
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
|
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
|
||||||
|
|
||||||
extern DThinker *NextToThink;
|
|
||||||
|
|
||||||
// PUBLIC DATA DEFINITIONS -------------------------------------------------
|
// PUBLIC DATA DEFINITIONS -------------------------------------------------
|
||||||
|
|
||||||
namespace GC
|
namespace GC
|
||||||
|
@ -282,7 +280,6 @@ static void MarkRoot()
|
||||||
Mark(StatusBar);
|
Mark(StatusBar);
|
||||||
M_MarkMenus();
|
M_MarkMenus();
|
||||||
Mark(DIntermissionController::CurrentIntermission);
|
Mark(DIntermissionController::CurrentIntermission);
|
||||||
DThinker::MarkRoots();
|
|
||||||
Mark(E_FirstEventHandler);
|
Mark(E_FirstEventHandler);
|
||||||
Mark(E_LastEventHandler);
|
Mark(E_LastEventHandler);
|
||||||
for (auto Level : AllLevels())
|
for (auto Level : AllLevels())
|
||||||
|
@ -300,8 +297,6 @@ static void MarkRoot()
|
||||||
{
|
{
|
||||||
Level->Mark();
|
Level->Mark();
|
||||||
}
|
}
|
||||||
// NextToThink must not be freed while thinkers are ticking.
|
|
||||||
Mark(NextToThink);
|
|
||||||
// Mark soft roots.
|
// Mark soft roots.
|
||||||
if (SoftRoots != NULL)
|
if (SoftRoots != NULL)
|
||||||
{
|
{
|
||||||
|
|
938
src/dthinker.cpp
938
src/dthinker.cpp
File diff suppressed because it is too large
Load diff
|
@ -53,13 +53,43 @@ enum { MAX_STATNUM = 127 };
|
||||||
// Doubly linked ring list of thinkers
|
// Doubly linked ring list of thinkers
|
||||||
struct FThinkerList
|
struct FThinkerList
|
||||||
{
|
{
|
||||||
FThinkerList() : Sentinel(0) {}
|
// No destructor. If this list goes away it's the GC's task to clean the orphaned thinkers. Otherwise this may clash with engine shutdown.
|
||||||
void AddTail(DThinker *thinker);
|
void AddTail(DThinker *thinker);
|
||||||
DThinker *GetHead() const;
|
DThinker *GetHead() const;
|
||||||
DThinker *GetTail() const;
|
DThinker *GetTail() const;
|
||||||
bool IsEmpty() const;
|
bool IsEmpty() const;
|
||||||
|
void DestroyThinkers();
|
||||||
|
bool DoDestroyThinkers();
|
||||||
|
int TickThinkers(FThinkerList *dest); // Returns: # of thinkers ticked
|
||||||
|
int ProfileThinkers(FThinkerList *dest);
|
||||||
|
void SaveList(FSerializer &arc);
|
||||||
|
|
||||||
DThinker *Sentinel;
|
private:
|
||||||
|
DThinker *Sentinel = nullptr;
|
||||||
|
|
||||||
|
friend struct FThinkerCollection;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FThinkerCollection
|
||||||
|
{
|
||||||
|
void DestroyThinkersInList(int statnum)
|
||||||
|
{
|
||||||
|
Thinkers[statnum].DestroyThinkers();
|
||||||
|
FreshThinkers[statnum].DestroyThinkers();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RunThinkers(FLevelLocals *Level); // The level is needed to tick the lights
|
||||||
|
void DestroyAllThinkers();
|
||||||
|
void SerializeThinkers(FSerializer &arc, bool keepPlayers);
|
||||||
|
void MarkRoots();
|
||||||
|
DThinker *FirstThinker(int statnum);
|
||||||
|
void Link(DThinker *thinker, int statnum);
|
||||||
|
|
||||||
|
private:
|
||||||
|
FThinkerList Thinkers[MAX_STATNUM + 2];
|
||||||
|
FThinkerList FreshThinkers[MAX_STATNUM + 1];
|
||||||
|
|
||||||
|
friend class FThinkerIterator;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DThinker : public DObject
|
class DThinker : public DObject
|
||||||
|
@ -79,29 +109,11 @@ public:
|
||||||
|
|
||||||
void ChangeStatNum (int statnum);
|
void ChangeStatNum (int statnum);
|
||||||
|
|
||||||
static void RunThinkers ();
|
|
||||||
static void RunThinkers (int statnum);
|
|
||||||
static void DestroyAllThinkers ();
|
|
||||||
static void DestroyThinkersInList(int statnum)
|
|
||||||
{
|
|
||||||
DestroyThinkersInList(Thinkers[statnum]);
|
|
||||||
DestroyThinkersInList(FreshThinkers[statnum]);
|
|
||||||
}
|
|
||||||
static void SerializeThinkers(FSerializer &arc, bool keepPlayers);
|
|
||||||
static void MarkRoots();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void DestroyThinkersInList (FThinkerList &list);
|
|
||||||
static bool DoDestroyThinkersInList(FThinkerList &list);
|
|
||||||
static int TickThinkers (FThinkerList *list, FThinkerList *dest); // Returns: # of thinkers ticked
|
|
||||||
static int ProfileThinkers(FThinkerList *list, FThinkerList *dest);
|
|
||||||
static void SaveList(FSerializer &arc, DThinker *node);
|
|
||||||
void Remove();
|
void Remove();
|
||||||
|
|
||||||
static FThinkerList Thinkers[MAX_STATNUM+2]; // Current thinkers
|
|
||||||
static FThinkerList FreshThinkers[MAX_STATNUM+1]; // Newly created thinkers
|
|
||||||
|
|
||||||
friend struct FThinkerList;
|
friend struct FThinkerList;
|
||||||
|
friend struct FThinkerCollection;
|
||||||
friend class FThinkerIterator;
|
friend class FThinkerIterator;
|
||||||
friend class DObject;
|
friend class DObject;
|
||||||
friend class FSerializer;
|
friend class FSerializer;
|
||||||
|
@ -167,4 +179,5 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern FThinkerCollection Thinkers;
|
||||||
#endif //__DTHINKER_H__
|
#endif //__DTHINKER_H__
|
||||||
|
|
|
@ -469,7 +469,7 @@ void G_InitNew (const char *mapname, bool bTitleLevel)
|
||||||
UnlatchCVars ();
|
UnlatchCVars ();
|
||||||
G_VerifySkill();
|
G_VerifySkill();
|
||||||
UnlatchCVars ();
|
UnlatchCVars ();
|
||||||
DThinker::DestroyThinkersInList(STAT_STATIC);
|
Thinkers.DestroyThinkersInList(STAT_STATIC);
|
||||||
|
|
||||||
if (paused)
|
if (paused)
|
||||||
{
|
{
|
||||||
|
@ -1466,7 +1466,7 @@ int FLevelLocals::FinishTravel ()
|
||||||
// make sure that, after travelling has completed, no travelling thinkers are left.
|
// make sure that, after travelling has completed, no travelling thinkers are left.
|
||||||
// Since this list is excluded from regular thinker cleaning, anything that may survive through here
|
// Since this list is excluded from regular thinker cleaning, anything that may survive through here
|
||||||
// will endlessly multiply and severely break the following savegames or just simply crash on broken pointers.
|
// will endlessly multiply and severely break the following savegames or just simply crash on broken pointers.
|
||||||
DThinker::DestroyThinkersInList(STAT_TRAVELLING);
|
Thinkers.DestroyThinkersInList(STAT_TRAVELLING);
|
||||||
return failnum;
|
return failnum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -393,7 +393,7 @@ public:
|
||||||
DThinker *thinker = static_cast<DThinker*>(cls->CreateNew());
|
DThinker *thinker = static_cast<DThinker*>(cls->CreateNew());
|
||||||
assert(thinker->IsKindOf(RUNTIME_CLASS(DThinker)));
|
assert(thinker->IsKindOf(RUNTIME_CLASS(DThinker)));
|
||||||
thinker->ObjectFlags |= OF_JustSpawned;
|
thinker->ObjectFlags |= OF_JustSpawned;
|
||||||
DThinker::FreshThinkers[statnum].AddTail(thinker);
|
Thinkers.Link(thinker, statnum);
|
||||||
thinker->Level = this;
|
thinker->Level = this;
|
||||||
return thinker;
|
return thinker;
|
||||||
}
|
}
|
||||||
|
|
|
@ -295,7 +295,13 @@ void DPusher::Tick ()
|
||||||
|
|
||||||
void FLevelLocals::AdjustPusher(int tag, int magnitude, int angle, bool wind)
|
void FLevelLocals::AdjustPusher(int tag, int magnitude, int angle, bool wind)
|
||||||
{
|
{
|
||||||
DPusher::EPusher type = wind ? DPusher::p_wind : DPusher::p_current;
|
struct FThinkerCollection
|
||||||
|
{
|
||||||
|
int RefNum;
|
||||||
|
DThinker *Obj;
|
||||||
|
};
|
||||||
|
|
||||||
|
DPusher::EPusher type = wind? DPusher::p_wind : DPusher::p_current;
|
||||||
|
|
||||||
// Find pushers already attached to the sector, and change their parameters.
|
// Find pushers already attached to the sector, and change their parameters.
|
||||||
TArray<FThinkerCollection> Collection;
|
TArray<FThinkerCollection> Collection;
|
||||||
|
|
|
@ -928,7 +928,7 @@ void FLevelLocals::Serialize(FSerializer &arc, bool hubload)
|
||||||
|
|
||||||
if (arc.isReading())
|
if (arc.isReading())
|
||||||
{
|
{
|
||||||
DThinker::DestroyAllThinkers();
|
Thinkers.DestroyAllThinkers();
|
||||||
interpolator.ClearInterpolations();
|
interpolator.ClearInterpolations();
|
||||||
arc.ReadObjects(hubload);
|
arc.ReadObjects(hubload);
|
||||||
ActiveSequences = 0;
|
ActiveSequences = 0;
|
||||||
|
@ -1000,7 +1000,7 @@ void FLevelLocals::Serialize(FSerializer &arc, bool hubload)
|
||||||
P_SerializeHealthGroups(this, arc);
|
P_SerializeHealthGroups(this, arc);
|
||||||
// [ZZ] serialize events
|
// [ZZ] serialize events
|
||||||
E_SerializeEvents(arc);
|
E_SerializeEvents(arc);
|
||||||
DThinker::SerializeThinkers(arc, hubload);
|
Thinkers.SerializeThinkers(arc, hubload);
|
||||||
arc("polyobjs", Polyobjects);
|
arc("polyobjs", Polyobjects);
|
||||||
SerializeSubsectors(arc, "subsectors");
|
SerializeSubsectors(arc, "subsectors");
|
||||||
StatusBar->SerializeMessages(arc);
|
StatusBar->SerializeMessages(arc);
|
||||||
|
|
|
@ -349,7 +349,7 @@ void P_FreeLevelData ()
|
||||||
E_Shutdown(true);
|
E_Shutdown(true);
|
||||||
R_FreePastViewers();
|
R_FreePastViewers();
|
||||||
|
|
||||||
DThinker::DestroyAllThinkers ();
|
Thinkers.DestroyAllThinkers ();
|
||||||
|
|
||||||
level.ClearLevelData();
|
level.ClearLevelData();
|
||||||
}
|
}
|
||||||
|
@ -574,7 +574,7 @@ void P_Init ()
|
||||||
|
|
||||||
static void P_Shutdown ()
|
static void P_Shutdown ()
|
||||||
{
|
{
|
||||||
DThinker::DestroyThinkersInList(STAT_STATIC);
|
Thinkers.DestroyThinkersInList(STAT_STATIC);
|
||||||
P_FreeLevelData ();
|
P_FreeLevelData ();
|
||||||
// [ZZ] delete global event handlers
|
// [ZZ] delete global event handlers
|
||||||
E_Shutdown(false);
|
E_Shutdown(false);
|
||||||
|
|
|
@ -40,12 +40,6 @@ class FScanner;
|
||||||
struct level_info_t;
|
struct level_info_t;
|
||||||
struct FDoorAnimation;
|
struct FDoorAnimation;
|
||||||
|
|
||||||
struct FThinkerCollection
|
|
||||||
{
|
|
||||||
int RefNum;
|
|
||||||
DThinker *Obj;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class EScroll : int
|
enum class EScroll : int
|
||||||
{
|
{
|
||||||
sc_side,
|
sc_side,
|
||||||
|
|
|
@ -151,7 +151,7 @@ void P_Ticker (void)
|
||||||
E_WorldTick();
|
E_WorldTick();
|
||||||
StatusBar->CallTick (); // [RH] moved this here
|
StatusBar->CallTick (); // [RH] moved this here
|
||||||
level.Tick (); // [RH] let the level tick
|
level.Tick (); // [RH] let the level tick
|
||||||
DThinker::RunThinkers ();
|
Thinkers.RunThinkers(&level);
|
||||||
|
|
||||||
//if added by MC: Freeze mode.
|
//if added by MC: Freeze mode.
|
||||||
if (!level.isFrozen())
|
if (!level.isFrozen())
|
||||||
|
|
Loading…
Reference in a new issue