using Sandbox; using System; using System.Text.Json; using System.Text.Json.Serialization; namespace VeloX.Audio; [JsonConverter( typeof( ControllerConverter ) )] public sealed class Controller { public enum InputTypes { Throttle, RpmFraction, } public enum OutputTypes { Volume, Pitch, } public required InputTypes InputParameter { get; set; } [Property] public ValueRange InputRange { get; set; } public required OutputTypes OutputParameter { get; set; } public ValueRange OutputRange { get; set; } } public record struct ValueRange { public ValueRange( float inputMin, float inputMax ) { Min = inputMin; Max = inputMax; } [Range( 0, 1 )] public float Min { get; set; } [Range( 0, 1 )] public float Max { get; set; } public readonly float Remap( float value, float newMin, float newMax ) { var normalized = (value - Min) / (Max - Min); return newMin + normalized * (newMax - newMin); } }; public sealed class ControllerConverter : JsonConverter { public override Controller Read( ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options ) { if ( reader.TokenType != JsonTokenType.StartArray ) throw new JsonException( "Expected array for Controller" ); reader.Read(); string inputParam = reader.GetString() ?? string.Empty; reader.Read(); float inputMin = reader.GetSingle(); reader.Read(); float inputMax = reader.GetSingle(); reader.Read(); string outputParam = reader.GetString() ?? string.Empty; reader.Read(); float outputMin = reader.GetSingle(); reader.Read(); float outputMax = reader.GetSingle(); reader.Read(); // End of array return new Controller { InputParameter = Enum.Parse( inputParam, true ), InputRange = new ValueRange( inputMin, inputMax ), OutputParameter = Enum.Parse( outputParam, true ), OutputRange = new ValueRange( outputMin, outputMax ) }; } public override void Write( Utf8JsonWriter writer, Controller value, JsonSerializerOptions options ) { writer.WriteStartArray(); writer.WriteStringValue( value.InputParameter.ToString() ); writer.WriteNumberValue( value.InputRange.Min ); writer.WriteNumberValue( value.InputRange.Max ); writer.WriteStringValue( value.OutputParameter.ToString() ); writer.WriteNumberValue( value.OutputRange.Min ); writer.WriteNumberValue( value.OutputRange.Max ); writer.WriteEndArray(); } }