Merge pull request #12315 from obrakmann/activities-pt1

Activities re-write, part 1 (aka the boring bits)
This commit is contained in:
reaperrr
2016-11-18 13:52:06 +01:00
committed by GitHub
26 changed files with 96 additions and 100 deletions

View File

@@ -18,14 +18,25 @@ namespace OpenRA.Activities
public abstract class Activity public abstract class Activity
{ {
public Activity NextActivity { get; set; } public Activity NextActivity { get; set; }
public bool IsInterruptible { get; protected set; }
protected bool IsCanceled { get; private set; } protected bool IsCanceled { get; private set; }
public Activity()
{
IsInterruptible = true;
}
public abstract Activity Tick(Actor self); public abstract Activity Tick(Actor self);
public virtual void Cancel(Actor self) public virtual bool Cancel(Actor self)
{ {
if (!IsInterruptible)
return false;
IsCanceled = true; IsCanceled = true;
NextActivity = null; NextActivity = null;
return true;
} }
public virtual void Queue(Activity activity) public virtual void Queue(Activity activity)
@@ -46,7 +57,7 @@ namespace OpenRA.Activities
{ {
public static IEnumerable<Target> GetTargetQueue(this Actor self) public static IEnumerable<Target> GetTargetQueue(this Actor self)
{ {
return self.GetCurrentActivity() return self.CurrentActivity
.Iterate(u => u.NextActivity) .Iterate(u => u.NextActivity)
.TakeWhile(u => u != null) .TakeWhile(u => u != null)
.SelectMany(u => u.GetTargets(self)); .SelectMany(u => u.GetTargets(self));

View File

@@ -16,25 +16,18 @@ namespace OpenRA.Activities
public class CallFunc : Activity public class CallFunc : Activity
{ {
public CallFunc(Action a) { this.a = a; } public CallFunc(Action a) { this.a = a; }
public CallFunc(Action a, bool interruptable) public CallFunc(Action a, bool interruptible)
{ {
this.a = a; this.a = a;
this.interruptable = interruptable; IsInterruptible = interruptible;
} }
Action a; Action a;
bool interruptable;
public override Activity Tick(Actor self) public override Activity Tick(Actor self)
{ {
if (a != null) a(); if (a != null) a();
return NextActivity; return NextActivity;
} }
public override void Cancel(Actor self)
{
if (interruptable)
base.Cancel(self);
}
} }
} }

View File

@@ -43,7 +43,7 @@ namespace OpenRA
public bool IsInWorld { get; internal set; } public bool IsInWorld { get; internal set; }
public bool Disposed { get; private set; } public bool Disposed { get; private set; }
Activity currentActivity; public Activity CurrentActivity { get; private set; }
public Group Group; public Group Group;
public int Generation; public int Generation;
@@ -54,7 +54,7 @@ namespace OpenRA
public IOccupySpace OccupiesSpace { get; private set; } public IOccupySpace OccupiesSpace { get; private set; }
public ITargetable[] Targetables { get; private set; } public ITargetable[] Targetables { get; private set; }
public bool IsIdle { get { return currentActivity == null; } } public bool IsIdle { get { return CurrentActivity == null; } }
public bool IsDead { get { return Disposed || (health != null && health.IsDead); } } public bool IsDead { get { return Disposed || (health != null && health.IsDead); } }
public CPos Location { get { return OccupiesSpace.TopLeft; } } public CPos Location { get { return OccupiesSpace.TopLeft; } }
@@ -161,7 +161,7 @@ namespace OpenRA
public void Tick() public void Tick()
{ {
var wasIdle = IsIdle; var wasIdle = IsIdle;
currentActivity = ActivityUtils.RunActivity(this, currentActivity); CurrentActivity = ActivityUtils.RunActivity(this, CurrentActivity);
if (!wasIdle && IsIdle) if (!wasIdle && IsIdle)
foreach (var n in TraitsImplementing<INotifyBecomingIdle>()) foreach (var n in TraitsImplementing<INotifyBecomingIdle>())
@@ -200,21 +200,18 @@ namespace OpenRA
public void QueueActivity(Activity nextActivity) public void QueueActivity(Activity nextActivity)
{ {
if (currentActivity == null) if (CurrentActivity == null)
currentActivity = nextActivity; CurrentActivity = nextActivity;
else else
currentActivity.Queue(nextActivity); CurrentActivity.Queue(nextActivity);
} }
public void CancelActivity() public bool CancelActivity()
{ {
if (currentActivity != null) if (CurrentActivity != null)
currentActivity.Cancel(this); return CurrentActivity.Cancel(this);
}
public Activity GetCurrentActivity() return true;
{
return currentActivity;
} }
public override int GetHashCode() public override int GetHashCode()

View File

@@ -794,8 +794,7 @@ namespace OpenRA.Mods.Common.AI
if (!harvester.IsIdle) if (!harvester.IsIdle)
{ {
var act = harvester.GetCurrentActivity(); var act = harvester.CurrentActivity;
if (act.NextActivity == null || act.NextActivity.GetType() != typeof(FindResources)) if (act.NextActivity == null || act.NextActivity.GetType() != typeof(FindResources))
continue; continue;
} }

View File

@@ -125,10 +125,10 @@ namespace OpenRA.Mods.Common.AI
protected static bool IsRearm(Actor a) protected static bool IsRearm(Actor a)
{ {
var activity = a.GetCurrentActivity(); if (a.IsIdle)
if (activity == null)
return false; return false;
var activity = a.CurrentActivity;
var type = activity.GetType(); var type = activity.GetType();
if (type == typeof(Rearm) || type == typeof(ResupplyAircraft)) if (type == typeof(Rearm) || type == typeof(ResupplyAircraft))
return true; return true;

View File

@@ -44,15 +44,16 @@ namespace OpenRA.Mods.Common.AI
if (a.IsIdle) if (a.IsIdle)
return false; return false;
var type = a.GetCurrentActivity().GetType(); var activity = a.CurrentActivity;
var type = activity.GetType();
if (type == typeof(Attack) || type == typeof(FlyAttack)) if (type == typeof(Attack) || type == typeof(FlyAttack))
return true; return true;
var next = a.GetCurrentActivity().NextActivity; var next = activity.NextActivity;
if (next == null) if (next == null)
return false; return false;
var nextType = a.GetCurrentActivity().NextActivity.GetType(); var nextType = next.GetType();
if (nextType == typeof(Attack) || nextType == typeof(FlyAttack)) if (nextType == typeof(Attack) || nextType == typeof(FlyAttack))
return true; return true;

View File

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

View File

@@ -68,13 +68,13 @@ namespace OpenRA.Mods.Common.Activities
return this; return this;
} }
public override void Cancel(Actor self) public override bool Cancel(Actor self)
{ {
if (!IsCanceled && inner != null) if (!IsCanceled && inner != null && !inner.Cancel(self))
inner.Cancel(self); return false;
// NextActivity must always be set to null: // 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; return inner == null || inner == NextActivity ? NextActivity : this;
} }
public override void Cancel(Actor self) public override bool Cancel(Actor self)
{ {
if (!IsCanceled && inner != null) if (!IsCanceled && inner != null && !inner.Cancel(self))
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>(); movement = self.Trait<IMove>();
harv = self.Trait<Harvester>(); harv = self.Trait<Harvester>();
IsInterruptible = false;
} }
public override Activity Tick(Actor self) public override Activity Tick(Actor self)
@@ -79,8 +80,5 @@ namespace OpenRA.Mods.Common.Activities
return ActivityUtils.SequenceActivities(new Wait(10), this); 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) if (!IsCanceled && innerActivity != null && !innerActivity.Cancel(self))
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); inner.Cancel(self);
} }
public override void Cancel(Actor self) public override bool Cancel(Actor self)
{ {
AbortOrExit(self); AbortOrExit(self);
if (nextState < State.Exiting) if (nextState < State.Exiting)
base.Cancel(self); return base.Cancel(self);
else else
NextActivity = null; NextActivity = null;
return true;
} }
ReserveStatus TryReserveElseTryAlternateReserve(Actor self) ReserveStatus TryReserveElseTryAlternateReserve(Actor self)

View File

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

View File

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

View File

@@ -32,6 +32,7 @@ namespace OpenRA.Mods.Common.Activities
this.start = start; this.start = start;
this.end = end; this.end = end;
this.length = length; this.length = length;
IsInterruptible = false;
} }
public override Activity Tick(Actor self) public override Activity Tick(Actor self)
@@ -62,8 +63,5 @@ namespace OpenRA.Mods.Common.Activities
{ {
yield return Target.FromPos(end); 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); return Pair.New(nextCell, subCell);
} }
public override void Cancel(Actor self) public override bool Cancel(Actor self)
{ {
path = NoPath; path = NoPath;
base.Cancel(self); return base.Cancel(self);
} }
public override IEnumerable<Target> GetTargets(Actor 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); Move.Cancel(self);
base.Cancel(self); return base.Cancel(self);
} }
public override void Queue(Activity activity) public override void Queue(Activity activity)

