From 34a68cd2cad1106debee0eaabea8daa434db068a Mon Sep 17 00:00:00 2001 From: RoosterDragon Date: Sat, 15 Jun 2024 21:29:38 +0100 Subject: [PATCH] Avoid keeping ActorInitializers in memory. The SupportPowerManager and WithSpriteBody trait captured the ActorInitializer in lambda expressions, which keeps it alive as long as the trait. The lambdas didn't need to capture the ActorInitializer, so rejig them to allow the ActorInitializer to be reclaimed after the traits have been created. As the TypeDictionary in the ActorInitializer can be quite large, this helps reduce memory usage. --- OpenRA.Mods.Common/Traits/Render/WithSpriteBody.cs | 12 +++++++----- .../Traits/SupportPowers/SupportPowerManager.cs | 2 +- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/OpenRA.Mods.Common/Traits/Render/WithSpriteBody.cs b/OpenRA.Mods.Common/Traits/Render/WithSpriteBody.cs index 91ba850e9c..feeb08ce51 100644 --- a/OpenRA.Mods.Common/Traits/Render/WithSpriteBody.cs +++ b/OpenRA.Mods.Common/Traits/Render/WithSpriteBody.cs @@ -72,20 +72,22 @@ namespace OpenRA.Mods.Common.Traits.Render protected WithSpriteBody(ActorInitializer init, WithSpriteBodyInfo info, Func baseFacing) : base(info) { - var rs = init.Self.Trait(); + var self = init.Self; + + var rs = self.Trait(); bool Paused() => IsTraitPaused && - DefaultAnimation.CurrentSequence.Name == NormalizeSequence(init.Self, Info.Sequence); + DefaultAnimation.CurrentSequence.Name == NormalizeSequence(self, Info.Sequence); Func subtractDAT = null; if (info.ForceToGround) - subtractDAT = () => new WVec(0, 0, -init.Self.World.Map.DistanceAboveTerrain(init.Self.CenterPosition).Length); + subtractDAT = () => new WVec(0, 0, -self.World.Map.DistanceAboveTerrain(self.CenterPosition).Length); - DefaultAnimation = new Animation(init.World, rs.GetImage(init.Self), baseFacing, Paused); + DefaultAnimation = new Animation(init.World, rs.GetImage(self), baseFacing, Paused); rs.Add(new AnimationWithOffset(DefaultAnimation, subtractDAT, () => IsTraitDisabled), info.Palette, info.IsPlayerPalette); // Cache the bounds from the default sequence to avoid flickering when the animation changes - boundsAnimation = new Animation(init.World, rs.GetImage(init.Self), baseFacing, Paused); + boundsAnimation = new Animation(init.World, rs.GetImage(self), baseFacing, Paused); boundsAnimation.PlayRepeating(info.Sequence); } diff --git a/OpenRA.Mods.Common/Traits/SupportPowers/SupportPowerManager.cs b/OpenRA.Mods.Common/Traits/SupportPowers/SupportPowerManager.cs index 19e46b7a11..2ee754ebd9 100644 --- a/OpenRA.Mods.Common/Traits/SupportPowers/SupportPowerManager.cs +++ b/OpenRA.Mods.Common/Traits/SupportPowers/SupportPowerManager.cs @@ -39,7 +39,7 @@ namespace OpenRA.Mods.Common.Traits Self = init.Self; DevMode = Self.Trait(); TechTree = Self.Trait(); - RadarPings = Exts.Lazy(() => init.World.WorldActor.TraitOrDefault()); + RadarPings = Exts.Lazy(() => Self.World.WorldActor.TraitOrDefault()); init.World.ActorAdded += ActorAdded; init.World.ActorRemoved += ActorRemoved;