2023-03-21 23:41:19 +01:00
using Ryujinx.Common.Utilities ;
using System ;
2021-04-14 12:28:43 +02:00
using System.Text.Json ;
using System.Text.Json.Serialization ;
namespace Ryujinx.Common.Configuration.Hid.Controller.Motion
{
class JsonMotionConfigControllerConverter : JsonConverter < MotionConfigController >
{
2023-03-21 23:41:19 +01:00
private static readonly MotionConfigJsonSerializerContext SerializerContext = new ( JsonHelper . GetDefaultSerializerOptions ( ) ) ;
2021-04-14 12:28:43 +02:00
private static MotionInputBackendType GetMotionInputBackendType ( ref Utf8JsonReader reader )
{
// Temporary reader to get the backend type
Utf8JsonReader tempReader = reader ;
MotionInputBackendType result = MotionInputBackendType . Invalid ;
while ( tempReader . Read ( ) )
{
// NOTE: We scan all properties ignoring the depth entirely on purpose.
// The reason behind this is that we cannot track in a reliable way the depth of the object because Utf8JsonReader never emit the first TokenType == StartObject if the json start with an object.
// As such, this code will try to parse very field named "motion_backend" to the correct enum.
if ( tempReader . TokenType = = JsonTokenType . PropertyName )
{
string propertyName = tempReader . GetString ( ) ;
if ( propertyName . Equals ( "motion_backend" ) )
{
tempReader . Read ( ) ;
if ( tempReader . TokenType = = JsonTokenType . String )
{
string backendTypeRaw = tempReader . GetString ( ) ;
if ( ! Enum . TryParse ( backendTypeRaw , out result ) )
{
result = MotionInputBackendType . Invalid ;
}
else
{
break ;
}
}
}
}
}
return result ;
}
public override MotionConfigController Read ( ref Utf8JsonReader reader , Type typeToConvert , JsonSerializerOptions options )
{
MotionInputBackendType motionBackendType = GetMotionInputBackendType ( ref reader ) ;
return motionBackendType switch
{
2023-03-21 23:41:19 +01:00
MotionInputBackendType . GamepadDriver = > JsonSerializer . Deserialize ( ref reader , SerializerContext . StandardMotionConfigController ) ,
MotionInputBackendType . CemuHook = > JsonSerializer . Deserialize ( ref reader , SerializerContext . CemuHookMotionConfigController ) ,
2021-04-14 12:28:43 +02:00
_ = > throw new InvalidOperationException ( $"Unknown backend type {motionBackendType}" ) ,
} ;
}
public override void Write ( Utf8JsonWriter writer , MotionConfigController value , JsonSerializerOptions options )
{
switch ( value . MotionBackend )
{
case MotionInputBackendType . GamepadDriver :
2023-03-21 23:41:19 +01:00
JsonSerializer . Serialize ( writer , value as StandardMotionConfigController , SerializerContext . StandardMotionConfigController ) ;
2021-04-14 12:28:43 +02:00
break ;
case MotionInputBackendType . CemuHook :
2023-03-21 23:41:19 +01:00
JsonSerializer . Serialize ( writer , value as CemuHookMotionConfigController , SerializerContext . CemuHookMotionConfigController ) ;
2021-04-14 12:28:43 +02:00
break ;
default :
throw new ArgumentException ( $"Unknown motion backend type {value.MotionBackend}" ) ;
}
}
}
}