View File

@@ -161,12 +161,12 @@ namespace OpenRA.Mods.Common.Activities
return Target.None; return Target.None;
} }
public override void Cancel(Actor self) public override bool Cancel(Actor self)
{ {
if (inner != null) if (!IsCanceled && inner != null && !inner.Cancel(self))
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>(); para = self.Info.TraitInfo<ParachutableInfo>();
fallVector = new WVec(0, 0, para.FallRate); fallVector = new WVec(0, 0, para.FallRate);
this.dropPosition = dropPosition; this.dropPosition = dropPosition;
IsInterruptible = false;
} }
Activity FirstTick(Actor self) Activity FirstTick(Actor self)
@@ -91,8 +92,5 @@ namespace OpenRA.Mods.Common.Activities
{ {
NextActivity = activity; 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) if (!IsCanceled && innerActivity != null && !innerActivity.Cancel(self))
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>(); health = self.TraitOrDefault<Health>();
sellableInfo = self.Info.TraitInfo<SellableInfo>(); sellableInfo = self.Info.TraitInfo<SellableInfo>();
playerResources = self.Owner.PlayerActor.Trait<PlayerResources>(); playerResources = self.Owner.PlayerActor.Trait<PlayerResources>();
IsInterruptible = false;
} }
public override Activity Tick(Actor self) public override Activity Tick(Actor self)
@@ -45,8 +46,5 @@ namespace OpenRA.Mods.Common.Activities
self.Dispose(); self.Dispose();
return this; 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 public class Wait : Activity
{ {
int remainingTicks; int remainingTicks;
bool interruptable = true;
public Wait(int period) { remainingTicks = period; } public Wait(int period) { remainingTicks = period; }
public Wait(int period, bool interruptable) public Wait(int period, bool interruptible)
{ {
remainingTicks = period; remainingTicks = period;
this.interruptable = interruptable; IsInterruptible = interruptible;
} }
public override Activity Tick(Actor self) public override Activity Tick(Actor self)
@@ -31,26 +30,25 @@ namespace OpenRA.Mods.Common.Activities
return (remainingTicks-- == 0) ? NextActivity : this; return (remainingTicks-- == 0) ? NextActivity : this;
} }
public override void Cancel(Actor self) public override bool Cancel(Actor self)
{ {
if (!interruptable) if (!base.Cancel(self))
return; return false;
remainingTicks = 0; remainingTicks = 0;
base.Cancel(self); return true;
} }
} }
public class WaitFor : Activity public class WaitFor : Activity
{ {
Func<bool> f; Func<bool> f;
bool interruptable = true;
public WaitFor(Func<bool> f) { this.f = f; } public WaitFor(Func<bool> f) { this.f = f; }
public WaitFor(Func<bool> f, bool interruptable) public WaitFor(Func<bool> f, bool interruptible)
{ {
this.f = f; this.f = f;
this.interruptable = interruptable; IsInterruptible = interruptible;
} }
public override Activity Tick(Actor self) public override Activity Tick(Actor self)
@@ -58,13 +56,13 @@ namespace OpenRA.Mods.Common.Activities
return (f == null || f()) ? NextActivity : this; return (f == null || f()) ? NextActivity : this;
} }
public override void Cancel(Actor self) public override bool Cancel(Actor self)
{ {
if (!interruptable) if (!base.Cancel(self))
return; return false;
f = null; f = null;
base.Cancel(self); return true;
} }
} }
} }

