diff --git a/OpenRA.Game/Activities/Activity.cs b/OpenRA.Game/Activities/Activity.cs index 9a7679ad23..f4e1956cd3 100644 --- a/OpenRA.Game/Activities/Activity.cs +++ b/OpenRA.Game/Activities/Activity.cs @@ -9,14 +9,19 @@ */ #endregion +using System; using System.Collections.Generic; using System.Linq; using OpenRA.Traits; namespace OpenRA.Activities { + public enum ActivityState { Queued, Active, Done } + public abstract class Activity { + public ActivityState State { get; private set; } + public Activity NextActivity { get; set; } public bool IsInterruptible { get; protected set; } protected bool IsCanceled { get; private set; } @@ -26,8 +31,39 @@ namespace OpenRA.Activities IsInterruptible = true; } + public Activity TickOuter(Actor self) + { + if (State == ActivityState.Done && Game.Settings.Debug.StrictActivityChecking) + throw new InvalidOperationException("Actor {0} attempted to tick activity {1} after it had already completed.".F(self, this.GetType())); + + if (State == ActivityState.Queued) + { + OnFirstRun(self); + State = ActivityState.Active; + } + + var ret = Tick(self); + if (ret != this) + { + State = ActivityState.Done; + OnLastRun(self); + } + + return ret; + } + public abstract Activity Tick(Actor self); + /// + /// Runs once immediately before the first Tick() execution. + /// + protected virtual void OnFirstRun(Actor self) { } + + /// + /// Runs once immediately after the last Tick() execution. + /// + protected virtual void OnLastRun(Actor self) { } + public virtual bool Cancel(Actor self) { if (!IsInterruptible) diff --git a/OpenRA.Game/Settings.cs b/OpenRA.Game/Settings.cs index 9dc80aa7d2..9433a6b045 100644 --- a/OpenRA.Game/Settings.cs +++ b/OpenRA.Game/Settings.cs @@ -92,6 +92,7 @@ namespace OpenRA public bool SanityCheckUnsyncedCode = false; public int Samples = 25; public bool IgnoreVersionMismatch = false; + public bool StrictActivityChecking = false; public bool SendSystemInformation = true; public int SystemInformationVersionPrompt = 0; public string UUID = System.Guid.NewGuid().ToString(); diff --git a/OpenRA.Game/Traits/ActivityUtils.cs b/OpenRA.Game/Traits/ActivityUtils.cs index 210461d050..463a961441 100644 --- a/OpenRA.Game/Traits/ActivityUtils.cs +++ b/OpenRA.Game/Traits/ActivityUtils.cs @@ -34,7 +34,7 @@ namespace OpenRA.Traits while (act != null) { var prev = act; - act = act.Tick(self); + act = act.TickOuter(self); var current = Stopwatch.GetTimestamp(); if (current - start > longTickThresholdInStopwatchTicks) {