using System.Reflection;
namespace AcDream.App.Rendering.Gpu.Gl;
///
/// The single source of truth mapping each
/// field to the GLSL uniform name the GL backend binds it to — the names
/// documented on the fields themselves.
/// reads these constants (not string literals of its own) when it calls
/// GL.GetUniformLocation, and lets a
/// test prove the table cannot silently drop a field that a later slice adds
/// to the shared struct.
///
internal static class GlPushConstantUniformNames
{
public const string ViewProjection = "uViewProjection";
public const string DrawIdOffset = "uDrawIDOffset";
public const string LightingMode = "uLightingMode";
public const string RenderPass = "uRenderPass";
public const string LightDebug = "uLightDebug";
public const string TextureIndexA = "uTextureIndexA";
public const string TextureIndexB = "uTextureIndexB";
public const string ParamA = "uParamA";
public const string ParamB = "uParamB";
///
/// Field name (as declared on ) to GLSL
/// uniform name, built from the same constants the binder applies with —
/// so the binder and this completeness table can never disagree.
///
public static IReadOnlyDictionary ByFieldName { get; } =
new Dictionary
{
[nameof(GpuPushConstants.ViewProjection)] = ViewProjection,
[nameof(GpuPushConstants.DrawIdOffset)] = DrawIdOffset,
[nameof(GpuPushConstants.LightingMode)] = LightingMode,
[nameof(GpuPushConstants.RenderPass)] = RenderPass,
[nameof(GpuPushConstants.LightDebug)] = LightDebug,
[nameof(GpuPushConstants.TextureIndexA)] = TextureIndexA,
[nameof(GpuPushConstants.TextureIndexB)] = TextureIndexB,
[nameof(GpuPushConstants.ParamA)] = ParamA,
[nameof(GpuPushConstants.ParamB)] = ParamB,
};
///
/// Throws if declares a public instance
/// field this table does not map — the drift guard the campaign spec asks
/// for. Called from a unit test, not from production code.
///
internal static void AssertMapsEveryField()
{
FieldInfo[] fields = typeof(GpuPushConstants).GetFields(
BindingFlags.Public | BindingFlags.Instance);
foreach (FieldInfo field in fields)
{
if (!ByFieldName.ContainsKey(field.Name))
{
throw new InvalidOperationException(
$"GpuPushConstants.{field.Name} has no mapped GLSL uniform name in " +
$"{nameof(GlPushConstantUniformNames)}.");
}
}
if (ByFieldName.Count != fields.Length)
{
throw new InvalidOperationException(
$"{nameof(GlPushConstantUniformNames)} maps {ByFieldName.Count} names but " +
$"{nameof(GpuPushConstants)} declares {fields.Length} fields — a stale entry " +
"survives a field rename or removal.");
}
}
}