Cache results of TraitsImplementing calls.

If a class is caching the TraitsImplementing enumerable, instead cache the results of enumerating it to an array. The avoids having to enumerate the sequence each time it is needed.
This commit is contained in:
RoosterDragon
2015-04-20 23:48:00 +01:00
parent 2937a31463
commit fb0cab7481
18 changed files with 45 additions and 47 deletions

View File

@@ -19,8 +19,8 @@ namespace OpenRA.GameRules
public class ProjectileArgs
{
public WeaponInfo Weapon;
public IEnumerable<int> DamageModifiers;
public IEnumerable<int> InaccuracyModifiers;
public int[] DamageModifiers;
public int[] InaccuracyModifiers;
public int Facing;
public WPos Source;
public Actor SourceActor;

View File

@@ -21,7 +21,7 @@ namespace OpenRA.Mods.Common.Activities
{
readonly Target target;
readonly AttackPlane attackPlane;
readonly IEnumerable<AmmoPool> ammoPools;
readonly AmmoPool[] ammoPools;
Activity inner;
int ticksUntilTurn;
@@ -29,7 +29,7 @@ namespace OpenRA.Mods.Common.Activities
{
this.target = target;
attackPlane = self.TraitOrDefault<AttackPlane>();
ammoPools = self.TraitsImplementing<AmmoPool>();
ammoPools = self.TraitsImplementing<AmmoPool>().ToArray();
ticksUntilTurn = attackPlane.AttackPlaneInfo.AttackTurnDelay;
}
@@ -40,7 +40,7 @@ namespace OpenRA.Mods.Common.Activities
// Move to the next activity only if all ammo pools are depleted and none reload automatically
// TODO: This should check whether there is ammo left that is actually suitable for the target
if (ammoPools != null && ammoPools.All(x => !x.Info.SelfReloads && !x.HasAmmo()))
if (ammoPools.All(x => !x.Info.SelfReloads && !x.HasAmmo()))
return NextActivity;
if (attackPlane != null)

View File

@@ -22,14 +22,14 @@ namespace OpenRA.Mods.Common.Activities
readonly Target target;
readonly Helicopter helicopter;
readonly AttackHeli attackHeli;
readonly IEnumerable<AmmoPool> ammoPools;
readonly AmmoPool[] ammoPools;
public HeliAttack(Actor self, Target target)
{
this.target = target;
helicopter = self.Trait<Helicopter>();
attackHeli = self.Trait<AttackHeli>();
ammoPools = self.TraitsImplementing<AmmoPool>();
ammoPools = self.TraitsImplementing<AmmoPool>().ToArray();
}
public override Activity Tick(Actor self)
@@ -39,7 +39,7 @@ namespace OpenRA.Mods.Common.Activities
// If all ammo pools are depleted and none reload automatically, return to helipad to reload and then move to next activity
// TODO: This should check whether there is ammo left that is actually suitable for the target
if (ammoPools != null && ammoPools.All(x => !x.Info.SelfReloads && !x.HasAmmo()))
if (ammoPools.All(x => !x.Info.SelfReloads && !x.HasAmmo()))
return Util.SequenceActivities(new HeliReturn(self), NextActivity);
var dist = target.CenterPosition - self.CenterPosition;

View File

@@ -19,7 +19,7 @@ namespace OpenRA.Mods.Common.Activities
class Demolish : Enter
{
readonly Actor target;
readonly IEnumerable<IDemolishable> demolishables;
readonly IDemolishable[] demolishables;
readonly int delay;
readonly int flashes;
readonly int flashesDelay;
@@ -32,7 +32,7 @@ namespace OpenRA.Mods.Common.Activities
: base(self, target)
{
this.target = target;
demolishables = target.TraitsImplementing<IDemolishable>();
demolishables = target.TraitsImplementing<IDemolishable>().ToArray();
this.delay = delay;
this.flashes = flashes;
this.flashesDelay = flashesDelay;

View File

@@ -19,7 +19,7 @@ namespace OpenRA.Mods.Common.Activities
{
readonly IPositionable positionable;
readonly IMove movement;
readonly IEnumerable<IDisableMove> moveDisablers;
readonly IDisableMove[] moveDisablers;
WPos start, end;
int length;
int ticks = 0;
@@ -28,7 +28,7 @@ namespace OpenRA.Mods.Common.Activities
{
positionable = self.Trait<IPositionable>();
movement = self.TraitOrDefault<IMove>();
moveDisablers = self.TraitsImplementing<IDisableMove>();
moveDisablers = self.TraitsImplementing<IDisableMove>().ToArray();
this.start = start;
this.end = end;
this.length = length;

View File

@@ -25,7 +25,7 @@ namespace OpenRA.Mods.Common.Activities
static readonly List<CPos> NoPath = new List<CPos>();
readonly Mobile mobile;
readonly IEnumerable<IDisableMove> moveDisablers;
readonly IDisableMove[] moveDisablers;
readonly WRange nearEnough;
readonly Func<List<CPos>> getPath;
readonly Actor ignoredActor;
@@ -43,7 +43,7 @@ namespace OpenRA.Mods.Common.Activities
public Move(Actor self, CPos destination)
{
mobile = self.Trait<Mobile>();
moveDisablers = self.TraitsImplementing<IDisableMove>();
moveDisablers = self.TraitsImplementing<IDisableMove>().ToArray();
getPath = () =>
self.World.WorldActor.Trait<IPathFinder>().FindPath(
@@ -60,7 +60,7 @@ namespace OpenRA.Mods.Common.Activities
public Move(Actor self, CPos destination, WRange nearEnough)
{
mobile = self.Trait<Mobile>();
moveDisablers = self.TraitsImplementing<IDisableMove>();
moveDisablers = self.TraitsImplementing<IDisableMove>().ToArray();
getPath = () => self.World.WorldActor.Trait<IPathFinder>()
.FindUnitPath(mobile.ToCell, destination, self);
@@ -71,7 +71,7 @@ namespace OpenRA.Mods.Common.Activities
public Move(Actor self, CPos destination, SubCell subCell, WRange nearEnough)
{
mobile = self.Trait<Mobile>();
moveDisablers = self.TraitsImplementing<IDisableMove>();
moveDisablers = self.TraitsImplementing<IDisableMove>().ToArray();
getPath = () => self.World.WorldActor.Trait<IPathFinder>()
.FindUnitPathToRange(mobile.FromCell, subCell, self.World.Map.CenterOfSubCell(destination, subCell), nearEnough, self);
@@ -82,7 +82,7 @@ namespace OpenRA.Mods.Common.Activities
public Move(Actor self, CPos destination, Actor ignoredActor)
{
mobile = self.Trait<Mobile>();
moveDisablers = self.TraitsImplementing<IDisableMove>();
moveDisablers = self.TraitsImplementing<IDisableMove>().ToArray();
getPath = () =>
self.World.WorldActor.Trait<IPathFinder>().FindPath(
@@ -97,7 +97,7 @@ namespace OpenRA.Mods.Common.Activities
public Move(Actor self, Target target, WRange range)
{
mobile = self.Trait<Mobile>();
moveDisablers = self.TraitsImplementing<IDisableMove>();
moveDisablers = self.TraitsImplementing<IDisableMove>().ToArray();
getPath = () =>
{
@@ -115,7 +115,7 @@ namespace OpenRA.Mods.Common.Activities
public Move(Actor self, Func<List<CPos>> getPath)
{
mobile = self.Trait<Mobile>();
moveDisablers = self.TraitsImplementing<IDisableMove>();
moveDisablers = self.TraitsImplementing<IDisableMove>().ToArray();
this.getPath = getPath;

View File

@@ -17,12 +17,12 @@ namespace OpenRA.Mods.Common.Activities
{
public class Rearm : Activity
{
readonly IEnumerable<AmmoPool> ammoPools;
readonly AmmoPool[] ammoPools;
readonly Dictionary<AmmoPool, int> ammoPoolsReloadTimes;
public Rearm(Actor self)
{
ammoPools = self.TraitsImplementing<AmmoPool>().Where(p => !p.Info.SelfReloads);
ammoPools = self.TraitsImplementing<AmmoPool>().Where(p => !p.Info.SelfReloads).ToArray();
if (ammoPools == null)
return;

View File

@@ -17,12 +17,12 @@ namespace OpenRA.Mods.Common.Activities
{
public class Turn : Activity
{
readonly IEnumerable<IDisableMove> moveDisablers;
readonly IDisableMove[] moveDisablers;
readonly int desiredFacing;
public Turn(Actor self, int desiredFacing)
{
moveDisablers = self.TraitsImplementing<IDisableMove>();
moveDisablers = self.TraitsImplementing<IDisableMove>().ToArray();
this.desiredFacing = desiredFacing;
}

View File

@@ -59,12 +59,12 @@ namespace OpenRA.Mods.Common.Scripting
[ScriptPropertyGroup("Power")]
public class ActorPowerProperties : ScriptActorProperties, Requires<PowerInfo>
{
readonly IEnumerable<PowerTrait> power;
readonly PowerTrait[] power;
public ActorPowerProperties(ScriptContext context, Actor self)
: base(context, self)
{
power = self.TraitsImplementing<PowerTrait>();
power = self.TraitsImplementing<PowerTrait>().ToArray();
}
[Desc("Returns the power drained/provided by this actor.")]

View File

@@ -84,13 +84,13 @@ namespace OpenRA.Mods.Common.Scripting
[ScriptPropertyGroup("Production")]
public class ProductionQueueProperties : ScriptActorProperties, Requires<ProductionQueueInfo>, Requires<ScriptTriggersInfo>
{
readonly List<ProductionQueue> queues;
readonly ProductionQueue[] queues;
readonly ScriptTriggers triggers;
public ProductionQueueProperties(ScriptContext context, Actor self)
: base(context, self)
{
queues = self.TraitsImplementing<ProductionQueue>().Where(q => q.Enabled).ToList();
queues = self.TraitsImplementing<ProductionQueue>().Where(q => q.Enabled).ToArray();
triggers = TriggerGlobal.GetScriptTriggers(self);
}

View File

@@ -167,10 +167,10 @@ namespace OpenRA.Mods.Common.Traits
Facing = legacyFacing,
DamageModifiers = self.TraitsImplementing<IFirepowerModifier>()
.Select(a => a.GetFirepowerModifier()),
.Select(a => a.GetFirepowerModifier()).ToArray(),
InaccuracyModifiers = self.TraitsImplementing<IInaccuracyModifier>()
.Select(a => a.GetInaccuracyModifier()),
.Select(a => a.GetInaccuracyModifier()).ToArray(),
Source = muzzlePosition,
SourceActor = self,

View File

@@ -53,7 +53,7 @@ namespace OpenRA.Mods.Common.Traits
this.self = self;
var armaments = Exts.Lazy(() => self.TraitsImplementing<Armament>()
.Where(a => info.Armaments.Contains(a.Info.Name)));
.Where(a => info.Armaments.Contains(a.Info.Name)).ToArray());
getArmaments = () => armaments.Value;

View File

@@ -9,6 +9,7 @@
#endregion
using System.Collections.Generic;
using System.Linq;
using OpenRA.Activities;
using OpenRA.Traits;
@@ -22,12 +23,12 @@ namespace OpenRA.Mods.Common.Traits
public class AttackTurreted : AttackFollow, ITick, ISync
{
protected IEnumerable<Turreted> turrets;
protected Turreted[] turrets;
public AttackTurreted(Actor self, AttackTurretedInfo info)
: base(self, info)
{
turrets = self.TraitsImplementing<Turreted>();
turrets = self.TraitsImplementing<Turreted>().ToArray();
}
protected override bool CanAttack(Actor self, Target target)

View File

@@ -62,7 +62,7 @@ namespace OpenRA.Mods.Common.Traits
IBodyOrientation body;
AttackBase ab;
Turreted t;
IEnumerable<Armament> arms;
Armament[] arms;
Animation anim;
public WithTurret(Actor self, WithTurretInfo info)
@@ -75,7 +75,7 @@ namespace OpenRA.Mods.Common.Traits
t = self.TraitsImplementing<Turreted>()
.First(tt => tt.Name == info.Turret);
arms = self.TraitsImplementing<Armament>()
.Where(w => w.Info.Turret == info.Turret);
.Where(w => w.Info.Turret == info.Turret).ToArray();
anim = new Animation(self.World, rs.GetImage(self), () => t.TurretFacing);
anim.Play(info.Sequence);

View File

@@ -29,13 +29,13 @@ namespace OpenRA.Mods.Common.Traits
{
readonly RepairableInfo info;
readonly Health health;
readonly IEnumerable<AmmoPool> ammoPools;
readonly AmmoPool[] ammoPools;
public Repairable(Actor self, RepairableInfo info)
{
this.info = info;
health = self.Trait<Health>();
ammoPools = self.TraitsImplementing<AmmoPool>();
ammoPools = self.TraitsImplementing<AmmoPool>().ToArray();
}
public IEnumerable<IOrderTargeter> Orders
@@ -72,10 +72,7 @@ namespace OpenRA.Mods.Common.Traits
bool CanRearm()
{
if (ammoPools != null)
return ammoPools.Any(x => !x.Info.SelfReloads && !x.FullAmmo());
else
return false;
return ammoPools.Any(x => !x.Info.SelfReloads && !x.FullAmmo());
}
public string VoicePhraseForOrder(Actor self, Order order)

View File

@@ -28,7 +28,7 @@ namespace OpenRA.Mods.Common.Widgets
public WorldTooltipType TooltipType { get; private set; }
public IToolTip ActorTooltip { get; private set; }
public IEnumerable<IProvideTooltipInfo> ActorTooltipExtra { get; private set; }
public IProvideTooltipInfo[] ActorTooltipExtra { get; private set; }
public FrozenActor FrozenActorTooltip { get; private set; }
public int EdgeScrollThreshold = 15;
@@ -112,7 +112,7 @@ namespace OpenRA.Mods.Common.Widgets
if (underCursor != null)
{
ActorTooltip = underCursor.TraitsImplementing<IToolTip>().First();
ActorTooltipExtra = underCursor.TraitsImplementing<IProvideTooltipInfo>();
ActorTooltipExtra = underCursor.TraitsImplementing<IProvideTooltipInfo>().ToArray();
TooltipType = WorldTooltipType.Actor;
return;
}
@@ -125,7 +125,7 @@ namespace OpenRA.Mods.Common.Widgets
{
FrozenActorTooltip = frozen;
if (frozen.Actor != null)
ActorTooltipExtra = frozen.Actor.TraitsImplementing<IProvideTooltipInfo>();
ActorTooltipExtra = frozen.Actor.TraitsImplementing<IProvideTooltipInfo>().ToArray();
TooltipType = WorldTooltipType.FrozenActor;
}
}

View File

@@ -50,10 +50,10 @@ namespace OpenRA.Mods.D2k.Traits
Facing = self.World.SharedRandom.Next(-1, 255),
DamageModifiers = self.TraitsImplementing<IFirepowerModifier>()
.Select(a => a.GetFirepowerModifier()),
.Select(a => a.GetFirepowerModifier()).ToArray(),
InaccuracyModifiers = self.TraitsImplementing<IInaccuracyModifier>()
.Select(a => a.GetInaccuracyModifier()),
.Select(a => a.GetInaccuracyModifier()).ToArray(),
Source = self.CenterPosition,
SourceActor = self,

View File

@@ -25,7 +25,7 @@ namespace OpenRA.Mods.RA.Activities
{
readonly Minelayer minelayer;
readonly MinelayerInfo info;
readonly IEnumerable<AmmoPool> ammoPools;
readonly AmmoPool[] ammoPools;
readonly IMove movement;
readonly string[] rearmBuildings;
@@ -33,7 +33,7 @@ namespace OpenRA.Mods.RA.Activities
{
minelayer = self.TraitOrDefault<Minelayer>();
info = self.Info.Traits.Get<MinelayerInfo>();
ammoPools = self.TraitsImplementing<AmmoPool>();
ammoPools = self.TraitsImplementing<AmmoPool>().ToArray();
movement = self.Trait<IMove>();
rearmBuildings = info.RearmBuildings;
}