From 6f52365f9dd8b0e6cde52457926056f428503829 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Sun, 12 Jan 2020 12:14:28 +0000 Subject: [PATCH] Don't run NextActivity if it has been canceled. --- OpenRA.Game/Activities/Activity.cs | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/OpenRA.Game/Activities/Activity.cs b/OpenRA.Game/Activities/Activity.cs index 4b7d667fe2..9312a38718 100644 --- a/OpenRA.Game/Activities/Activity.cs +++ b/OpenRA.Game/Activities/Activity.cs @@ -51,7 +51,31 @@ namespace OpenRA.Activities public ActivityState State { get; private set; } protected Activity ChildActivity { get; private set; } - public Activity NextActivity { get; private set; } + + Activity nextActivity; + public Activity NextActivity + { + get + { + // If Activity.NextActivity.Cancel() was called, NextActivity will be in the Canceling + // state rather than Queued (the activity system guarantees that it cannot be Active or Done). + // An unknown number of ticks may have elapsed between the Activity.NextActivity.Cancel() call + // and now, so we cannot make any assumptions on the value of Activity.NextActivity.NextActivity. + // We must not return nextActivity (ticking it would be bogus), but returning null would potentially + // drop valid activities queued after it. Walk the queue until we find a valid activity or + // (more likely) run out of activities. + var next = nextActivity; + while (next != null && next.State == ActivityState.Canceling) + next = next.NextActivity; + + return next; + } + + private set + { + nextActivity = value; + } + } public bool IsInterruptible { get; protected set; } public bool ChildHasPriority { get; protected set; }