View File

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

View File

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

View File

@@ -237,7 +237,7 @@ namespace OpenRA.Mods.Common.Traits
void INotifyBlockingMove.OnNotifyBlockingMove(Actor self, Actor blocking) void INotifyBlockingMove.OnNotifyBlockingMove(Actor self, Actor blocking)
{ {
// I'm blocking someone else from moving to my location: // I'm blocking someone else from moving to my location:
var act = self.GetCurrentActivity(); var act = self.CurrentActivity;
// If I'm just waiting around then get out of the way: // If I'm just waiting around then get out of the way:
if (act is Wait) if (act is Wait)

View File

@@ -76,7 +76,7 @@ namespace OpenRA.Mods.Common.Traits.Render
yield return new TextRenderable(font, self.CenterPosition - offset, 0, color, tagString); yield return new TextRenderable(font, self.CenterPosition - offset, 0, color, tagString);
// Get the actor's activity. // Get the actor's activity.
var activity = self.GetCurrentActivity(); var activity = self.CurrentActivity;
if (activity != null) if (activity != null)
{ {
var activityName = activity.GetType().ToString().Split('.').Last(); var activityName = activity.GetType().ToString().Split('.').Last();

View File

@@ -62,7 +62,7 @@ namespace OpenRA.Mods.Common.Traits.Render
if (!self.IsInWorld || self.IsDead) if (!self.IsInWorld || self.IsDead)
yield break; yield break;
var activity = self.GetCurrentActivity(); var activity = self.CurrentActivity;
if (activity != null) if (activity != null)
{ {
var targets = activity.GetTargets(self); var targets = activity.GetTargets(self);