Misc constructor caching

Cache trait look-ups in constructor for various other traits and
activities.
This commit is contained in:
reaperrr
2015-03-14 04:00:39 +01:00
parent 1e9d1a6cb7
commit b52d055eec
11 changed files with 70 additions and 48 deletions

View File

@@ -16,15 +16,19 @@ namespace OpenRA.Mods.Common.Activities
public class CaptureActor : Enter public class CaptureActor : Enter
{ {
readonly Actor actor; readonly Actor actor;
readonly Building building;
readonly Capturable capturable; readonly Capturable capturable;
readonly CapturesInfo capturesInfo; readonly CapturesInfo capturesInfo;
readonly Health health;
public CaptureActor(Actor self, Actor target) public CaptureActor(Actor self, Actor target)
: base(self, target) : base(self, target)
{ {
actor = target; actor = target;
building = actor.TraitOrDefault<Building>();
capturesInfo = self.Info.Traits.Get<CapturesInfo>(); capturesInfo = self.Info.Traits.Get<CapturesInfo>();
capturable = target.Trait<Capturable>(); capturable = target.Trait<Capturable>();
health = actor.Trait<Health>();
} }
protected override bool CanReserve(Actor self) protected override bool CanReserve(Actor self)
@@ -37,20 +41,17 @@ namespace OpenRA.Mods.Common.Activities
if (actor.IsDead || capturable.BeingCaptured) if (actor.IsDead || capturable.BeingCaptured)
return; return;
var b = actor.TraitOrDefault<Building>(); if (building != null && !building.Lock())
if (b != null && !b.Lock())
return; return;
self.World.AddFrameEndTask(w => self.World.AddFrameEndTask(w =>
{ {
if (b != null && b.Locked) if (building != null && building.Locked)
b.Unlock(); building.Unlock();
if (actor.IsDead || capturable.BeingCaptured) if (actor.IsDead || capturable.BeingCaptured)
return; return;
var health = actor.Trait<Health>();
var lowEnoughHealth = health.HP <= capturable.Info.CaptureThreshold * health.MaxHP; var lowEnoughHealth = health.HP <= capturable.Info.CaptureThreshold * health.MaxHP;
if (!capturesInfo.Sabotage || lowEnoughHealth || actor.Owner.NonCombatant) if (!capturesInfo.Sabotage || lowEnoughHealth || actor.Owner.NonCombatant)
{ {
@@ -61,8 +62,8 @@ namespace OpenRA.Mods.Common.Activities
foreach (var t in actor.TraitsImplementing<INotifyCapture>()) foreach (var t in actor.TraitsImplementing<INotifyCapture>())
t.OnCapture(actor, self, oldOwner, self.Owner); t.OnCapture(actor, self, oldOwner, self.Owner);
if (b != null && b.Locked) if (building != null && building.Locked)
b.Unlock(); building.Unlock();
} }
else else
{ {

View File

@@ -17,17 +17,24 @@ namespace OpenRA.Mods.Common.Activities
{ {
class ExternalCaptureActor : Activity class ExternalCaptureActor : Activity
{ {
Target target; readonly ExternalCapturable capturable;
readonly ExternalCapturesInfo capturesInfo;
readonly Mobile mobile;
readonly Target target;
public ExternalCaptureActor(Target target) { this.target = target; } public ExternalCaptureActor(Actor self, Target target)
{
this.target = target;
capturable = target.Actor.Trait<ExternalCapturable>();
capturesInfo = self.Info.Traits.Get<ExternalCapturesInfo>();
mobile = self.Trait<Mobile>();
}
public override Activity Tick(Actor self) public override Activity Tick(Actor self)
{ {
if (target.Type != TargetType.Actor) if (target.Type != TargetType.Actor)
return NextActivity; return NextActivity;
var capturable = target.Actor.Trait<ExternalCapturable>();
if (IsCanceled || !self.IsInWorld || self.IsDead || !target.IsValidFor(self)) if (IsCanceled || !self.IsInWorld || self.IsDead || !target.IsValidFor(self))
{ {
if (capturable.CaptureInProgress) if (capturable.CaptureInProgress)
@@ -36,7 +43,6 @@ namespace OpenRA.Mods.Common.Activities
return NextActivity; return NextActivity;
} }
var mobile = self.Trait<Mobile>();
var nearest = target.Actor.OccupiesSpace.NearestCellTo(mobile.ToCell); var nearest = target.Actor.OccupiesSpace.NearestCellTo(mobile.ToCell);
if ((nearest - mobile.ToCell).LengthSquared > 2) if ((nearest - mobile.ToCell).LengthSquared > 2)
@@ -56,8 +62,6 @@ namespace OpenRA.Mods.Common.Activities
if (capturable.CaptureProgressTime == capturable.Info.CaptureCompleteTime * 25) if (capturable.CaptureProgressTime == capturable.Info.CaptureCompleteTime * 25)
{ {
var capturesInfo = self.Info.Traits.Get<ExternalCapturesInfo>();
self.World.AddFrameEndTask(w => self.World.AddFrameEndTask(w =>
{ {
if (target.Actor.IsDead) if (target.Actor.IsDead)

View File

@@ -17,16 +17,23 @@ namespace OpenRA.Mods.Common.Activities
{ {
class Sell : Activity class Sell : Activity
{ {
readonly Health health;
readonly SellableInfo sellableInfo;
readonly PlayerResources playerResources;
public Sell(Actor self)
{
health = self.TraitOrDefault<Health>();
sellableInfo = self.Info.Traits.Get<SellableInfo>();
playerResources = self.Owner.PlayerActor.Trait<PlayerResources>();
}
public override Activity Tick(Actor self) public override Activity Tick(Actor self)
{ {
var h = self.TraitOrDefault<Health>();
var si = self.Info.Traits.Get<SellableInfo>();
var pr = self.Owner.PlayerActor.Trait<PlayerResources>();
var cost = self.GetSellValue(); var cost = self.GetSellValue();
var refund = (cost * si.RefundPercent * (h == null ? 1 : h.HP)) / (100 * (h == null ? 1 : h.MaxHP)); var refund = (cost * sellableInfo.RefundPercent * (health == null ? 1 : health.HP)) / (100 * (health == null ? 1 : health.MaxHP));
pr.GiveCash(refund); playerResources.GiveCash(refund);
foreach (var ns in self.TraitsImplementing<INotifySold>()) foreach (var ns in self.TraitsImplementing<INotifySold>())
ns.Sold(self); ns.Sold(self);

View File

@@ -25,8 +25,8 @@ namespace OpenRA.Mods.Common.Traits
class Burns : ITick, ISync class Burns : ITick, ISync
{ {
readonly BurnsInfo info;
[Sync] int ticks; [Sync] int ticks;
BurnsInfo info;
public Burns(Actor self, BurnsInfo info) public Burns(Actor self, BurnsInfo info)
{ {

View File

@@ -51,21 +51,20 @@ namespace OpenRA.Mods.Common.Traits
public class ExternalCapturable : ITick public class ExternalCapturable : ITick
{ {
readonly Building building;
[Sync] public int CaptureProgressTime = 0; [Sync] public int CaptureProgressTime = 0;
[Sync] public Actor Captor; [Sync] public Actor Captor;
private Actor self;
public ExternalCapturableInfo Info; public ExternalCapturableInfo Info;
public bool CaptureInProgress { get { return Captor != null; } } public bool CaptureInProgress { get { return Captor != null; } }
public ExternalCapturable(Actor self, ExternalCapturableInfo info) public ExternalCapturable(Actor self, ExternalCapturableInfo info)
{ {
this.self = self;
Info = info; Info = info;
building = self.TraitOrDefault<Building>();
} }
public void BeginCapture(Actor captor) public void BeginCapture(Actor captor)
{ {
var building = self.TraitOrDefault<Building>();
if (building != null) if (building != null)
building.Lock(); building.Lock();
@@ -74,7 +73,6 @@ namespace OpenRA.Mods.Common.Traits
public void EndCapture() public void EndCapture()
{ {
var building = self.TraitOrDefault<Building>();
if (building != null) if (building != null)
building.Unlock(); building.Unlock();

View File

@@ -99,7 +99,7 @@ namespace OpenRA.Mods.Common.Traits
self.CancelActivity(); self.CancelActivity();
self.SetTargetLine(target, Color.Red); self.SetTargetLine(target, Color.Red);
self.QueueActivity(new ExternalCaptureActor(target)); self.QueueActivity(new ExternalCaptureActor(self, target));
} }
} }

View File

@@ -30,6 +30,7 @@ namespace OpenRA.Mods.Common.Traits
class ScaredyCat : ITick, INotifyIdle, INotifyDamage, INotifyAttack, ISpeedModifier, ISync, IRenderInfantrySequenceModifier class ScaredyCat : ITick, INotifyIdle, INotifyDamage, INotifyAttack, ISpeedModifier, ISync, IRenderInfantrySequenceModifier
{ {
readonly ScaredyCatInfo info; readonly ScaredyCatInfo info;
readonly Mobile mobile;
[Sync] readonly Actor self; [Sync] readonly Actor self;
[Sync] int panicStartedTick; [Sync] int panicStartedTick;
bool Panicking { get { return panicStartedTick > 0; } } bool Panicking { get { return panicStartedTick > 0; } }
@@ -41,6 +42,7 @@ namespace OpenRA.Mods.Common.Traits
{ {
this.self = self; this.self = self;
this.info = info; this.info = info;
mobile = self.Trait<Mobile>();
} }
public void Panic() public void Panic()
@@ -68,7 +70,7 @@ namespace OpenRA.Mods.Common.Traits
if (!Panicking) if (!Panicking)
return; return;
self.Trait<Mobile>().Nudge(self, self, true); mobile.Nudge(self, self, true);
} }
public void Damaged(Actor self, AttackInfo e) public void Damaged(Actor self, AttackInfo e)

View File

@@ -27,21 +27,22 @@ namespace OpenRA.Mods.Common.Traits
[Desc("Custom palette name")] [Desc("Custom palette name")]
public readonly string Palette = "effect"; public readonly string Palette = "effect";
public object Create(ActorInitializer init) { return new WithBuildingExplosion(this); } public object Create(ActorInitializer init) { return new WithBuildingExplosion(init.Self, this); }
} }
class WithBuildingExplosion : INotifyKilled class WithBuildingExplosion : INotifyKilled
{ {
WithBuildingExplosionInfo info; WithBuildingExplosionInfo info;
BuildingInfo buildingInfo;
public WithBuildingExplosion(WithBuildingExplosionInfo info) public WithBuildingExplosion(Actor self, WithBuildingExplosionInfo info)
{ {
this.info = info; this.info = info;
buildingInfo = self.Info.Traits.Get<BuildingInfo>();
} }
public void Killed(Actor self, AttackInfo e) public void Killed(Actor self, AttackInfo e)
{ {
var buildingInfo = self.Info.Traits.Get<BuildingInfo>();
var cells = FootprintUtils.UnpathableTiles(self.Info.Name, buildingInfo, self.Location); var cells = FootprintUtils.UnpathableTiles(self.Info.Name, buildingInfo, self.Location);
if (info.Delay > 0) if (info.Delay > 0)

View File

@@ -29,8 +29,14 @@ namespace OpenRA.Mods.Common.Traits
{ {
readonly Actor self; readonly Actor self;
readonly RepairableNearInfo info; readonly RepairableNearInfo info;
readonly IMove movement;
public RepairableNear(Actor self, RepairableNearInfo info) { this.self = self; this.info = info; } public RepairableNear(Actor self, RepairableNearInfo info)
{
this.self = self;
this.info = info;
movement = self.Trait<IMove>();
}
public IEnumerable<IOrderTargeter> Orders public IEnumerable<IOrderTargeter> Orders
{ {
@@ -63,7 +69,6 @@ namespace OpenRA.Mods.Common.Traits
{ {
if (order.OrderString == "RepairNear" && CanRepairAt(order.TargetActor) && ShouldRepair()) if (order.OrderString == "RepairNear" && CanRepairAt(order.TargetActor) && ShouldRepair())
{ {
var movement = self.Trait<IMove>();
var target = Target.FromOrder(self.World, order); var target = Target.FromOrder(self.World, order);
self.CancelActivity(); self.CancelActivity();

View File

@@ -29,12 +29,18 @@ namespace OpenRA.Mods.Common.Traits
{ {
readonly Actor self; readonly Actor self;
readonly Lazy<Health> health; readonly Lazy<Health> health;
readonly SellableInfo info;
readonly Building building;
readonly WithMakeAnimation makeAnimation;
public Sellable(Actor self, SellableInfo info) public Sellable(Actor self, SellableInfo info)
: base(info) : base(info)
{ {
this.self = self; this.self = self;
this.info = info;
health = Exts.Lazy(() => self.TraitOrDefault<Health>()); health = Exts.Lazy(() => self.TraitOrDefault<Health>());
building = self.TraitOrDefault<Building>();
makeAnimation = self.TraitOrDefault<WithMakeAnimation>();
} }
public void ResolveOrder(Actor self, Order order) public void ResolveOrder(Actor self, Order order)
@@ -48,23 +54,21 @@ namespace OpenRA.Mods.Common.Traits
if (IsTraitDisabled) if (IsTraitDisabled)
return; return;
var building = self.TraitOrDefault<Building>();
if (building != null && !building.Lock()) if (building != null && !building.Lock())
return; return;
self.CancelActivity(); self.CancelActivity();
foreach (var s in Info.SellSounds) foreach (var s in info.SellSounds)
Sound.PlayToPlayer(self.Owner, s, self.CenterPosition); Sound.PlayToPlayer(self.Owner, s, self.CenterPosition);
foreach (var ns in self.TraitsImplementing<INotifySold>()) foreach (var ns in self.TraitsImplementing<INotifySold>())
ns.Selling(self); ns.Selling(self);
var makeAnimation = self.TraitOrDefault<WithMakeAnimation>();
if (makeAnimation != null) if (makeAnimation != null)
makeAnimation.Reverse(self, new Sell(), false); makeAnimation.Reverse(self, new Sell(self), false);
else else
self.QueueActivity(false, new Sell()); self.QueueActivity(false, new Sell(self));
} }
public bool IsTooltipVisible(Player forPlayer) public bool IsTooltipVisible(Player forPlayer)
@@ -78,7 +82,7 @@ namespace OpenRA.Mods.Common.Traits
{ {
get get
{ {
var sellValue = self.GetSellValue() * Info.RefundPercent / 100; var sellValue = self.GetSellValue() * info.RefundPercent / 100;
if (health.Value != null) if (health.Value != null)
{ {
sellValue *= health.Value.HP; sellValue *= health.Value.HP;

View File

@@ -46,14 +46,18 @@ namespace OpenRA.Mods.Common.Traits
{ {
readonly Actor self; readonly Actor self;
readonly TransformsInfo info; readonly TransformsInfo info;
readonly BuildingInfo bi; readonly Building building;
readonly BuildingInfo buildingInfo;
readonly string race; readonly string race;
readonly WithMakeAnimation makeAnimation;
public Transforms(ActorInitializer init, TransformsInfo info) public Transforms(ActorInitializer init, TransformsInfo info)
{ {
self = init.Self; self = init.Self;
this.info = info; this.info = info;
bi = self.World.Map.Rules.Actors[info.IntoActor].Traits.GetOrDefault<BuildingInfo>(); buildingInfo = self.World.Map.Rules.Actors[info.IntoActor].Traits.GetOrDefault<BuildingInfo>();
building = self.TraitOrDefault<Building>();
makeAnimation = self.TraitOrDefault<WithMakeAnimation>();
race = init.Contains<RaceInit>() ? init.Get<RaceInit, string>() : self.Owner.Country.Race; race = init.Contains<RaceInit>() ? init.Get<RaceInit, string>() : self.Owner.Country.Race;
} }
@@ -64,11 +68,10 @@ namespace OpenRA.Mods.Common.Traits
bool CanDeploy() bool CanDeploy()
{ {
var b = self.TraitOrDefault<Building>(); if (building != null && building.Locked)
if (b != null && b.Locked)
return false; return false;
return bi == null || self.World.CanPlaceBuilding(info.IntoActor, bi, self.Location + info.Offset, self); return buildingInfo == null || self.World.CanPlaceBuilding(info.IntoActor, buildingInfo, self.Location + info.Offset, self);
} }
public IEnumerable<IOrderTargeter> Orders public IEnumerable<IOrderTargeter> Orders
@@ -86,9 +89,7 @@ namespace OpenRA.Mods.Common.Traits
public void DeployTransform(bool queued) public void DeployTransform(bool queued)
{ {
var b = self.TraitOrDefault<Building>(); if (!CanDeploy() || (building != null && !building.Lock()))
if (!CanDeploy() || (b != null && !b.Lock()))
{ {
foreach (var s in info.NoTransformSounds) foreach (var s in info.NoTransformSounds)
Sound.PlayToPlayer(self.Owner, s); Sound.PlayToPlayer(self.Owner, s);
@@ -116,7 +117,6 @@ namespace OpenRA.Mods.Common.Traits
Race = race Race = race
}; };
var makeAnimation = self.TraitOrDefault<WithMakeAnimation>();
if (makeAnimation != null) if (makeAnimation != null)
makeAnimation.Reverse(self, transform); makeAnimation.Reverse(self, transform);
else else