diff --git a/OpenRA.Mods.Common/Traits/Radar/AppearsOnRadar.cs b/OpenRA.Mods.Common/Traits/Radar/AppearsOnRadar.cs index e23d141c55..344c037125 100644 --- a/OpenRA.Mods.Common/Traits/Radar/AppearsOnRadar.cs +++ b/OpenRA.Mods.Common/Traits/Radar/AppearsOnRadar.cs @@ -30,12 +30,8 @@ namespace OpenRA.Mods.Common.Traits.Radar public class AppearsOnRadar : ConditionalTrait, IRadarSignature { - static readonly IEnumerable> NoCells = Enumerable.Empty>(); IRadarColorModifier modifier; - Color currentColor = Color.Transparent; - Func, Pair> cellToSignature; - public AppearsOnRadar(AppearsOnRadarInfo info) : base(info) { } @@ -45,27 +41,24 @@ namespace OpenRA.Mods.Common.Traits.Radar modifier = self.TraitsImplementing().FirstOrDefault(); } - public IEnumerable> RadarSignatureCells(Actor self) + public void PopulateRadarSignatureCells(Actor self, List> destinationBuffer) { var viewer = self.World.RenderPlayer ?? self.World.LocalPlayer; if (IsTraitDisabled || (viewer != null && !Info.ValidStances.HasStance(self.Owner.Stances[viewer]))) - return NoCells; + return; var color = Game.Settings.Game.UsePlayerStanceColors ? self.Owner.PlayerStanceColor(self) : self.Owner.Color.RGB; if (modifier != null) color = modifier.RadarColorOverride(self, color); if (Info.UseLocation) - return new[] { Pair.New(self.Location, color) }; - - // PERF: Cache cellToSignature delegate to avoid allocations as color does not change often. - if (currentColor != color) { - currentColor = color; - cellToSignature = c => Pair.New(c.First, color); + destinationBuffer.Add(Pair.New(self.Location, color)); + return; } - return self.OccupiesSpace.OccupiedCells().Select(cellToSignature); + foreach (var cell in self.OccupiesSpace.OccupiedCells()) + destinationBuffer.Add(Pair.New(cell.First, color)); } } } \ No newline at end of file diff --git a/OpenRA.Mods.Common/Traits/World/EditorActorLayer.cs b/OpenRA.Mods.Common/Traits/World/EditorActorLayer.cs index c8d8b83765..7e9e18ee33 100644 --- a/OpenRA.Mods.Common/Traits/World/EditorActorLayer.cs +++ b/OpenRA.Mods.Common/Traits/World/EditorActorLayer.cs @@ -272,9 +272,11 @@ namespace OpenRA.Mods.Common.Traits return nodes; } - public IEnumerable> RadarSignatureCells(Actor self) + public void PopulateRadarSignatureCells(Actor self, List> destinationBuffer) { - return cellMap.SelectMany(c => c.Value.Select(p => Pair.New(c.Key, p.Owner.Color.RGB))); + foreach (var previewsForCell in cellMap) + foreach (var preview in previewsForCell.Value) + destinationBuffer.Add(Pair.New(previewsForCell.Key, preview.Owner.Color.RGB)); } } } diff --git a/OpenRA.Mods.Common/TraitsInterfaces.cs b/OpenRA.Mods.Common/TraitsInterfaces.cs index e63781d448..d51bdee682 100644 --- a/OpenRA.Mods.Common/TraitsInterfaces.cs +++ b/OpenRA.Mods.Common/TraitsInterfaces.cs @@ -354,7 +354,7 @@ namespace OpenRA.Mods.Common.Traits public interface IRadarSignature { - IEnumerable> RadarSignatureCells(Actor self); + void PopulateRadarSignatureCells(Actor self, List> destinationBuffer); } public interface IRadarColorModifier { Color RadarColorOverride(Actor self, Color color); } diff --git a/OpenRA.Mods.Common/Widgets/RadarWidget.cs b/OpenRA.Mods.Common/Widgets/RadarWidget.cs index c12f51938d..bdaf4c8d7d 100644 --- a/OpenRA.Mods.Common/Widgets/RadarWidget.cs +++ b/OpenRA.Mods.Common/Widgets/RadarWidget.cs @@ -15,6 +15,7 @@ using System.Drawing; using System.Linq; using OpenRA.Graphics; using OpenRA.Mods.Common.Traits; +using OpenRA.Primitives; using OpenRA.Traits; using OpenRA.Widgets; @@ -361,6 +362,8 @@ namespace OpenRA.Mods.Common.Widgets var stride = radarSheet.Size.Width; Array.Clear(radarData, 4 * actorSprite.Bounds.Top * stride, 4 * actorSprite.Bounds.Height * stride); + var cells = new List>(); + unsafe { fixed (byte* colorBytes = &radarData[0]) @@ -372,7 +375,9 @@ namespace OpenRA.Mods.Common.Widgets if (!t.Actor.IsInWorld || world.FogObscures(t.Actor)) continue; - foreach (var cell in t.Trait.RadarSignatureCells(t.Actor)) + cells.Clear(); + t.Trait.PopulateRadarSignatureCells(t.Actor, cells); + foreach (var cell in cells) { if (!world.Map.Contains(cell.First)) continue;