Avoid allocations when generating RadarSignatureCells.
The RadarWidget can supply a reusable buffer to each trait to avoid individual traits having to return new enumerables. Additionally, this allows the two traits to avoid LINQ and further allocations as they can manually enumerate and populate the buffer themselves.
This commit is contained in:
@@ -30,12 +30,8 @@ namespace OpenRA.Mods.Common.Traits.Radar
|
|||||||
|
|
||||||
public class AppearsOnRadar : ConditionalTrait<AppearsOnRadarInfo>, IRadarSignature
|
public class AppearsOnRadar : ConditionalTrait<AppearsOnRadarInfo>, IRadarSignature
|
||||||
{
|
{
|
||||||
static readonly IEnumerable<Pair<CPos, Color>> NoCells = Enumerable.Empty<Pair<CPos, Color>>();
|
|
||||||
IRadarColorModifier modifier;
|
IRadarColorModifier modifier;
|
||||||
|
|
||||||
Color currentColor = Color.Transparent;
|
|
||||||
Func<Pair<CPos, SubCell>, Pair<CPos, Color>> cellToSignature;
|
|
||||||
|
|
||||||
public AppearsOnRadar(AppearsOnRadarInfo info)
|
public AppearsOnRadar(AppearsOnRadarInfo info)
|
||||||
: base(info) { }
|
: base(info) { }
|
||||||
|
|
||||||
@@ -45,27 +41,24 @@ namespace OpenRA.Mods.Common.Traits.Radar
|
|||||||
modifier = self.TraitsImplementing<IRadarColorModifier>().FirstOrDefault();
|
modifier = self.TraitsImplementing<IRadarColorModifier>().FirstOrDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<Pair<CPos, Color>> RadarSignatureCells(Actor self)
|
public void PopulateRadarSignatureCells(Actor self, List<Pair<CPos, Color>> destinationBuffer)
|
||||||
{
|
{
|
||||||
var viewer = self.World.RenderPlayer ?? self.World.LocalPlayer;
|
var viewer = self.World.RenderPlayer ?? self.World.LocalPlayer;
|
||||||
if (IsTraitDisabled || (viewer != null && !Info.ValidStances.HasStance(self.Owner.Stances[viewer])))
|
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;
|
var color = Game.Settings.Game.UsePlayerStanceColors ? self.Owner.PlayerStanceColor(self) : self.Owner.Color.RGB;
|
||||||
if (modifier != null)
|
if (modifier != null)
|
||||||
color = modifier.RadarColorOverride(self, color);
|
color = modifier.RadarColorOverride(self, color);
|
||||||
|
|
||||||
if (Info.UseLocation)
|
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;
|
destinationBuffer.Add(Pair.New(self.Location, color));
|
||||||
cellToSignature = c => Pair.New(c.First, color);
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return self.OccupiesSpace.OccupiedCells().Select(cellToSignature);
|
foreach (var cell in self.OccupiesSpace.OccupiedCells())
|
||||||
|
destinationBuffer.Add(Pair.New(cell.First, color));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -272,9 +272,11 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
return nodes;
|
return nodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<Pair<CPos, Color>> RadarSignatureCells(Actor self)
|
public void PopulateRadarSignatureCells(Actor self, List<Pair<CPos, Color>> 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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -354,7 +354,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
public interface IRadarSignature
|
public interface IRadarSignature
|
||||||
{
|
{
|
||||||
IEnumerable<Pair<CPos, Color>> RadarSignatureCells(Actor self);
|
void PopulateRadarSignatureCells(Actor self, List<Pair<CPos, Color>> destinationBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface IRadarColorModifier { Color RadarColorOverride(Actor self, Color color); }
|
public interface IRadarColorModifier { Color RadarColorOverride(Actor self, Color color); }
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ using System.Drawing;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using OpenRA.Graphics;
|
using OpenRA.Graphics;
|
||||||
using OpenRA.Mods.Common.Traits;
|
using OpenRA.Mods.Common.Traits;
|
||||||
|
using OpenRA.Primitives;
|
||||||
using OpenRA.Traits;
|
using OpenRA.Traits;
|
||||||
using OpenRA.Widgets;
|
using OpenRA.Widgets;
|
||||||
|
|
||||||
@@ -361,6 +362,8 @@ namespace OpenRA.Mods.Common.Widgets
|
|||||||
var stride = radarSheet.Size.Width;
|
var stride = radarSheet.Size.Width;
|
||||||
Array.Clear(radarData, 4 * actorSprite.Bounds.Top * stride, 4 * actorSprite.Bounds.Height * stride);
|
Array.Clear(radarData, 4 * actorSprite.Bounds.Top * stride, 4 * actorSprite.Bounds.Height * stride);
|
||||||
|
|
||||||
|
var cells = new List<Pair<CPos, Color>>();
|
||||||
|
|
||||||
unsafe
|
unsafe
|
||||||
{
|
{
|
||||||
fixed (byte* colorBytes = &radarData[0])
|
fixed (byte* colorBytes = &radarData[0])
|
||||||
@@ -372,7 +375,9 @@ namespace OpenRA.Mods.Common.Widgets
|
|||||||
if (!t.Actor.IsInWorld || world.FogObscures(t.Actor))
|
if (!t.Actor.IsInWorld || world.FogObscures(t.Actor))
|
||||||
continue;
|
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))
|
if (!world.Map.Contains(cell.First))
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
Reference in New Issue
Block a user