Directly mark queued activities that are cancelled as Done

This commit is contained in:
abcdefg30
2020-02-15 22:41:39 +00:00
committed by reaperrr
parent f45dd24781
commit abcb2ea512

View File

@@ -55,26 +55,23 @@ namespace OpenRA.Activities
Activity nextActivity; Activity nextActivity;
public Activity NextActivity public Activity NextActivity
{ {
get get { return SkipDoneActivities(nextActivity); }
{ private set { nextActivity = value; }
// 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; internal static Activity SkipDoneActivities(Activity first)
} {
// If first.Cancel() was called while it was queued (i.e. before it first ticked), its state will be Done
// rather than Queued (the activity system guarantees that it cannot be Active or Canceling).
// An unknown number of ticks may have elapsed between the Cancel() call and now,
// so we cannot make any assumptions on the value of first.NextActivity.
// We must not return first (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.
while (first != null && first.State == ActivityState.Done)
first = first.NextActivity;
private set return first;
{
nextActivity = value;
}
} }
public bool IsInterruptible { get; protected set; } public bool IsInterruptible { get; protected set; }
@@ -195,7 +192,8 @@ namespace OpenRA.Activities
if (ChildActivity != null) if (ChildActivity != null)
ChildActivity.Cancel(self); ChildActivity.Cancel(self);
State = ActivityState.Canceling; // Directly mark activities that are queued and therefore didn't run yet as done
State = State == ActivityState.Queued ? ActivityState.Done : ActivityState.Canceling;
} }
public void Queue(Activity activity) public void Queue(Activity activity)