Move OnLoad to after everything is done serializing

Makes behavior much more consistent and safer.
This commit is contained in:
Boondorl 2025-07-09 20:34:29 -04:00 committed by Rachael Alexanderson
commit 42a3ca3d56
3 changed files with 46 additions and 13 deletions

View file

@ -1538,6 +1538,10 @@ void FLevelLocals::DoLoadLevel(const FString &nextmapname, int position, bool au
{
I_Error("no start for player %d found.", pnumerr);
}
// If loading in from existing data, allow things to reinitialize if needed.
if (FromSnapshot || savegamerestore)
Thinkers.OnLoad();
}

View file

@ -362,6 +362,20 @@ void FThinkerCollection::DestroyAllThinkers(bool fullgc)
//
//==========================================================================
void FThinkerCollection::OnLoad()
{
for (auto& list : FreshThinkers)
list.OnLoad();
for (auto& list : Thinkers)
list.OnLoad();
}
//==========================================================================
//
//
//
//==========================================================================
void FThinkerCollection::SerializeThinkers(FSerializer &arc, bool hubLoad)
{
//DThinker *thinker;
@ -415,12 +429,12 @@ void FThinkerCollection::SerializeThinkers(FSerializer &arc, bool hubLoad)
else if (thinker->ObjectFlags & OF_JustSpawned)
{
FreshThinkers[i].AddTail(thinker);
thinker->CallPostSerialize();
thinker->PostSerialize();
}
else
{
Thinkers[i].AddTail(thinker);
thinker->CallPostSerialize();
thinker->PostSerialize();
}
}
}
@ -645,6 +659,30 @@ void FThinkerList::SaveList(FSerializer &arc)
//
//==========================================================================
void FThinkerList::OnLoad()
{
DThinker* node = GetHead();
if (node == nullptr)
return;
while (node != Sentinel)
{
NextToThink = node->NextThinker;
if (!(node->ObjectFlags & OF_EuthanizeMe))
{
IFOVERRIDENVIRTUALPTRNAME(node, NAME_Thinker, OnLoad)
VMCallVoid<DThinker*>(func, node);
}
node = NextToThink;
}
}
//==========================================================================
//
//
//
//==========================================================================
int FThinkerList::TickThinkers(FThinkerList *dest)
{
int count = 0;
@ -833,16 +871,6 @@ void DThinker::PostSerialize()
{
}
void DThinker::CallPostSerialize()
{
PostSerialize();
IFOVERRIDENVIRTUALPTRNAME(this, NAME_Thinker, OnLoad)
{
VMValue params[] = { this };
VMCall(func, params, 1, nullptr, 0);
}
}
//==========================================================================
//
//

View file

@ -60,6 +60,7 @@ struct FThinkerList
bool IsEmpty() const;
void DestroyThinkers();
bool DoDestroyThinkers();
void OnLoad();
int TickThinkers(FThinkerList *dest); // Returns: # of thinkers ticked
int ProfileThinkers(FThinkerList *dest);
void SaveList(FSerializer &arc);
@ -83,6 +84,7 @@ struct FThinkerCollection
void DestroyAllThinkers(bool fullgc = true);
void SerializeThinkers(FSerializer &arc, bool keepPlayers);
void MarkRoots();
void OnLoad();
DThinker *FirstThinker(int statnum);
void Link(DThinker *thinker, int statnum);
@ -105,7 +107,6 @@ public:
virtual void PostBeginPlay (); // Called just before the first tick
virtual void CallPostBeginPlay(); // different in actor.
virtual void PostSerialize();
void CallPostSerialize();
void Serialize(FSerializer &arc) override;
size_t PropagateMark();