Reduce duplication and allocations around CalculateFrameIndices.

This commit is contained in:
Paul Chote
2023-03-08 23:18:57 +00:00
committed by Gustas
parent f0cf728825
commit 3b0b15abb9
3 changed files with 21 additions and 34 deletions

View File

@@ -45,15 +45,7 @@ namespace OpenRA.Mods.Cnc.Graphics
var tilesetNode = node.Value.Nodes.FirstOrDefault(n => n.Key == tileset); var tilesetNode = node.Value.Nodes.FirstOrDefault(n => n.Key == tileset);
if (tilesetNode != null) if (tilesetNode != null)
{ {
// Only request the subset of frames that we actually need var loadFrames = CalculateFrameIndices(start, length, stride ?? length ?? 0, facings, frames, transpose, reverseFacings, shadowStart);
int[] loadFrames = null;
if (length != null)
{
loadFrames = CalculateFrameIndices(start, length.Value, stride ?? length.Value, facings, frames, transpose, reverseFacings);
if (shadowStart >= 0)
loadFrames = loadFrames.Concat(loadFrames.Select(i => i + shadowStart - start)).ToArray();
}
return new[] { new ReservationInfo(tilesetNode.Value.Value, loadFrames, frames, tilesetNode.Location) }; return new[] { new ReservationInfo(tilesetNode.Value.Value, loadFrames, frames, tilesetNode.Location) };
} }
} }

View File

@@ -101,11 +101,14 @@ namespace OpenRA.Mods.Common.Graphics
protected readonly struct ReservationInfo protected readonly struct ReservationInfo
{ {
public readonly string Filename; public readonly string Filename;
public readonly int[] LoadFrames; public readonly List<int> LoadFrames;
public readonly int[] Frames; public readonly int[] Frames;
public readonly MiniYamlNode.SourceLocation Location; public readonly MiniYamlNode.SourceLocation Location;
public ReservationInfo(string filename, int[] loadFrames, int[] frames, MiniYamlNode.SourceLocation location) public ReservationInfo(string filename, int[] loadFrames, int[] frames, MiniYamlNode.SourceLocation location)
: this(filename, loadFrames?.ToList(), frames, location) { }
public ReservationInfo(string filename, List<int> loadFrames, int[] frames, MiniYamlNode.SourceLocation location)
{ {
Filename = filename; Filename = filename;
LoadFrames = loadFrames; LoadFrames = loadFrames;
@@ -294,37 +297,37 @@ namespace OpenRA.Mods.Common.Graphics
return Rectangle.FromLTRB(left, top, right, bottom); return Rectangle.FromLTRB(left, top, right, bottom);
} }
protected static int[] CalculateFrameIndices(int start, int length, int stride, int facings, int[] frames, bool transpose, bool reverseFacings) protected static List<int> CalculateFrameIndices(int start, int? length, int stride, int facings, int[] frames, bool transpose, bool reverseFacings, int shadowStart)
{ {
// Request all frames
if (length == null)
return null;
// Only request the subset of frames that we actually need
var usedFrames = new List<int>(); var usedFrames = new List<int>();
for (var facing = 0; facing < facings; facing++) for (var facing = 0; facing < facings; facing++)
{ {
var facingInner = reverseFacings ? (facings - facing) % facings : facing; var facingInner = reverseFacings ? (facings - facing) % facings : facing;
for (var frame = 0; frame < length; frame++) for (var frame = 0; frame < length.Value; frame++)
{ {
var i = transpose ? frame % length * facings + facingInner : var i = transpose ? frame % length.Value * facings + facingInner :
facingInner * stride + frame % length; facingInner * stride + frame % length.Value;
usedFrames.Add(frames?[i] ?? start + i); usedFrames.Add(frames?[i] ?? start + i);
} }
} }
return usedFrames.ToArray(); if (shadowStart >= 0)
usedFrames.AddRange(usedFrames.ToList().Select(i => i + shadowStart - start));
return usedFrames;
} }
protected virtual IEnumerable<ReservationInfo> ParseFilenames(ModData modData, string tileset, int[] frames, MiniYaml data, MiniYaml defaults) protected virtual IEnumerable<ReservationInfo> ParseFilenames(ModData modData, string tileset, int[] frames, MiniYaml data, MiniYaml defaults)
{ {
var filename = LoadField(Filename, data, defaults, out var location); var filename = LoadField(Filename, data, defaults, out var location);
// Only request the subset of frames that we actually need. var loadFrames = CalculateFrameIndices(start, length, stride ?? length ?? 0, facings, frames, transpose, reverseFacings, shadowStart);
int[] loadFrames = null;
if (length != null)
{
loadFrames = CalculateFrameIndices(start, length.Value, stride ?? length.Value, facings, frames, transpose, reverseFacings);
if (shadowStart >= 0)
loadFrames = loadFrames.Concat(loadFrames.Select(i => i + shadowStart - start)).ToArray();
}
yield return new ReservationInfo(filename, loadFrames, frames, location); yield return new ReservationInfo(filename, loadFrames, frames, location);
} }
@@ -502,7 +505,7 @@ namespace OpenRA.Mods.Common.Graphics
alpha = Exts.MakeArray(length.Value, i => float2.Lerp(1f, 0f, i / (length.Value - 1f))); alpha = Exts.MakeArray(length.Value, i => float2.Lerp(1f, 0f, i / (length.Value - 1f)));
// Reindex sprites to order facings anti-clockwise and remove unused frames // Reindex sprites to order facings anti-clockwise and remove unused frames
var index = CalculateFrameIndices(start, length.Value, stride ?? length.Value, facings, null, transpose, reverseFacings).ToList(); var index = CalculateFrameIndices(start, length.Value, stride ?? length.Value, facings, null, transpose, reverseFacings, -1);
if (reverses) if (reverses)
{ {
index.AddRange(index.Skip(1).Take(length.Value - 2).Reverse()); index.AddRange(index.Skip(1).Take(length.Value - 2).Reverse());

View File

@@ -43,15 +43,7 @@ namespace OpenRA.Mods.Common.Graphics
var tilesetNode = node.Value.Nodes.FirstOrDefault(n => n.Key == tileset); var tilesetNode = node.Value.Nodes.FirstOrDefault(n => n.Key == tileset);
if (tilesetNode != null) if (tilesetNode != null)
{ {
// Only request the subset of frames that we actually need var loadFrames = CalculateFrameIndices(start, length, stride ?? length ?? 0, facings, frames, transpose, reverseFacings, shadowStart);
int[] loadFrames = null;
if (length != null)
{
loadFrames = CalculateFrameIndices(start, length.Value, stride ?? length.Value, facings, frames, transpose, reverseFacings);
if (shadowStart >= 0)
loadFrames = loadFrames.Concat(loadFrames.Select(i => i + shadowStart - start)).ToArray();
}
return new[] { new ReservationInfo(tilesetNode.Value.Value, loadFrames, frames, tilesetNode.Location) }; return new[] { new ReservationInfo(tilesetNode.Value.Value, loadFrames, frames, tilesetNode.Location) };
} }
} }