Merge pull request #8028 from RoosterDragon/cache-traits

Cache traits
This commit is contained in:
Paul Chote
2015-04-26 18:23:15 +12:00
30 changed files with 86 additions and 89 deletions

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

@@ -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<ISpeedModifier>().ToArray();
ToSubCell = FromSubCell = info.SharesCell ? init.World.Map.DefaultSubCell : SubCell.FullCell;
if (init.Contains<SubCellInit>())
FromSubCell = ToSubCell = init.Get<SubCellInit, SubCell>();
@@ -597,7 +600,7 @@ namespace OpenRA.Mods.Common.Traits
return 0;
speed *= Info.Speed;
foreach (var t in self.TraitsImplementing<ISpeedModifier>())
foreach (var t in speedModifiers)
speed *= t.GetSpeedModifier() / 100m;
return (int)(speed / 100);

View File

@@ -54,11 +54,8 @@ namespace OpenRA.Mods.Common.Traits
DefaultAnimation.PlayRepeating(NormalizeSequence(self, info.Sequence));
if (info.PauseOnLowPower)
{
var disabled = self.TraitsImplementing<IDisable>();
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)

View File

@@ -30,13 +30,11 @@ namespace OpenRA.Mods.Common.Traits
public class WithActiveAnimation : ITick, INotifyBuildComplete, INotifySold
{
readonly IEnumerable<IDisable> disabled;
readonly WithActiveAnimationInfo info;
readonly RenderBuilding renderBuilding;
public WithActiveAnimation(Actor self, WithActiveAnimationInfo info)
{
disabled = self.TraitsImplementing<IDisable>();
renderBuilding = self.Trait<RenderBuilding>();
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;
}

View File

@@ -61,7 +61,6 @@ namespace OpenRA.Mods.Common.Traits
{
var rs = self.Trait<RenderSprites>();
var body = self.Trait<IBodyOrientation>();
var disabled = self.TraitsImplementing<IDisable>();
buildComplete = !self.HasTrait<Building>(); // 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);
}

View File

@@ -27,9 +27,10 @@ namespace OpenRA.Mods.Common.Traits
class WithMuzzleFlash : UpgradableTrait<WithMuzzleFlashInfo>, INotifyAttack, IRender, ITick
{
Dictionary<Barrel, bool> visible = new Dictionary<Barrel, bool>();
Dictionary<Barrel, AnimationWithOffset> anims = new Dictionary<Barrel, AnimationWithOffset>();
Func<int> getFacing;
readonly Dictionary<Barrel, bool> visible = new Dictionary<Barrel, bool>();
readonly Dictionary<Barrel, AnimationWithOffset> anims = new Dictionary<Barrel, AnimationWithOffset>();
readonly Func<int> 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<RenderSprites>();
var facing = self.TraitOrDefault<IFacing>();
foreach (var arm in self.TraitsImplementing<Armament>())
armaments = self.TraitsImplementing<Armament>().ToArray();
foreach (var arm in armaments)
{
var armClosure = arm; // closure hazard in AnimationWithOffset
@@ -87,7 +90,7 @@ namespace OpenRA.Mods.Common.Traits
public IEnumerable<IRenderable> Render(Actor self, WorldRenderer wr)
{
foreach (var arm in self.TraitsImplementing<Armament>())
foreach (var arm in armaments)
{
var palette = wr.Palette(arm.Info.MuzzlePalette);
foreach (var kv in anims)

View File

@@ -27,19 +27,17 @@ namespace OpenRA.Mods.Common.Traits
public class WithRepairAnimation : INotifyRepair
{
IEnumerable<IDisable> disabled;
WithRepairAnimationInfo info;
public WithRepairAnimation(Actor self, WithRepairAnimationInfo info)
{
disabled = self.TraitsImplementing<IDisable>();
this.info = info;
}
public void Repairing(Actor self, Actor host)
{
var building = host.TraitOrDefault<RenderBuilding>();
if (building != null && !(info.PauseOnLowPower && disabled.Any(d => d.Disabled)))
if (building != null && !(info.PauseOnLowPower && self.IsDisabled()))
building.PlayCustomAnim(host, info.Sequence);
}
}

View File

@@ -44,7 +44,6 @@ namespace OpenRA.Mods.Common.Traits
{
var rs = self.Trait<RenderSprites>();
var body = self.Trait<IBodyOrientation>();
var disabled = self.TraitsImplementing<IDisable>();
buildComplete = !self.HasTrait<Building>(); // 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);
}

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

@@ -179,7 +179,7 @@ namespace OpenRA.Mods.Common.Traits
static bool InstanceDisabled(SupportPower sp)
{
return sp.Self.TraitsImplementing<IDisable>().Any(d => d.Disabled);
return sp.Self.IsDisabled();
}
bool notifiedCharging;

View File

@@ -13,7 +13,7 @@ using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
public class TurretedInfo : ITraitInfo, UsesInit<TurretFacingInit>
public class TurretedInfo : ITraitInfo, UsesInit<TurretFacingInit>, Requires<IBodyOrientationInfo>
{
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<AttackTurreted>();
facing = self.TraitOrDefault<IFacing>();
body = self.Trait<IBodyOrientation>();
}
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<IBodyOrientation>();
var bodyOrientation = body.QuantizeOrientation(self, self.Orientation);
return body.LocalToWorld(Offset.Rotate(bodyOrientation));
}