6public static class AnimationDefinitionValidator
14 public static IReadOnlyList<string> Validate(AnimationDefinition definition)
16 ArgumentNullException.ThrowIfNull(definition);
18 var errors =
new List<string>();
20 if (
string.IsNullOrWhiteSpace(definition.Key))
21 errors.Add(
"Animation key is empty.");
23 if (!
double.IsFinite(definition.ThrottleTime) || definition.ThrottleTime < 0)
24 errors.Add(
"ThrottleTime must be a finite, non-negative number.");
26 if (!Enum.IsDefined(definition.CycleType))
27 errors.Add($
"Unknown cycle type '{definition.CycleType}'.");
29 definition.TilesheetSources ??= [];
30 var sourceNames =
new HashSet<string>(StringComparer.Ordinal);
32 for (
int i = 0; i < definition.TilesheetSources.Count; i++)
34 var source = definition.TilesheetSources[i];
35 var label = $
"Tilesheet source {i}";
39 errors.Add($
"{label}: source definition is null.");
43 if (
string.IsNullOrWhiteSpace(source.Tilesheet))
45 errors.Add($
"{label}: tilesheet name is empty.");
47 else if (!sourceNames.Add(source.Tilesheet))
50 $
"{label}: duplicate source for tilesheet '{source.Tilesheet}'.");
53 if (!Enum.IsDefined(source.Kind))
55 errors.Add($
"{label}: unknown source kind '{source.Kind}'.");
62 if (
string.IsNullOrWhiteSpace(source.GtsPath))
63 errors.Add($
"{label}: loose GTS source path is empty.");
67 if (
string.IsNullOrWhiteSpace(source.AssetsFilePath))
68 errors.Add($
"{label}: assets file path is empty.");
70 if (
string.IsNullOrWhiteSpace(source.AssetEntryName))
71 errors.Add($
"{label}: packed GTS entry name is empty.");
76 definition.Frames ??= [];
77 if (definition.Frames.Count == 0)
78 errors.Add(
"Animation must contain at least one frame.");
80 for (
int i = 0; i < definition.Frames.Count; i++)
82 var frame = definition.Frames[i];
83 var label = $
"Frame {i}";
87 errors.Add($
"{label}: frame definition is null.");
91 if (
string.IsNullOrWhiteSpace(frame.Tilesheet))
92 errors.Add($
"{label}: tilesheet name is empty.");
94 if (
string.IsNullOrWhiteSpace(frame.RegionName))
95 errors.Add($
"{label}: region name is empty.");
97 if (frame.XTile < 0 || frame.YTile < 0)
98 errors.Add($
"{label}: frame coordinates cannot be negative.");
100 if (frame.DurationSeconds is { } duration && (!
double.IsFinite(duration) || duration <= 0))
101 errors.Add($
"{label}: DurationSeconds must be finite and positive, or null for ThrottleTime.");
AnimationTilesheetSourceKind
Identifies how a GANI definition can locate one of its logical GTS dependencies for authoring and too...