Rewrite sequence loading logic.

Multiple layers of Lazy<T>ness are replaced with
an explicit two-part loading scheme.

Sequences are parsed immediately, without the need
for the sprite assets, and tell the SpriteCache
which frames they need. Use-cases that want the
actual sprites can then tell the SpriteCache to
load the frames and the sequences to resolve the
sprites.
This commit is contained in:
Paul Chote
2023-03-09 20:39:17 +00:00
committed by Gustas
parent 1f3403717b
commit c35ab081ff
21 changed files with 780 additions and 632 deletions

View File

@@ -10,7 +10,7 @@
#endregion
using System;
using OpenRA.Mods.Common.Graphics;
using OpenRA.Graphics;
using OpenRA.Mods.Common.Terrain;
using OpenRA.Mods.Common.Traits;
@@ -38,29 +38,21 @@ namespace OpenRA.Mods.Common.UtilityCommands
// any tilesets from being checked further.
try
{
// DefaultSequences is a dictionary of tileset: SequenceProvider
// so we can also use this to key our tileset checks
foreach (var kv in modData.DefaultSequences)
foreach (var (tileset, terrainInfo) in modData.DefaultTerrainInfo)
{
try
{
Console.WriteLine("Tileset: " + kv.Key);
var terrainInfo = modData.DefaultTerrainInfo[kv.Key];
Console.WriteLine("Tileset: " + tileset);
if (terrainInfo is ITemplatedTerrainInfo templatedTerrainInfo)
foreach (var r in modData.DefaultRules.Actors[SystemActors.World].TraitInfos<ITiledTerrainRendererInfo>())
failed |= r.ValidateTileSprites(templatedTerrainInfo, Console.WriteLine);
foreach (var ttr in modData.DefaultRules.Actors[SystemActors.World].TraitInfos<ITiledTerrainRendererInfo>())
failed |= ttr.ValidateTileSprites(templatedTerrainInfo, Console.WriteLine);
foreach (var image in kv.Value.Images)
var sequences = new SequenceSet(modData.DefaultFileSystem, modData, tileset, null);
sequences.SpriteCache.LoadReservations(modData);
foreach (var (filename, location) in sequences.SpriteCache.MissingFiles)
{
foreach (var sequence in kv.Value.Sequences(image))
{
if (!(kv.Value.GetSequence(image, sequence) is FileNotFoundSequence s))
continue;
Console.WriteLine("\tSequence `{0}.{1}` references sprite `{2}` that does not exist.", image, sequence, s.Filename);
failed = true;
}
Console.WriteLine($"\t{location}: {filename} not found");
failed = true;
}
}
catch (YamlException e)

View File

@@ -67,7 +67,7 @@ namespace OpenRA.Mods.Common.UtilityCommands
{
Console.WriteLine($"Testing default sequences for {tileset}");
var sequences = new SequenceProvider(modData.DefaultFileSystem, modData, tileset, null);
var sequences = new SequenceSet(modData.DefaultFileSystem, modData, tileset, null);
CheckSequences(modData, modData.DefaultRules, sequences);
}
@@ -165,7 +165,7 @@ namespace OpenRA.Mods.Common.UtilityCommands
}
}
void CheckSequences(ModData modData, Ruleset rules, SequenceProvider sequences)
void CheckSequences(ModData modData, Ruleset rules, SequenceSet sequences)
{
foreach (var customSequencesPassType in modData.ObjectCreator.GetTypesImplementing<ILintSequencesPass>())
{

View File

@@ -34,8 +34,10 @@ namespace OpenRA.Mods.Common.UtilityCommands
var palette = new ImmutablePalette(args[1], new[] { 0 }, Array.Empty<int>());
SequenceProvider sequences;
if (!modData.DefaultSequences.TryGetValue(args[2], out sequences))
SequenceSet sequences;
if (modData.DefaultTerrainInfo.ContainsKey(args[2]))
sequences = new SequenceSet(modData.ModFiles, modData, args[2], null);
else
{
var mapPackage = new Folder(Platform.EngineDir).OpenPackage(args[2], modData.ModFiles);
if (mapPackage == null)
@@ -44,7 +46,7 @@ namespace OpenRA.Mods.Common.UtilityCommands
sequences = new Map(modData, mapPackage).Sequences;
}
sequences.Preload();
sequences.LoadSprites();
var count = 0;

View File

@@ -51,8 +51,7 @@ namespace OpenRA.Mods.Common.UtilityCommands
var relatedEnumTypes = new HashSet<Type>();
var sequenceTypesInfo = sequenceTypes
.Where(x => !x.ContainsGenericParameters && !x.IsAbstract
&& x.Name != nameof(FileNotFoundSequence)) // NOTE: This is the simplest way to exclude FileNotFoundSequence, which shouldn't be added.
.Where(x => !x.ContainsGenericParameters && !x.IsAbstract)
.Select(type => new
{
type.Namespace,

View File

@@ -17,5 +17,5 @@ namespace OpenRA.Mods.Common.Lint
public interface ILintPass { void Run(Action<string> emitError, Action<string> emitWarning, ModData modData); }
public interface ILintMapPass { void Run(Action<string> emitError, Action<string> emitWarning, ModData modData, Map map); }
public interface ILintRulesPass { void Run(Action<string> emitError, Action<string> emitWarning, ModData modData, Ruleset rules); }
public interface ILintSequencesPass { void Run(Action<string> emitError, Action<string> emitWarning, ModData modData, Ruleset rules, SequenceProvider sequences); }
public interface ILintSequencesPass { void Run(Action<string> emitError, Action<string> emitWarning, ModData modData, Ruleset rules, SequenceSet sequences); }
}