4public static class SpriteDefinitionValidator
11 public static IReadOnlyList<string> Validate(SpriteDefinition definition) => Validate(definition,
false);
13 internal static IReadOnlyList<string> Validate(SpriteDefinition definition,
bool allowDuplicateNicknames)
15 ArgumentNullException.ThrowIfNull(definition);
16 var errors =
new List<string>();
17 var ids =
new HashSet<Guid>();
18 var names =
new HashSet<string>(StringComparer.Ordinal);
19 if (definition.Sprites is
null)
20 errors.Add(
"Sprites collection is required.");
21 foreach (var sprite
in definition.Sprites ?? [])
23 if (sprite is
null) { errors.Add(
"Sprites cannot contain null entries.");
continue; }
24 var label = $
"Sprite '{sprite.Nickname ?? sprite.Id.ToString()}'";
25 if (sprite.Id != Guid.Empty && !ids.Add(sprite.Id)) errors.Add($
"{label}: duplicate Id.");
26 if (!
string.IsNullOrWhiteSpace(sprite.Nickname) && !names.Add(sprite.Nickname) && !allowDuplicateNicknames) errors.Add($
"{label}: duplicate Nickname.");
27 if (
string.IsNullOrWhiteSpace(sprite.SceneId)) errors.Add($
"{label}: SceneId is required.");
28 if (
string.IsNullOrWhiteSpace(sprite.SceneLayerId)) errors.Add($
"{label}: SceneLayerId is required.");
30 if (sprite.Frame is { } frame)
32 if (
string.IsNullOrWhiteSpace(frame.Tilesheet)) errors.Add($
"{label}: Frame Tilesheet is required.");
33 if (
string.IsNullOrWhiteSpace(frame.RegionName)) errors.Add($
"{label}: Frame RegionName is required.");
34 if (frame.XTile < 0 || frame.YTile < 0) errors.Add($
"{label}: Frame coordinates must be nonnegative.");
36 if (!
float.IsFinite(sprite.Position.X) || !
float.IsFinite(sprite.Position.Y)) errors.Add($
"{label}: Position must be finite.");
37 if (!
float.IsFinite(sprite.Rotation)) errors.Add($
"{label}: Rotation must be finite.");
38 if (sprite.RenderSize.Width < 0 || sprite.RenderSize.Height < 0) errors.Add($
"{label}: RenderSize must be nonnegative.");
39 if (sprite.ZOrder < 1) errors.Add($
"{label}: ZOrder must be at least 1.");
40 if (!Enum.IsDefined(sprite.HorizAlign) || !Enum.IsDefined(sprite.VertAlign)) errors.Add($
"{label}: invalid alignment.");
41 if (!Enum.IsDefined(sprite.CollisionType)) errors.Add($
"{label}: invalid CollisionType.");
43 var sheets =
new HashSet<string>(StringComparer.Ordinal);
44 foreach (var source
in definition.TilesheetSources ?? [])
46 if (source is
null) { errors.Add(
"Null TilesheetSources entry.");
continue; }
47 if (
string.IsNullOrWhiteSpace(source.Tilesheet) || !sheets.Add(source.Tilesheet)) errors.Add(
"Invalid or duplicate TilesheetSources identity.");
48 ValidateSource(source.Kind ==
SpriteTilesheetSourceKind.LooseDefinitionFile, Enum.IsDefined(source.Kind), source.GtsPath, source.AssetsFilePath, source.AssetEntryName,
"TilesheetSources", errors);
50 var scenes =
new HashSet<string>(StringComparer.Ordinal);
51 foreach (var source
in definition.SceneSources ?? [])
53 if (source is
null) { errors.Add(
"Null SceneSources entry.");
continue; }
54 if (
string.IsNullOrWhiteSpace(source.SceneId) || !scenes.Add(source.SceneId)) errors.Add(
"Invalid or duplicate SceneSources identity.");
55 ValidateSource(source.Kind ==
SpriteSceneSourceKind.LooseDefinitionFile, Enum.IsDefined(source.Kind), source.GscnPath, source.AssetsFilePath, source.AssetEntryName,
"SceneSources", errors);
60 private static void ValidateSource(
bool loose,
bool validKind,
string? path,
string? archive,
string? entry,
string label, List<string> errors)
62 if (!validKind || (loose ?
string.IsNullOrWhiteSpace(path) :
string.IsNullOrWhiteSpace(archive) ||
string.IsNullOrWhiteSpace(entry)))
63 errors.Add($
"{label}: source location is incomplete or invalid.");
SpriteSceneSourceKind
Identifies how a GSPR definition can locate one of its logical GSCN dependencies for authoring and to...
SpriteTilesheetSourceKind
Identifies how a GSPR definition can locate one of its logical GTS dependencies for authoring and too...