UniformValue.cs
using System;
using System.Collections.Immutable;
using Sandbox;
namespace Goo;
public enum UniformKind : byte
{
None = 0,
Color,
Float,
Int,
Bool,
Vec2,
Vec3,
Vec4,
Texture,
}
public readonly struct UniformValue : IEquatable<UniformValue>
{
public readonly string Name;
public readonly UniformKind Kind;
public readonly Color ColorValue;
public readonly Vector4 VecValue;
public readonly float FloatValue;
public readonly int IntValue;
public readonly bool BoolValue;
public readonly Texture? TextureValue;
UniformValue(string name, UniformKind kind,
Color color = default, Vector4 vec = default,
float f = 0f, int i = 0, bool b = false, Texture? tex = null)
{
Name = name;
Kind = kind;
ColorValue = color;
VecValue = vec;
FloatValue = f;
IntValue = i;
BoolValue = b;
TextureValue = tex;
}
public static UniformValue OfColor(string name, Color value)
=> new(name, UniformKind.Color, color: value);
public static UniformValue OfFloat(string name, float value)
=> new(name, UniformKind.Float, f: value);
public static UniformValue OfInt(string name, int value)
=> new(name, UniformKind.Int, i: value);
public static UniformValue OfBool(string name, bool value)
=> new(name, UniformKind.Bool, b: value);
public static UniformValue OfVec2(string name, Vector2 value)
=> new(name, UniformKind.Vec2, vec: new Vector4(value.x, value.y, 0f, 0f));
public static UniformValue OfVec3(string name, Vector3 value)
=> new(name, UniformKind.Vec3, vec: new Vector4(value.x, value.y, value.z, 0f));
public static UniformValue OfVec4(string name, Vector4 value)
=> new(name, UniformKind.Vec4, vec: value);
public static UniformValue OfTexture(string name, Texture? value)
=> new(name, UniformKind.Texture, tex: value);
public bool Equals(UniformValue other)
{
if (Name != other.Name || Kind != other.Kind) return false;
return Kind switch
{
UniformKind.Color => ColorValue == other.ColorValue,
UniformKind.Float => FloatValue == other.FloatValue,
UniformKind.Int => IntValue == other.IntValue,
UniformKind.Bool => BoolValue == other.BoolValue,
UniformKind.Vec2 or UniformKind.Vec3 or UniformKind.Vec4 => VecValue == other.VecValue,
UniformKind.Texture => ReferenceEquals(TextureValue, other.TextureValue),
_ => true,
};
}
public override bool Equals(object? obj) => obj is UniformValue v && Equals(v);
public override int GetHashCode() => HashCode.Combine(Name, Kind);
public static bool operator ==(UniformValue a, UniformValue b) => a.Equals(b);
public static bool operator !=(UniformValue a, UniformValue b) => !a.Equals(b);
internal static bool SequenceEqual(ImmutableArray<UniformValue> a, ImmutableArray<UniformValue> b)
{
if (a.IsDefaultOrEmpty && b.IsDefaultOrEmpty) return true;
if (a.IsDefaultOrEmpty != b.IsDefaultOrEmpty) return false;
if (a.Length != b.Length) return false;
for (int i = 0; i < a.Length; i++)
if (!a[i].Equals(b[i])) return false;
return true;
}
}