mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-23 12:32:34 +00:00
Do not follow NextThinker links in DestroyThinkersInList
- Fixed: DThinker::Destroy(Most)ThinkersInList() were unreliable when destroyed thinkers destroyed more thinkers in the same list. Specifically, if the thinker it destroyed caused the very next thinker in the list to also be destroyed, it would get lost in the thinker list and end up with a NULL node. So just keep iterating through the first thinker in the list until there are none left. Since destroying a thinker causes it to remove itself from its list, the first thinker will always be changing as long as there's something to destroy.
This commit is contained in:
parent
3c376aa342
commit
0c9c624e8c
1 changed files with 3 additions and 6 deletions
|
@ -357,12 +357,10 @@ void DThinker::DestroyThinkersInList (FThinkerList &list)
|
||||||
{
|
{
|
||||||
if (list.Sentinel != NULL)
|
if (list.Sentinel != NULL)
|
||||||
{
|
{
|
||||||
DThinker *node = list.Sentinel->NextThinker;
|
for (DThinker *node = list.Sentinel->NextThinker; node != list.Sentinel; node = list.Sentinel->NextThinker)
|
||||||
while (node != list.Sentinel)
|
|
||||||
{
|
{
|
||||||
DThinker *next = node->NextThinker;
|
assert(node != NULL);
|
||||||
node->Destroy();
|
node->Destroy();
|
||||||
node = next;
|
|
||||||
}
|
}
|
||||||
list.Sentinel->Destroy();
|
list.Sentinel->Destroy();
|
||||||
list.Sentinel = NULL;
|
list.Sentinel = NULL;
|
||||||
|
@ -380,9 +378,8 @@ void DThinker::DestroyMostThinkersInList (FThinkerList &list, int stat)
|
||||||
// it from the list. G_FinishTravel() will find it later from
|
// it from the list. G_FinishTravel() will find it later from
|
||||||
// a players[].mo link and destroy it then, after copying various
|
// a players[].mo link and destroy it then, after copying various
|
||||||
// information to a new player.
|
// information to a new player.
|
||||||
for (DThinker *probe = list.Sentinel->NextThinker, *next; probe != list.Sentinel; probe = next)
|
for (DThinker *probe = list.Sentinel->NextThinker; probe != list.Sentinel; probe = list.Sentinel->NextThinker)
|
||||||
{
|
{
|
||||||
next = probe->NextThinker;
|
|
||||||
if (!probe->IsKindOf(RUNTIME_CLASS(APlayerPawn)) || // <- should not happen
|
if (!probe->IsKindOf(RUNTIME_CLASS(APlayerPawn)) || // <- should not happen
|
||||||
static_cast<AActor *>(probe)->player == NULL ||
|
static_cast<AActor *>(probe)->player == NULL ||
|
||||||
static_cast<AActor *>(probe)->player->mo != probe)
|
static_cast<AActor *>(probe)->player->mo != probe)
|
||||||
|
|
Loading…
Reference in a new issue