mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-29 15:22:08 +00:00
- changed global thinker storage into a struct instead of some static variables inside DThinker.
As it is now it can handle multiple thinker collections for different levels, but right now there's still only one global list for everything.
This commit is contained in:
parent
dd5addd6ad
commit
703cb9cf4e
11 changed files with 545 additions and 514 deletions
|
@ -2585,7 +2585,7 @@ void D_DoomMain (void)
|
|||
gamestate = GS_FULLCONSOLE;
|
||||
Net_NewMakeTic ();
|
||||
ForAllLevels([](FLevelLocals *Level) {
|
||||
DThinker::RunThinkers (Level);
|
||||
Thinkers.RunThinkers (Level);
|
||||
});
|
||||
gamestate = GS_STARTUP;
|
||||
|
||||
|
@ -2702,7 +2702,7 @@ void D_DoomMain (void)
|
|||
// clean up game state
|
||||
ST_Clear();
|
||||
D_ErrorCleanup ();
|
||||
DThinker::DestroyThinkersInList(STAT_STATIC);
|
||||
Thinkers.DestroyThinkersInList(STAT_STATIC);
|
||||
E_Shutdown(false);
|
||||
P_FreeLevelData();
|
||||
|
||||
|
|
|
@ -282,7 +282,6 @@ static void MarkRoot()
|
|||
Mark(StatusBar);
|
||||
M_MarkMenus();
|
||||
Mark(DIntermissionController::CurrentIntermission);
|
||||
DThinker::MarkRoots();
|
||||
Mark(E_FirstEventHandler);
|
||||
Mark(E_LastEventHandler);
|
||||
|
||||
|
|
965
src/dthinker.cpp
965
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
|
||||
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);
|
||||
DThinker *GetHead() const;
|
||||
DThinker *GetTail() 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);
|
||||
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
|
||||
|
@ -89,35 +119,15 @@ public:
|
|||
|
||||
void ChangeStatNum (int statnum);
|
||||
|
||||
static void RunThinkers (FLevelLocals *Level);
|
||||
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();
|
||||
|
||||
static DThinker *FirstThinker (int statnum);
|
||||
|
||||
FLevelLocals *Level;
|
||||
|
||||
protected:
|
||||
DThinker() = default;
|
||||
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();
|
||||
|
||||
static FThinkerList Thinkers[MAX_STATNUM+2]; // Current thinkers
|
||||
static FThinkerList FreshThinkers[MAX_STATNUM+1]; // Newly created thinkers
|
||||
|
||||
friend struct FThinkerList;
|
||||
friend struct FThinkerCollection;
|
||||
friend class FThinkerIterator;
|
||||
friend class DObject;
|
||||
friend class FSerializer;
|
||||
|
@ -194,4 +204,5 @@ T* CreateThinker(Args&&... args)
|
|||
return object;
|
||||
}
|
||||
|
||||
extern FThinkerCollection Thinkers;
|
||||
#endif //__DTHINKER_H__
|
||||
|
|
|
@ -489,7 +489,7 @@ void G_InitNew (const char *mapname, bool bTitleLevel)
|
|||
UnlatchCVars ();
|
||||
G_VerifySkill();
|
||||
UnlatchCVars ();
|
||||
DThinker::DestroyThinkersInList(STAT_STATIC);
|
||||
Thinkers.DestroyThinkersInList(STAT_STATIC);
|
||||
|
||||
if (paused)
|
||||
{
|
||||
|
@ -1515,7 +1515,7 @@ int G_FinishTravel (FLevelLocals *Level)
|
|||
// 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
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
@ -1529,7 +1529,7 @@ FLevelLocals::~FLevelLocals()
|
|||
{
|
||||
SN_StopAllSequences(this);
|
||||
ClearAllSubsectorLinks(); // can't be done as part of the polyobj deletion process.
|
||||
DThinker::DestroyAllThinkers();
|
||||
Thinkers.DestroyAllThinkers();
|
||||
|
||||
// delete allocated data in the level arrays.
|
||||
if (sectors.Size() > 0)
|
||||
|
@ -2217,6 +2217,7 @@ void FLevelLocals::Mark()
|
|||
GC::Mark(ACSThinker);
|
||||
GC::Mark(interpolator.Head);
|
||||
GC::Mark(SequenceListHead);
|
||||
Thinkers.MarkRoots();
|
||||
|
||||
canvasTextureInfo.Mark();
|
||||
for (auto &c : CorpseQueue)
|
||||
|
|
|
@ -533,7 +533,7 @@ CUSTOM_CVAR (Int, cl_maxdecals, 1024, CVAR_ARCHIVE)
|
|||
{
|
||||
while (Level->ImpactDecalCount > self)
|
||||
{
|
||||
DThinker *thinker = DThinker::FirstThinker(STAT_AUTODECAL);
|
||||
DThinker *thinker = Thinkers.FirstThinker(STAT_AUTODECAL);
|
||||
if (thinker != NULL)
|
||||
{
|
||||
thinker->Destroy();
|
||||
|
@ -552,7 +552,7 @@ void DImpactDecal::CheckMax ()
|
|||
{
|
||||
if (++Level->ImpactDecalCount >= cl_maxdecals)
|
||||
{
|
||||
DThinker *thinker = DThinker::FirstThinker (STAT_AUTODECAL);
|
||||
DThinker *thinker = Thinkers.FirstThinker (STAT_AUTODECAL);
|
||||
if (thinker != NULL)
|
||||
{
|
||||
thinker->Destroy();
|
||||
|
|
|
@ -415,8 +415,15 @@ void P_SpawnPushers (FLevelLocals *Level)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void AdjustPusher (FLevelLocals *Level, int tag, int magnitude, int angle, bool wind)
|
||||
{
|
||||
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.
|
||||
|
|
|
@ -914,7 +914,7 @@ void G_SerializeLevel(FSerializer &arc, FLevelLocals *Level, bool hubload)
|
|||
|
||||
if (arc.isReading())
|
||||
{
|
||||
DThinker::DestroyAllThinkers();
|
||||
Thinkers.DestroyAllThinkers();
|
||||
Level->interpolator.ClearInterpolations();
|
||||
arc.ReadObjects(hubload);
|
||||
}
|
||||
|
@ -977,7 +977,7 @@ void G_SerializeLevel(FSerializer &arc, FLevelLocals *Level, bool hubload)
|
|||
P_SerializeHealthGroups(Level, arc);
|
||||
// [ZZ] serialize events
|
||||
E_SerializeEvents(arc);
|
||||
DThinker::SerializeThinkers(arc, hubload);
|
||||
Thinkers.SerializeThinkers(arc, hubload);
|
||||
arc("polyobjs", Level->Polyobjects);
|
||||
SerializeSubsectors(arc, Level, "subsectors");
|
||||
StatusBar->SerializeMessages(arc);
|
||||
|
|
|
@ -426,7 +426,7 @@ static void P_Shutdown ()
|
|||
{
|
||||
delete currentSession;
|
||||
currentSession = nullptr;
|
||||
DThinker::DestroyThinkersInList(STAT_STATIC);
|
||||
Thinkers.DestroyThinkersInList(STAT_STATIC);
|
||||
P_FreeLevelData ();
|
||||
// [ZZ] delete global event handlers
|
||||
E_Shutdown(false);
|
||||
|
|
|
@ -40,12 +40,6 @@ class FScanner;
|
|||
struct level_info_t;
|
||||
struct FDoorAnimation;
|
||||
|
||||
struct FThinkerCollection
|
||||
{
|
||||
int RefNum;
|
||||
DThinker *Obj;
|
||||
};
|
||||
|
||||
enum class EScroll : int
|
||||
{
|
||||
sc_side,
|
||||
|
|
|
@ -152,7 +152,7 @@ void P_Ticker (void)
|
|||
memset(&Level->Scrolls[0], 0, sizeof(Level->Scrolls[0]) * Level->Scrolls.Size());
|
||||
}
|
||||
|
||||
DThinker::RunThinkers(Level);
|
||||
Thinkers.RunThinkers(Level);
|
||||
|
||||
//if added by MC: Freeze mode.
|
||||
if (!currentSession->isFrozen())
|
||||
|
|
Loading…
Reference in a new issue