Add native support for uninterruptible activities

This pattern occurs a few times throughout the code, so it makes sense to bake it into the Activity class itself.
This commit is contained in:
Oliver Brakmann
2016-10-29 17:38:10 +02:00
parent 3e9bf7aa4d
commit 2c66ee8c13
20 changed files with 76 additions and 75 deletions

View File

@@ -18,14 +18,25 @@ namespace OpenRA.Activities
public abstract class Activity
{
public Activity NextActivity { get; set; }
public bool IsInterruptible { get; protected set; }
protected bool IsCanceled { get; private set; }
public Activity()
{
IsInterruptible = true;
}
public abstract Activity Tick(Actor self);
public virtual void Cancel(Actor self)
public virtual bool Cancel(Actor self)
{
if (!IsInterruptible)
return false;
IsCanceled = true;
NextActivity = null;
return true;
}
public virtual void Queue(Activity activity)

View File

@@ -19,22 +19,15 @@ namespace OpenRA.Activities
public CallFunc(Action a, bool interruptable)
{
this.a = a;
this.interruptable = interruptable;
IsInterruptible = interruptable;
}
Action a;
bool interruptable;
public override Activity Tick(Actor self)
{
if (a != null) a();
return NextActivity;
}
public override void Cancel(Actor self)
{
if (interruptable)
base.Cancel(self);
}
}
}

View File

@@ -206,10 +206,12 @@ namespace OpenRA
CurrentActivity.Queue(nextActivity);
}
public void CancelActivity()
public bool CancelActivity()
{
if (CurrentActivity != null)
CurrentActivity.Cancel(this);
return CurrentActivity.Cancel(this);
return true;
}
public override int GetHashCode()

View File

@@ -26,6 +26,7 @@ namespace OpenRA.Mods.Common.Activities
public FallToEarth(Actor self, FallsToEarthInfo info)
{
this.info = info;
IsInterruptible = false;
aircraft = self.Trait<Aircraft>();
if (info.Spins)
acceleration = self.World.SharedRandom.Next(2) * 2 - 1;
@@ -57,8 +58,5 @@ namespace OpenRA.Mods.Common.Activities
return this;
}
// Cannot be cancelled
public override void Cancel(Actor self) { }
}
}

View File

@@ -68,13 +68,13 @@ namespace OpenRA.Mods.Common.Activities
return this;
}
public override void Cancel(Actor self)
public override bool Cancel(Actor self)
{
if (!IsCanceled && inner != null)
inner.Cancel(self);
if (!IsCanceled && inner != null && !inner.Cancel(self))
return false;
// NextActivity must always be set to null:
base.Cancel(self);
return base.Cancel(self);
}
}
}

View File

@@ -63,12 +63,12 @@ namespace OpenRA.Mods.Common.Activities
return inner == null || inner == NextActivity ? NextActivity : this;
}
public override void Cancel(Actor self)
public override bool Cancel(Actor self)
{
if (!IsCanceled && inner != null)
inner.Cancel(self);
if (!IsCanceled && inner != null && !inner.Cancel(self))
return false;
base.Cancel(self);
return base.Cancel(self);
}
}
}

View File

@@ -30,6 +30,7 @@ namespace OpenRA.Mods.Common.Activities
{
movement = self.Trait<IMove>();
harv = self.Trait<Harvester>();
IsInterruptible = false;
}
public override Activity Tick(Actor self)
@@ -79,8 +80,5 @@ namespace OpenRA.Mods.Common.Activities
return ActivityUtils.SequenceActivities(new Wait(10), this);
}
// Cannot be cancelled
public override void Cancel(Actor self) { }
}
}

View File

@@ -207,12 +207,12 @@ namespace OpenRA.Mods.Common.Activities
});
}
public override void Cancel(Actor self)
public override bool Cancel(Actor self)
{
if (innerActivity != null)
innerActivity.Cancel(self);
if (!IsCanceled && innerActivity != null && !innerActivity.Cancel(self))
return false;
base.Cancel(self);
return base.Cancel(self);
}
}
}

View File

@@ -112,13 +112,15 @@ namespace OpenRA.Mods.Common.Activities
inner.Cancel(self);
}
public override void Cancel(Actor self)
public override bool Cancel(Actor self)
{
AbortOrExit(self);
if (nextState < State.Exiting)
base.Cancel(self);
return base.Cancel(self);
else
NextActivity = null;
return true;
}
ReserveStatus TryReserveElseTryAlternateReserve(Actor self)

View File

@@ -81,10 +81,10 @@ namespace OpenRA.Mods.Common.Activities
throw new InvalidOperationException("Invalid harvester dock state");
}
public override void Cancel(Actor self)
public override bool Cancel(Actor self)
{
dockingState = State.Undock;
base.Cancel(self);
return base.Cancel(self);
}
public override IEnumerable<Target> GetTargets(Actor self)

View File

@@ -46,12 +46,12 @@ namespace OpenRA.Mods.Common.Activities
return this;
}
public override void Cancel(Actor self)
public override bool Cancel(Actor self)
{
if (inner != null)
inner.Cancel(self);
if (!IsCanceled && inner != null && !inner.Cancel(self))
return false;
base.Cancel(self);
return base.Cancel(self);
}
public override IEnumerable<Target> GetTargets(Actor self)

