From 6125d7c11779186ee117fa056c05b75865cac226 Mon Sep 17 00:00:00 2001 From: RoosterDragon Date: Wed, 22 Apr 2015 20:09:41 +0100 Subject: [PATCH 1/4] Rename existing fields that are caching TraitsImplementing calls for consistency. --- OpenRA.Game/Actor.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/OpenRA.Game/Actor.cs b/OpenRA.Game/Actor.cs index 0cb4d73f1a..1f45274035 100644 --- a/OpenRA.Game/Actor.cs +++ b/OpenRA.Game/Actor.cs @@ -83,8 +83,8 @@ namespace OpenRA } } - readonly IRenderModifier[] traitsImplementingRenderModifier; - readonly IRender[] traitsImplementingRender; + readonly IRenderModifier[] renderModifiers; + readonly IRender[] renders; internal Actor(World world, string name, TypeDictionary initDict) { @@ -126,8 +126,8 @@ namespace OpenRA return new Rectangle(offset.X, offset.Y, size.X, size.Y); }); - traitsImplementingRenderModifier = TraitsImplementing().ToArray(); - traitsImplementingRender = TraitsImplementing().ToArray(); + renderModifiers = TraitsImplementing().ToArray(); + renders = TraitsImplementing().ToArray(); } public void Tick() @@ -143,14 +143,14 @@ namespace OpenRA public IEnumerable Render(WorldRenderer wr) { var renderables = Renderables(wr); - foreach (var modifier in traitsImplementingRenderModifier) + foreach (var modifier in renderModifiers) renderables = modifier.ModifyRender(this, wr, renderables); return renderables; } IEnumerable Renderables(WorldRenderer wr) { - foreach (var render in traitsImplementingRender) + foreach (var render in renders) foreach (var renderable in render.Render(this, wr)) yield return renderable; } From 500a33b5905a72f26178a839a6a4547a59519f8a Mon Sep 17 00:00:00 2001 From: RoosterDragon Date: Mon, 20 Apr 2015 21:21:09 +0100 Subject: [PATCH 2/4] Cache some trait lookups that occur frequently. --- OpenRA.Mods.Common/Activities/Move/Move.cs | 5 ++--- OpenRA.Mods.Common/Traits/Mobile.cs | 5 ++++- OpenRA.Mods.Common/Traits/Render/WithMuzzleFlash.cs | 13 ++++++++----- OpenRA.Mods.Common/Traits/Turreted.cs | 5 +++-- 4 files changed, 17 insertions(+), 11 deletions(-) diff --git a/OpenRA.Mods.Common/Activities/Move/Move.cs b/OpenRA.Mods.Common/Activities/Move/Move.cs index 53fbaa5998..1a45d0408b 100644 --- a/OpenRA.Mods.Common/Activities/Move/Move.cs +++ b/OpenRA.Mods.Common/Activities/Move/Move.cs @@ -315,13 +315,12 @@ namespace OpenRA.Mods.Common.Activities public override Activity Tick(Actor self) { - var mobile = self.Trait(); var ret = InnerTick(self, Move.mobile); - mobile.IsMoving = ret is MovePart; + Move.mobile.IsMoving = ret is MovePart; if (moveFraction > MoveFractionTotal) moveFraction = MoveFractionTotal; - UpdateCenterLocation(self, mobile); + UpdateCenterLocation(self, Move.mobile); return ret; } diff --git a/OpenRA.Mods.Common/Traits/Mobile.cs b/OpenRA.Mods.Common/Traits/Mobile.cs index 0d0000c387..78dc552ee2 100644 --- a/OpenRA.Mods.Common/Traits/Mobile.cs +++ b/OpenRA.Mods.Common/Traits/Mobile.cs @@ -312,6 +312,7 @@ namespace OpenRA.Mods.Common.Traits internal int TicksBeforePathing = 0; readonly Actor self; + readonly ISpeedModifier[] speedModifiers; public readonly MobileInfo Info; public bool IsMoving { get; set; } @@ -351,6 +352,8 @@ namespace OpenRA.Mods.Common.Traits self = init.Self; Info = info; + speedModifiers = self.TraitsImplementing().ToArray(); + ToSubCell = FromSubCell = info.SharesCell ? init.World.Map.DefaultSubCell : SubCell.FullCell; if (init.Contains()) FromSubCell = ToSubCell = init.Get(); @@ -597,7 +600,7 @@ namespace OpenRA.Mods.Common.Traits return 0; speed *= Info.Speed; - foreach (var t in self.TraitsImplementing()) + foreach (var t in speedModifiers) speed *= t.GetSpeedModifier() / 100m; return (int)(speed / 100); diff --git a/OpenRA.Mods.Common/Traits/Render/WithMuzzleFlash.cs b/OpenRA.Mods.Common/Traits/Render/WithMuzzleFlash.cs index 253739ce95..e768b56f03 100644 --- a/OpenRA.Mods.Common/Traits/Render/WithMuzzleFlash.cs +++ b/OpenRA.Mods.Common/Traits/Render/WithMuzzleFlash.cs @@ -27,9 +27,10 @@ namespace OpenRA.Mods.Common.Traits class WithMuzzleFlash : UpgradableTrait, INotifyAttack, IRender, ITick { - Dictionary visible = new Dictionary(); - Dictionary anims = new Dictionary(); - Func getFacing; + readonly Dictionary visible = new Dictionary(); + readonly Dictionary anims = new Dictionary(); + readonly Func getFacing; + readonly Armament[] armaments; public WithMuzzleFlash(Actor self, WithMuzzleFlashInfo info) : base(info) @@ -37,7 +38,9 @@ namespace OpenRA.Mods.Common.Traits var render = self.Trait(); var facing = self.TraitOrDefault(); - foreach (var arm in self.TraitsImplementing()) + armaments = self.TraitsImplementing().ToArray(); + + foreach (var arm in armaments) { var armClosure = arm; // closure hazard in AnimationWithOffset @@ -87,7 +90,7 @@ namespace OpenRA.Mods.Common.Traits public IEnumerable Render(Actor self, WorldRenderer wr) { - foreach (var arm in self.TraitsImplementing()) + foreach (var arm in armaments) { var palette = wr.Palette(arm.Info.MuzzlePalette); foreach (var kv in anims) diff --git a/OpenRA.Mods.Common/Traits/Turreted.cs b/OpenRA.Mods.Common/Traits/Turreted.cs index ad78fa147e..1035cea8e5 100644 --- a/OpenRA.Mods.Common/Traits/Turreted.cs +++ b/OpenRA.Mods.Common/Traits/Turreted.cs @@ -13,7 +13,7 @@ using OpenRA.Traits; namespace OpenRA.Mods.Common.Traits { - public class TurretedInfo : ITraitInfo, UsesInit + public class TurretedInfo : ITraitInfo, UsesInit, Requires { public readonly string Turret = "primary"; [Desc("Rate of Turning")] @@ -34,6 +34,7 @@ namespace OpenRA.Mods.Common.Traits readonly TurretedInfo info; AttackTurreted attack; IFacing facing; + IBodyOrientation body; [Sync] public int QuantizedFacings = 0; [Sync] public int TurretFacing = 0; @@ -67,6 +68,7 @@ namespace OpenRA.Mods.Common.Traits { attack = self.TraitOrDefault(); facing = self.TraitOrDefault(); + body = self.Trait(); } public virtual void Tick(Actor self) @@ -94,7 +96,6 @@ namespace OpenRA.Mods.Common.Traits // Turret offset in world-space public WVec Position(Actor self) { - var body = self.Trait(); var bodyOrientation = body.QuantizeOrientation(self, self.Orientation); return body.LocalToWorld(Offset.Rotate(bodyOrientation)); } From 2937a31463a6e8504ab8c758ffd61346c3d1e310 Mon Sep 17 00:00:00 2001 From: RoosterDragon Date: Mon, 20 Apr 2015 22:12:30 +0100 Subject: [PATCH 3/4] Make IsDisabled a method on Actor. This allows us to cache the disabled traits, which simplifies life for some callers since we relieve them of having to cache it, as well as improving perf for all IsDisabled calls. --- OpenRA.Game/Actor.cs | 10 ++++++++++ OpenRA.Game/Traits/CreatesShroud.cs | 2 +- OpenRA.Game/Traits/TraitsInterfaces.cs | 8 -------- OpenRA.Mods.Common/Traits/Render/RenderBuilding.cs | 7 ++----- .../Traits/Render/WithActiveAnimation.cs | 4 +--- OpenRA.Mods.Common/Traits/Render/WithIdleOverlay.cs | 3 +-- .../Traits/Render/WithRepairAnimation.cs | 4 +--- OpenRA.Mods.Common/Traits/Render/WithRepairOverlay.cs | 3 +-- .../Traits/SupportPowers/SupportPowerManager.cs | 2 +- 9 files changed, 18 insertions(+), 25 deletions(-) diff --git a/OpenRA.Game/Actor.cs b/OpenRA.Game/Actor.cs index 1f45274035..4c7b5b8eb9 100644 --- a/OpenRA.Game/Actor.cs +++ b/OpenRA.Game/Actor.cs @@ -85,6 +85,7 @@ namespace OpenRA readonly IRenderModifier[] renderModifiers; readonly IRender[] renders; + readonly IDisable[] disables; internal Actor(World world, string name, TypeDictionary initDict) { @@ -128,6 +129,7 @@ namespace OpenRA renderModifiers = TraitsImplementing().ToArray(); renders = TraitsImplementing().ToArray(); + disables = TraitsImplementing().ToArray(); } public void Tick() @@ -277,6 +279,14 @@ namespace OpenRA health.Value.InflictDamage(this, attacker, health.Value.MaxHP, null, true); } + public bool IsDisabled() + { + foreach (var disable in disables) + if (disable.Disabled) + return true; + return false; + } + #region Scripting interface Lazy luaInterface; diff --git a/OpenRA.Game/Traits/CreatesShroud.cs b/OpenRA.Game/Traits/CreatesShroud.cs index 6adcb682aa..2b6a28b5fc 100644 --- a/OpenRA.Game/Traits/CreatesShroud.cs +++ b/OpenRA.Game/Traits/CreatesShroud.cs @@ -37,7 +37,7 @@ namespace OpenRA.Traits if (lobbyShroudFogDisabled) return; - var disabled = self.TraitsImplementing().Any(d => d.Disabled); + var disabled = self.IsDisabled(); if (cachedLocation != self.Location || cachedDisabled != disabled) { cachedLocation = self.Location; diff --git a/OpenRA.Game/Traits/TraitsInterfaces.cs b/OpenRA.Game/Traits/TraitsInterfaces.cs index 015632cef0..253ddc38dc 100644 --- a/OpenRA.Game/Traits/TraitsInterfaces.cs +++ b/OpenRA.Game/Traits/TraitsInterfaces.cs @@ -329,14 +329,6 @@ namespace OpenRA.Traits void OnObjectiveFailed(Player player, int objectiveID); } - public static class DisableExts - { - public static bool IsDisabled(this Actor a) - { - return a.TraitsImplementing().Any(d => d.Disabled); - } - } - public interface ILegacyEditorRenderInfo { string EditorPalette { get; } diff --git a/OpenRA.Mods.Common/Traits/Render/RenderBuilding.cs b/OpenRA.Mods.Common/Traits/Render/RenderBuilding.cs index fce74db005..f5a36c0daf 100644 --- a/OpenRA.Mods.Common/Traits/Render/RenderBuilding.cs +++ b/OpenRA.Mods.Common/Traits/Render/RenderBuilding.cs @@ -54,11 +54,8 @@ namespace OpenRA.Mods.Common.Traits DefaultAnimation.PlayRepeating(NormalizeSequence(self, info.Sequence)); if (info.PauseOnLowPower) - { - var disabled = self.TraitsImplementing(); - DefaultAnimation.Paused = () => disabled.Any(d => d.Disabled) - && DefaultAnimation.CurrentSequence.Name == NormalizeSequence(self, info.Sequence); - } + DefaultAnimation.Paused = () => + self.IsDisabled() && DefaultAnimation.CurrentSequence.Name == NormalizeSequence(self, info.Sequence); } public void PlayCustomAnimThen(Actor self, string name, Action a) diff --git a/OpenRA.Mods.Common/Traits/Render/WithActiveAnimation.cs b/OpenRA.Mods.Common/Traits/Render/WithActiveAnimation.cs index a372ee24d9..6a4d93cd75 100644 --- a/OpenRA.Mods.Common/Traits/Render/WithActiveAnimation.cs +++ b/OpenRA.Mods.Common/Traits/Render/WithActiveAnimation.cs @@ -30,13 +30,11 @@ namespace OpenRA.Mods.Common.Traits public class WithActiveAnimation : ITick, INotifyBuildComplete, INotifySold { - readonly IEnumerable disabled; readonly WithActiveAnimationInfo info; readonly RenderBuilding renderBuilding; public WithActiveAnimation(Actor self, WithActiveAnimationInfo info) { - disabled = self.TraitsImplementing(); renderBuilding = self.Trait(); this.info = info; } @@ -49,7 +47,7 @@ namespace OpenRA.Mods.Common.Traits if (--ticks <= 0) { - if (!(info.PauseOnLowPower && disabled.Any(d => d.Disabled))) + if (!(info.PauseOnLowPower && self.IsDisabled())) renderBuilding.PlayCustomAnim(self, info.Sequence); ticks = info.Interval; } diff --git a/OpenRA.Mods.Common/Traits/Render/WithIdleOverlay.cs b/OpenRA.Mods.Common/Traits/Render/WithIdleOverlay.cs index 41d427f999..75b381cdd8 100644 --- a/OpenRA.Mods.Common/Traits/Render/WithIdleOverlay.cs +++ b/OpenRA.Mods.Common/Traits/Render/WithIdleOverlay.cs @@ -61,7 +61,6 @@ namespace OpenRA.Mods.Common.Traits { var rs = self.Trait(); var body = self.Trait(); - var disabled = self.TraitsImplementing(); buildComplete = !self.HasTrait(); // always render instantly for units overlay = new Animation(self.World, rs.GetImage(self)); @@ -70,7 +69,7 @@ namespace OpenRA.Mods.Common.Traits new AnimationWithOffset(overlay, () => body.LocalToWorld(info.Offset.Rotate(body.QuantizeOrientation(self, self.Orientation))), () => IsTraitDisabled || !buildComplete, - () => info.PauseOnLowPower && disabled.Any(d => d.Disabled), + () => info.PauseOnLowPower && self.IsDisabled(), p => WithTurret.ZOffsetFromCenter(self, p, 1)), info.Palette, info.IsPlayerPalette); } diff --git a/OpenRA.Mods.Common/Traits/Render/WithRepairAnimation.cs b/OpenRA.Mods.Common/Traits/Render/WithRepairAnimation.cs index 7acfa409fa..d38612c4f6 100644 --- a/OpenRA.Mods.Common/Traits/Render/WithRepairAnimation.cs +++ b/OpenRA.Mods.Common/Traits/Render/WithRepairAnimation.cs @@ -27,19 +27,17 @@ namespace OpenRA.Mods.Common.Traits public class WithRepairAnimation : INotifyRepair { - IEnumerable disabled; WithRepairAnimationInfo info; public WithRepairAnimation(Actor self, WithRepairAnimationInfo info) { - disabled = self.TraitsImplementing(); this.info = info; } public void Repairing(Actor self, Actor host) { var building = host.TraitOrDefault(); - if (building != null && !(info.PauseOnLowPower && disabled.Any(d => d.Disabled))) + if (building != null && !(info.PauseOnLowPower && self.IsDisabled())) building.PlayCustomAnim(host, info.Sequence); } } diff --git a/OpenRA.Mods.Common/Traits/Render/WithRepairOverlay.cs b/OpenRA.Mods.Common/Traits/Render/WithRepairOverlay.cs index 205ed29758..92746f31f1 100644 --- a/OpenRA.Mods.Common/Traits/Render/WithRepairOverlay.cs +++ b/OpenRA.Mods.Common/Traits/Render/WithRepairOverlay.cs @@ -44,7 +44,6 @@ namespace OpenRA.Mods.Common.Traits { var rs = self.Trait(); var body = self.Trait(); - var disabled = self.TraitsImplementing(); buildComplete = !self.HasTrait(); // always render instantly for units overlay = new Animation(self.World, rs.GetImage(self)); @@ -53,7 +52,7 @@ namespace OpenRA.Mods.Common.Traits new AnimationWithOffset(overlay, () => body.LocalToWorld(info.Offset.Rotate(body.QuantizeOrientation(self, self.Orientation))), () => !buildComplete, - () => info.PauseOnLowPower && disabled.Any(d => d.Disabled), + () => info.PauseOnLowPower && self.IsDisabled(), p => WithTurret.ZOffsetFromCenter(self, p, 1)), info.Palette, info.IsPlayerPalette); } diff --git a/OpenRA.Mods.Common/Traits/SupportPowers/SupportPowerManager.cs b/OpenRA.Mods.Common/Traits/SupportPowers/SupportPowerManager.cs index 6f49b1c926..7c9dafe0c4 100644 --- a/OpenRA.Mods.Common/Traits/SupportPowers/SupportPowerManager.cs +++ b/OpenRA.Mods.Common/Traits/SupportPowers/SupportPowerManager.cs @@ -179,7 +179,7 @@ namespace OpenRA.Mods.Common.Traits static bool InstanceDisabled(SupportPower sp) { - return sp.Self.TraitsImplementing().Any(d => d.Disabled); + return sp.Self.IsDisabled(); } bool notifiedCharging; From fb0cab74819002c676652da68ba2a3e99f85a4f9 Mon Sep 17 00:00:00 2001 From: RoosterDragon Date: Mon, 20 Apr 2015 23:48:00 +0100 Subject: [PATCH 4/4] 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. --- OpenRA.Game/GameRules/WeaponInfo.cs | 4 ++-- OpenRA.Mods.Common/Activities/Air/FlyAttack.cs | 6 +++--- OpenRA.Mods.Common/Activities/Air/HeliAttack.cs | 6 +++--- OpenRA.Mods.Common/Activities/Demolish.cs | 4 ++-- OpenRA.Mods.Common/Activities/Move/Drag.cs | 4 ++-- OpenRA.Mods.Common/Activities/Move/Move.cs | 14 +++++++------- OpenRA.Mods.Common/Activities/Rearm.cs | 4 ++-- OpenRA.Mods.Common/Activities/Turn.cs | 4 ++-- .../Scripting/Properties/PowerProperties.cs | 4 ++-- .../Scripting/Properties/ProductionProperties.cs | 4 ++-- OpenRA.Mods.Common/Traits/Armament.cs | 4 ++-- OpenRA.Mods.Common/Traits/Attack/AttackBase.cs | 2 +- OpenRA.Mods.Common/Traits/Attack/AttackTurreted.cs | 5 +++-- OpenRA.Mods.Common/Traits/Render/WithTurret.cs | 4 ++-- OpenRA.Mods.Common/Traits/Repairable.cs | 9 +++------ .../Widgets/ViewportControllerWidget.cs | 6 +++--- OpenRA.Mods.D2k/Traits/ThrowsShrapnel.cs | 4 ++-- OpenRA.Mods.RA/Activities/LayMines.cs | 4 ++-- 18 files changed, 45 insertions(+), 47 deletions(-) diff --git a/OpenRA.Game/GameRules/WeaponInfo.cs b/OpenRA.Game/GameRules/WeaponInfo.cs index 83e96eae68..448c5f8ec7 100644 --- a/OpenRA.Game/GameRules/WeaponInfo.cs +++ b/OpenRA.Game/GameRules/WeaponInfo.cs @@ -19,8 +19,8 @@ namespace OpenRA.GameRules public class ProjectileArgs { public WeaponInfo Weapon; - public IEnumerable DamageModifiers; - public IEnumerable InaccuracyModifiers; + public int[] DamageModifiers; + public int[] InaccuracyModifiers; public int Facing; public WPos Source; public Actor SourceActor; diff --git a/OpenRA.Mods.Common/Activities/Air/FlyAttack.cs b/OpenRA.Mods.Common/Activities/Air/FlyAttack.cs index ef20515a01..806efaba29 100644 --- a/OpenRA.Mods.Common/Activities/Air/FlyAttack.cs +++ b/OpenRA.Mods.Common/Activities/Air/FlyAttack.cs @@ -21,7 +21,7 @@ namespace OpenRA.Mods.Common.Activities { readonly Target target; readonly AttackPlane attackPlane; - readonly IEnumerable ammoPools; + readonly AmmoPool[] ammoPools; Activity inner; int ticksUntilTurn; @@ -29,7 +29,7 @@ namespace OpenRA.Mods.Common.Activities { this.target = target; attackPlane = self.TraitOrDefault(); - ammoPools = self.TraitsImplementing(); + ammoPools = self.TraitsImplementing().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) diff --git a/OpenRA.Mods.Common/Activities/Air/HeliAttack.cs b/OpenRA.Mods.Common/Activities/Air/HeliAttack.cs index 0e2839bd6f..e9155ecf9f 100644 --- a/OpenRA.Mods.Common/Activities/Air/HeliAttack.cs +++ b/OpenRA.Mods.Common/Activities/Air/HeliAttack.cs @@ -22,14 +22,14 @@ namespace OpenRA.Mods.Common.Activities readonly Target target; readonly Helicopter helicopter; readonly AttackHeli attackHeli; - readonly IEnumerable ammoPools; + readonly AmmoPool[] ammoPools; public HeliAttack(Actor self, Target target) { this.target = target; helicopter = self.Trait(); attackHeli = self.Trait(); - ammoPools = self.TraitsImplementing(); + ammoPools = self.TraitsImplementing().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; diff --git a/OpenRA.Mods.Common/Activities/Demolish.cs b/OpenRA.Mods.Common/Activities/Demolish.cs index 1ce0282d2a..c72b89290b 100644 --- a/OpenRA.Mods.Common/Activities/Demolish.cs +++ b/OpenRA.Mods.Common/Activities/Demolish.cs @@ -19,7 +19,7 @@ namespace OpenRA.Mods.Common.Activities class Demolish : Enter { readonly Actor target; - readonly IEnumerable 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(); + demolishables = target.TraitsImplementing().ToArray(); this.delay = delay; this.flashes = flashes; this.flashesDelay = flashesDelay; diff --git a/OpenRA.Mods.Common/Activities/Move/Drag.cs b/OpenRA.Mods.Common/Activities/Move/Drag.cs index b4174169c2..0095b9d6c7 100644 --- a/OpenRA.Mods.Common/Activities/Move/Drag.cs +++ b/OpenRA.Mods.Common/Activities/Move/Drag.cs @@ -19,7 +19,7 @@ namespace OpenRA.Mods.Common.Activities { readonly IPositionable positionable; readonly IMove movement; - readonly IEnumerable moveDisablers; + readonly IDisableMove[] moveDisablers; WPos start, end; int length; int ticks = 0; @@ -28,7 +28,7 @@ namespace OpenRA.Mods.Common.Activities { positionable = self.Trait(); movement = self.TraitOrDefault(); - moveDisablers = self.TraitsImplementing(); + moveDisablers = self.TraitsImplementing().ToArray(); this.start = start; this.end = end; this.length = length; diff --git a/OpenRA.Mods.Common/Activities/Move/Move.cs b/OpenRA.Mods.Common/Activities/Move/Move.cs index 1a45d0408b..9092a14af7 100644 --- a/OpenRA.Mods.Common/Activities/Move/Move.cs +++ b/OpenRA.Mods.Common/Activities/Move/Move.cs @@ -25,7 +25,7 @@ namespace OpenRA.Mods.Common.Activities static readonly List NoPath = new List(); readonly Mobile mobile; - readonly IEnumerable moveDisablers; + readonly IDisableMove[] moveDisablers; readonly WRange nearEnough; readonly Func> getPath; readonly Actor ignoredActor; @@ -43,7 +43,7 @@ namespace OpenRA.Mods.Common.Activities public Move(Actor self, CPos destination) { mobile = self.Trait(); - moveDisablers = self.TraitsImplementing(); + moveDisablers = self.TraitsImplementing().ToArray(); getPath = () => self.World.WorldActor.Trait().FindPath( @@ -60,7 +60,7 @@ namespace OpenRA.Mods.Common.Activities public Move(Actor self, CPos destination, WRange nearEnough) { mobile = self.Trait(); - moveDisablers = self.TraitsImplementing(); + moveDisablers = self.TraitsImplementing().ToArray(); getPath = () => self.World.WorldActor.Trait() .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(); - moveDisablers = self.TraitsImplementing(); + moveDisablers = self.TraitsImplementing().ToArray(); getPath = () => self.World.WorldActor.Trait() .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(); - moveDisablers = self.TraitsImplementing(); + moveDisablers = self.TraitsImplementing().ToArray(); getPath = () => self.World.WorldActor.Trait().FindPath( @@ -97,7 +97,7 @@ namespace OpenRA.Mods.Common.Activities public Move(Actor self, Target target, WRange range) { mobile = self.Trait(); - moveDisablers = self.TraitsImplementing(); + moveDisablers = self.TraitsImplementing().ToArray(); getPath = () => { @@ -115,7 +115,7 @@ namespace OpenRA.Mods.Common.Activities public Move(Actor self, Func> getPath) { mobile = self.Trait(); - moveDisablers = self.TraitsImplementing(); + moveDisablers = self.TraitsImplementing().ToArray(); this.getPath = getPath; diff --git a/OpenRA.Mods.Common/Activities/Rearm.cs b/OpenRA.Mods.Common/Activities/Rearm.cs index 3a63d52d94..6c4bace567 100644 --- a/OpenRA.Mods.Common/Activities/Rearm.cs +++ b/OpenRA.Mods.Common/Activities/Rearm.cs @@ -17,12 +17,12 @@ namespace OpenRA.Mods.Common.Activities { public class Rearm : Activity { - readonly IEnumerable ammoPools; + readonly AmmoPool[] ammoPools; readonly Dictionary ammoPoolsReloadTimes; public Rearm(Actor self) { - ammoPools = self.TraitsImplementing().Where(p => !p.Info.SelfReloads); + ammoPools = self.TraitsImplementing().Where(p => !p.Info.SelfReloads).ToArray(); if (ammoPools == null) return; diff --git a/OpenRA.Mods.Common/Activities/Turn.cs b/OpenRA.Mods.Common/Activities/Turn.cs index bbfc01d302..fe5d986edd 100644 --- a/OpenRA.Mods.Common/Activities/Turn.cs +++ b/OpenRA.Mods.Common/Activities/Turn.cs @@ -17,12 +17,12 @@ namespace OpenRA.Mods.Common.Activities { public class Turn : Activity { - readonly IEnumerable moveDisablers; + readonly IDisableMove[] moveDisablers; readonly int desiredFacing; public Turn(Actor self, int desiredFacing) { - moveDisablers = self.TraitsImplementing(); + moveDisablers = self.TraitsImplementing().ToArray(); this.desiredFacing = desiredFacing; } diff --git a/OpenRA.Mods.Common/Scripting/Properties/PowerProperties.cs b/OpenRA.Mods.Common/Scripting/Properties/PowerProperties.cs index a942f8809d..450ec40076 100644 --- a/OpenRA.Mods.Common/Scripting/Properties/PowerProperties.cs +++ b/OpenRA.Mods.Common/Scripting/Properties/PowerProperties.cs @@ -59,12 +59,12 @@ namespace OpenRA.Mods.Common.Scripting [ScriptPropertyGroup("Power")] public class ActorPowerProperties : ScriptActorProperties, Requires { - readonly IEnumerable power; + readonly PowerTrait[] power; public ActorPowerProperties(ScriptContext context, Actor self) : base(context, self) { - power = self.TraitsImplementing(); + power = self.TraitsImplementing().ToArray(); } [Desc("Returns the power drained/provided by this actor.")] diff --git a/OpenRA.Mods.Common/Scripting/Properties/ProductionProperties.cs b/OpenRA.Mods.Common/Scripting/Properties/ProductionProperties.cs index abc5f73f8b..06d4f607f0 100644 --- a/OpenRA.Mods.Common/Scripting/Properties/ProductionProperties.cs +++ b/OpenRA.Mods.Common/Scripting/Properties/ProductionProperties.cs @@ -84,13 +84,13 @@ namespace OpenRA.Mods.Common.Scripting [ScriptPropertyGroup("Production")] public class ProductionQueueProperties : ScriptActorProperties, Requires, Requires { - readonly List queues; + readonly ProductionQueue[] queues; readonly ScriptTriggers triggers; public ProductionQueueProperties(ScriptContext context, Actor self) : base(context, self) { - queues = self.TraitsImplementing().Where(q => q.Enabled).ToList(); + queues = self.TraitsImplementing().Where(q => q.Enabled).ToArray(); triggers = TriggerGlobal.GetScriptTriggers(self); } diff --git a/OpenRA.Mods.Common/Traits/Armament.cs b/OpenRA.Mods.Common/Traits/Armament.cs index c28b6453c2..4afb573f11 100644 --- a/OpenRA.Mods.Common/Traits/Armament.cs +++ b/OpenRA.Mods.Common/Traits/Armament.cs @@ -167,10 +167,10 @@ namespace OpenRA.Mods.Common.Traits Facing = legacyFacing, DamageModifiers = self.TraitsImplementing() - .Select(a => a.GetFirepowerModifier()), + .Select(a => a.GetFirepowerModifier()).ToArray(), InaccuracyModifiers = self.TraitsImplementing() - .Select(a => a.GetInaccuracyModifier()), + .Select(a => a.GetInaccuracyModifier()).ToArray(), Source = muzzlePosition, SourceActor = self, diff --git a/OpenRA.Mods.Common/Traits/Attack/AttackBase.cs b/OpenRA.Mods.Common/Traits/Attack/AttackBase.cs index a76bccee40..83057ff250 100644 --- a/OpenRA.Mods.Common/Traits/Attack/AttackBase.cs +++ b/OpenRA.Mods.Common/Traits/Attack/AttackBase.cs @@ -53,7 +53,7 @@ namespace OpenRA.Mods.Common.Traits this.self = self; var armaments = Exts.Lazy(() => self.TraitsImplementing() - .Where(a => info.Armaments.Contains(a.Info.Name))); + .Where(a => info.Armaments.Contains(a.Info.Name)).ToArray()); getArmaments = () => armaments.Value; diff --git a/OpenRA.Mods.Common/Traits/Attack/AttackTurreted.cs b/OpenRA.Mods.Common/Traits/Attack/AttackTurreted.cs index 0badcb0b29..aca0f97111 100644 --- a/OpenRA.Mods.Common/Traits/Attack/AttackTurreted.cs +++ b/OpenRA.Mods.Common/Traits/Attack/AttackTurreted.cs @@ -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 turrets; + protected Turreted[] turrets; public AttackTurreted(Actor self, AttackTurretedInfo info) : base(self, info) { - turrets = self.TraitsImplementing(); + turrets = self.TraitsImplementing().ToArray(); } protected override bool CanAttack(Actor self, Target target) diff --git a/OpenRA.Mods.Common/Traits/Render/WithTurret.cs b/OpenRA.Mods.Common/Traits/Render/WithTurret.cs index e13708d5f0..a5c254ee2c 100644 --- a/OpenRA.Mods.Common/Traits/Render/WithTurret.cs +++ b/OpenRA.Mods.Common/Traits/Render/WithTurret.cs @@ -62,7 +62,7 @@ namespace OpenRA.Mods.Common.Traits IBodyOrientation body; AttackBase ab; Turreted t; - IEnumerable arms; + Armament[] arms; Animation anim; public WithTurret(Actor self, WithTurretInfo info) @@ -75,7 +75,7 @@ namespace OpenRA.Mods.Common.Traits t = self.TraitsImplementing() .First(tt => tt.Name == info.Turret); arms = self.TraitsImplementing() - .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); diff --git a/OpenRA.Mods.Common/Traits/Repairable.cs b/OpenRA.Mods.Common/Traits/Repairable.cs index e3df40b5c5..b275311bfa 100644 --- a/OpenRA.Mods.Common/Traits/Repairable.cs +++ b/OpenRA.Mods.Common/Traits/Repairable.cs @@ -29,13 +29,13 @@ namespace OpenRA.Mods.Common.Traits { readonly RepairableInfo info; readonly Health health; - readonly IEnumerable ammoPools; + readonly AmmoPool[] ammoPools; public Repairable(Actor self, RepairableInfo info) { this.info = info; health = self.Trait(); - ammoPools = self.TraitsImplementing(); + ammoPools = self.TraitsImplementing().ToArray(); } public IEnumerable 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) diff --git a/OpenRA.Mods.Common/Widgets/ViewportControllerWidget.cs b/OpenRA.Mods.Common/Widgets/ViewportControllerWidget.cs index eb32bd562a..dbd83528dd 100644 --- a/OpenRA.Mods.Common/Widgets/ViewportControllerWidget.cs +++ b/OpenRA.Mods.Common/Widgets/ViewportControllerWidget.cs @@ -28,7 +28,7 @@ namespace OpenRA.Mods.Common.Widgets public WorldTooltipType TooltipType { get; private set; } public IToolTip ActorTooltip { get; private set; } - public IEnumerable 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().First(); - ActorTooltipExtra = underCursor.TraitsImplementing(); + ActorTooltipExtra = underCursor.TraitsImplementing().ToArray(); TooltipType = WorldTooltipType.Actor; return; } @@ -125,7 +125,7 @@ namespace OpenRA.Mods.Common.Widgets { FrozenActorTooltip = frozen; if (frozen.Actor != null) - ActorTooltipExtra = frozen.Actor.TraitsImplementing(); + ActorTooltipExtra = frozen.Actor.TraitsImplementing().ToArray(); TooltipType = WorldTooltipType.FrozenActor; } } diff --git a/OpenRA.Mods.D2k/Traits/ThrowsShrapnel.cs b/OpenRA.Mods.D2k/Traits/ThrowsShrapnel.cs index c1d7a4abe7..8d024c5efc 100644 --- a/OpenRA.Mods.D2k/Traits/ThrowsShrapnel.cs +++ b/OpenRA.Mods.D2k/Traits/ThrowsShrapnel.cs @@ -50,10 +50,10 @@ namespace OpenRA.Mods.D2k.Traits Facing = self.World.SharedRandom.Next(-1, 255), DamageModifiers = self.TraitsImplementing() - .Select(a => a.GetFirepowerModifier()), + .Select(a => a.GetFirepowerModifier()).ToArray(), InaccuracyModifiers = self.TraitsImplementing() - .Select(a => a.GetInaccuracyModifier()), + .Select(a => a.GetInaccuracyModifier()).ToArray(), Source = self.CenterPosition, SourceActor = self, diff --git a/OpenRA.Mods.RA/Activities/LayMines.cs b/OpenRA.Mods.RA/Activities/LayMines.cs index bff5105113..be26ed2fe9 100644 --- a/OpenRA.Mods.RA/Activities/LayMines.cs +++ b/OpenRA.Mods.RA/Activities/LayMines.cs @@ -25,7 +25,7 @@ namespace OpenRA.Mods.RA.Activities { readonly Minelayer minelayer; readonly MinelayerInfo info; - readonly IEnumerable ammoPools; + readonly AmmoPool[] ammoPools; readonly IMove movement; readonly string[] rearmBuildings; @@ -33,7 +33,7 @@ namespace OpenRA.Mods.RA.Activities { minelayer = self.TraitOrDefault(); info = self.Info.Traits.Get(); - ammoPools = self.TraitsImplementing(); + ammoPools = self.TraitsImplementing().ToArray(); movement = self.Trait(); rearmBuildings = info.RearmBuildings; }