Gondwana Game Engine Development (master) - 2.6.1
Gondwana is a cross-platform 2.5D game and rendering engine written in C#/.NET 8. It provides fine-grained control over rendering, timing, and scene composition, with built-in support for parallax, z-ordering, pixel overhang, collision detection, and particle effects. Gondwana targets desktop and web platforms using SkiaSharp for graphics and pluggable audio backends for desktop and browser targets.
Loading...
Searching...
No Matches
AudioDefinitionValidator.cs
1namespace Gondwana.Audio.GSND;
2
6public static class AudioDefinitionValidator
7{
13 public static IReadOnlyList<string> Validate(AudioDefinition definition)
14 {
15 ArgumentNullException.ThrowIfNull(definition);
16
17 var errors = new List<string>();
18 var keys = new HashSet<string>(StringComparer.Ordinal);
19
20 definition.Resources ??= [];
21
22 for (int i = 0; i < definition.Resources.Count; i++)
23 {
24 var resource = definition.Resources[i];
25 var label = $"Resource {i}";
26
27 if (resource is null)
28 {
29 errors.Add($"{label}: resource definition is null.");
30 continue;
31 }
32
33 if (string.IsNullOrWhiteSpace(resource.Key))
34 errors.Add($"{label}: key is empty.");
35 else if (!keys.Add(resource.Key))
36 errors.Add($"{label}: duplicate key '{resource.Key}'.");
37
38 if (!Enum.IsDefined(resource.SourceKind))
39 {
40 errors.Add($"{label}: unknown source kind '{resource.SourceKind}'.");
41 continue;
42 }
43
44 if (!float.IsFinite(resource.Volume) || resource.Volume < 0f || resource.Volume > 1f)
45 errors.Add($"{label}: Volume must be between 0 and 1.");
46
47 if (!float.IsFinite(resource.Pan) || resource.Pan < -1f || resource.Pan > 1f)
48 errors.Add($"{label}: Pan must be between -1 and 1.");
49
50 if (!float.IsFinite(resource.PlaybackSpeed) ||
51 resource.PlaybackSpeed < AudioResource.MinimumPlaybackSpeed ||
52 resource.PlaybackSpeed > AudioResource.MaximumPlaybackSpeed)
53 {
54 errors.Add(
55 $"{label}: PlaybackSpeed must be between {AudioResource.MinimumPlaybackSpeed} and {AudioResource.MaximumPlaybackSpeed}.");
56 }
57
58 switch (resource.SourceKind)
59 {
60 case AudioResourceSourceKind.LooseFile:
61 if (string.IsNullOrWhiteSpace(resource.FilePath))
62 errors.Add($"{label}: loose FilePath is empty.");
63 break;
64
65 case AudioResourceSourceKind.PackedAsset:
66 if (string.IsNullOrWhiteSpace(resource.AssetsFilePath))
67 errors.Add($"{label}: AssetsFilePath is empty.");
68 if (string.IsNullOrWhiteSpace(resource.AssetEntryName))
69 errors.Add($"{label}: AssetEntryName is empty.");
70 if (string.IsNullOrWhiteSpace(resource.SourceExtension) &&
71 string.IsNullOrWhiteSpace(Path.GetExtension(resource.AssetEntryName)))
72 {
73 errors.Add($"{label}: packed audio requires SourceExtension when AssetEntryName has no extension.");
74 }
75 break;
76
78 if (string.IsNullOrWhiteSpace(resource.SourceUri))
79 errors.Add($"{label}: SourceUri is empty.");
80 else if (!Uri.TryCreate(resource.SourceUri, UriKind.RelativeOrAbsolute, out _))
81 errors.Add($"{label}: SourceUri is invalid.");
82 break;
83 }
84 }
85
86 return errors;
87 }
88}
AudioResourceSourceKind
Identifies how a GSND audio resource locates its underlying media.