View File

@@ -32,6 +32,7 @@ namespace OpenRA.Mods.Common.Activities
this.start = start;
this.end = end;
this.length = length;
IsInterruptible = false;
}
public override Activity Tick(Actor self)
@@ -62,8 +63,5 @@ namespace OpenRA.Mods.Common.Activities
{
yield return Target.FromPos(end);
}
// Cannot be cancelled
public override void Cancel(Actor self) { }
}
}

View File

@@ -272,10 +272,10 @@ namespace OpenRA.Mods.Common.Activities
return Pair.New(nextCell, subCell);
}
public override void Cancel(Actor self)
public override bool Cancel(Actor self)
{
path = NoPath;
base.Cancel(self);
return base.Cancel(self);
}
public override IEnumerable<Target> GetTargets(Actor self)
@@ -331,10 +331,10 @@ namespace OpenRA.Mods.Common.Activities
}
}
public override void Cancel(Actor self)
public override bool Cancel(Actor self)
{
Move.Cancel(self);
base.Cancel(self);
return base.Cancel(self);
}
public override void Queue(Activity activity)

View File

@@ -161,12 +161,12 @@ namespace OpenRA.Mods.Common.Activities
return Target.None;
}
public override void Cancel(Actor self)
public override bool Cancel(Actor self)
{
if (inner != null)
inner.Cancel(self);
if (!IsCanceled && inner != null && !inner.Cancel(self))
return false;
base.Cancel(self);
return base.Cancel(self);
}
}
}

View File

@@ -37,6 +37,7 @@ namespace OpenRA.Mods.Common.Activities
para = self.Info.TraitInfo<ParachutableInfo>();
fallVector = new WVec(0, 0, para.FallRate);
this.dropPosition = dropPosition;
IsInterruptible = false;
}
Activity FirstTick(Actor self)
@@ -91,8 +92,5 @@ namespace OpenRA.Mods.Common.Activities
{
NextActivity = activity;
}
// Cannot be cancelled
public override void Cancel(Actor self) { }
}
}

View File

@@ -157,12 +157,12 @@ namespace OpenRA.Mods.Common.Activities
});
}
public override void Cancel(Actor self)
public override bool Cancel(Actor self)
{
if (innerActivity != null)
innerActivity.Cancel(self);
if (!IsCanceled && innerActivity != null && !innerActivity.Cancel(self))
return false;
base.Cancel(self);
return base.Cancel(self);
}
}
}

View File

@@ -27,6 +27,7 @@ namespace OpenRA.Mods.Common.Activities
health = self.TraitOrDefault<Health>();
sellableInfo = self.Info.TraitInfo<SellableInfo>();
playerResources = self.Owner.PlayerActor.Trait<PlayerResources>();
IsInterruptible = false;
}
public override Activity Tick(Actor self)
@@ -45,8 +46,5 @@ namespace OpenRA.Mods.Common.Activities
self.Dispose();
return this;
}
// Cannot be cancelled
public override void Cancel(Actor self) { }
}
}

View File

@@ -17,13 +17,12 @@ namespace OpenRA.Mods.Common.Activities
public class Wait : Activity
{
int remainingTicks;
bool interruptable = true;
public Wait(int period) { remainingTicks = period; }
public Wait(int period, bool interruptable)
{
remainingTicks = period;
this.interruptable = interruptable;
IsInterruptible = interruptable;
}
public override Activity Tick(Actor self)
@@ -31,26 +30,25 @@ namespace OpenRA.Mods.Common.Activities
return (remainingTicks-- == 0) ? NextActivity : this;
}
public override void Cancel(Actor self)
public override bool Cancel(Actor self)
{
if (!interruptable)
return;
if (!base.Cancel(self))
return false;
remainingTicks = 0;
base.Cancel(self);
return true;
}
}
public class WaitFor : Activity
{
Func<bool> f;
bool interruptable = true;
public WaitFor(Func<bool> f) { this.f = f; }
public WaitFor(Func<bool> f, bool interruptable)
{
this.f = f;
this.interruptable = interruptable;
IsInterruptible = interruptable;
}
public override Activity Tick(Actor self)
@@ -58,13 +56,13 @@ namespace OpenRA.Mods.Common.Activities
return (f == null || f()) ? NextActivity : this;
}
public override void Cancel(Actor self)
public override bool Cancel(Actor self)
{
if (!interruptable)
return;
if (!base.Cancel(self))
return false;
f = null;
base.Cancel(self);
return true;
}
}
}

View File

@@ -41,10 +41,12 @@ namespace OpenRA.Mods.Common.Activities
return this;
}
public override void Cancel(Actor self)
public override bool Cancel(Actor self)
{
if (inner != null)
inner.Cancel(self);
if (!IsCanceled && inner != null && !inner.Cancel(self))
return false;
return base.Cancel(self);
}
}
}

View File

@@ -43,10 +43,13 @@ namespace OpenRA.Mods.Common.Activities
return NextActivity;
}
public override void Cancel(Actor self)
public override bool Cancel(Actor self)
{
if (!base.Cancel(self))
return false;
Dispose();
base.Cancel(self);
return true;
}
public void Dispose()