From 262ab408b549a8257ef87cc21bedb1907ab40f56 Mon Sep 17 00:00:00 2001 From: RoosterDragon Date: Wed, 14 Oct 2015 20:36:32 +0100 Subject: [PATCH] Speed up checks for IOccupySpace trait. Eagerly load the trait (if it exists) in Actor, and use this reference to avoid having to perform self.Info.HasTraitInfo() checks. --- OpenRA.Game/Actor.cs | 18 ++++++++---------- OpenRA.Mods.Common/AI/HackyAI.cs | 2 +- OpenRA.Mods.Common/ActorExts.cs | 2 +- OpenRA.Mods.Common/Traits/Production.cs | 7 ++----- .../Traits/Sound/AmbientSound.cs | 2 +- 5 files changed, 13 insertions(+), 18 deletions(-) diff --git a/OpenRA.Game/Actor.cs b/OpenRA.Game/Actor.cs index 6102305334..e9c3444455 100644 --- a/OpenRA.Game/Actor.cs +++ b/OpenRA.Game/Actor.cs @@ -43,15 +43,7 @@ namespace OpenRA public Rectangle Bounds { get; private set; } public Rectangle VisualBounds { get; private set; } public IEffectiveOwner EffectiveOwner { get; private set; } - public IOccupySpace OccupiesSpace - { - get - { - if (occupySpace == null) - occupySpace = Trait(); - return occupySpace; - } - } + public IOccupySpace OccupiesSpace { get; private set; } public bool IsIdle { get { return currentActivity == null; } } public bool IsDead { get { return Disposed || (health != null && health.IsDead); } } @@ -69,7 +61,6 @@ namespace OpenRA } } - IOccupySpace occupySpace; readonly IFacing facing; readonly Health health; readonly IRenderModifier[] renderModifiers; @@ -96,7 +87,14 @@ namespace OpenRA Info = world.Map.Rules.Actors[name]; foreach (var trait in Info.TraitsInConstructOrder()) + { AddTrait(trait.Create(init)); + + // Some traits rely on properties provided by IOccupySpace in their initialization, + // so we must ready it now, we cannot wait until all traits have finished construction. + if (trait is IOccupySpaceInfo) + OccupiesSpace = Trait(); + } } Bounds = DetermineBounds(); diff --git a/OpenRA.Mods.Common/AI/HackyAI.cs b/OpenRA.Mods.Common/AI/HackyAI.cs index 34cf6974b0..3eb7c07d9c 100644 --- a/OpenRA.Mods.Common/AI/HackyAI.cs +++ b/OpenRA.Mods.Common/AI/HackyAI.cs @@ -574,7 +574,7 @@ namespace OpenRA.Mods.Common.AI // Pick something worth attacking owned by that player var target = World.Actors - .Where(a => a.Owner == enemy && a.Info.HasTraitInfo()) + .Where(a => a.Owner == enemy && a.OccupiesSpace != null) .ClosestTo(World.Map.CenterOfCell(GetRandomBaseCenter())); if (target == null) diff --git a/OpenRA.Mods.Common/ActorExts.cs b/OpenRA.Mods.Common/ActorExts.cs index 651a2ba6f3..a768128115 100644 --- a/OpenRA.Mods.Common/ActorExts.cs +++ b/OpenRA.Mods.Common/ActorExts.cs @@ -23,7 +23,7 @@ namespace OpenRA.Mods.Common if (self.IsDead) return false; - if (!self.Info.HasTraitInfo()) + if (self.OccupiesSpace == null) return false; if (!self.IsInWorld) diff --git a/OpenRA.Mods.Common/Traits/Production.cs b/OpenRA.Mods.Common/Traits/Production.cs index fe645740d0..d424c0eac8 100644 --- a/OpenRA.Mods.Common/Traits/Production.cs +++ b/OpenRA.Mods.Common/Traits/Production.cs @@ -35,12 +35,9 @@ namespace OpenRA.Mods.Common.Traits public readonly ProductionInfo Info; public string Faction { get; private set; } - readonly bool occupiesSpace; - public Production(ActorInitializer init, ProductionInfo info) { Info = info; - occupiesSpace = init.Self.Info.HasTraitInfo(); rp = Exts.Lazy(() => init.Self.IsDead ? null : init.Self.TraitOrDefault()); Faction = init.Contains() ? init.Get() : init.Self.Owner.Faction.InternalName; } @@ -60,7 +57,7 @@ namespace OpenRA.Mods.Common.Traits new OwnerInit(self.Owner), }; - if (occupiesSpace) + if (self.OccupiesSpace != null) { exit = self.Location + exitinfo.ExitCell; var spawn = self.CenterPosition + exitinfo.SpawnOffset; @@ -122,7 +119,7 @@ namespace OpenRA.Mods.Common.Traits var exit = self.Info.TraitInfos().Shuffle(self.World.SharedRandom) .FirstOrDefault(e => CanUseExit(self, producee, e)); - if (exit != null || !occupiesSpace) + if (exit != null || self.OccupiesSpace == null) { DoProduction(self, producee, exit, factionVariant); return true; diff --git a/OpenRA.Mods.Common/Traits/Sound/AmbientSound.cs b/OpenRA.Mods.Common/Traits/Sound/AmbientSound.cs index 056d6f83b3..9b1ca95441 100644 --- a/OpenRA.Mods.Common/Traits/Sound/AmbientSound.cs +++ b/OpenRA.Mods.Common/Traits/Sound/AmbientSound.cs @@ -25,7 +25,7 @@ namespace OpenRA.Mods.Common.Traits { public AmbientSound(Actor self, AmbientSoundInfo info) { - if (self.Info.HasTraitInfo()) + if (self.OccupiesSpace != null) Game.Sound.PlayLooped(info.SoundFile, self.CenterPosition); else Game.Sound.PlayLooped(info.SoundFile);