gd_core/addons/core/misc/ser.cs

257 lines
5.6 KiB
C#

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// D E R E L I C T
//
/// // (c) 2003..2024
using Godot;
//using Microsoft.CodeAnalysis.CSharp.Syntax;
using gen = System.Collections.Generic;
using System;
using System.Text;
public static class SerExtensions
{
public static T GetRefl<T>( Godot.Collections.Dictionary dict )
where T : new()
{
T v = new T();
Type type = typeof( T );
Type utilType = typeof( SerExtensions );
var getReflMethod = utilType.GetMethod( "GetRefl" );
var parseArrayMethod = utilType.GetMethod( "ParseReflArray" );
//GD.Print($"GetRefl dict {dict}");
//GD.Print($"GetRefl type {type.Name}");
var props = type.GetProperties();
foreach( var prop in props )
{
var nameBld = new StringBuilder( prop.Name );
nameBld[0] = char.ToLower( nameBld[0] );
var name = nameBld.ToString();
var propType = prop.PropertyType;
try
{
if( propType.IsArray )
{
GD.Print( $"Skipping Array {name}" );
continue;
}
if( propType.IsEnum )
{
propType = propType.GetEnumUnderlyingType();
}
TypeCode tc = Type.GetTypeCode( propType );
//GD.Print($"{name}: {propType.Name} {tc}");
switch( tc )
{
case TypeCode.Boolean:
prop.SetValue( v, GetBool( dict, name ) );
break;
case TypeCode.Char:
prop.SetValue( v, (char)GetLong( dict, name ) );
break;
case TypeCode.DateTime:
case TypeCode.DBNull:
case TypeCode.Decimal:
case TypeCode.Empty:
{
GD.Print( $"GetRefl ERROR Unhandled type for {name}: {propType.Name}" );
}
break;
case TypeCode.Single:
prop.SetValue( v, (float)GetDouble( dict, name ) );
break;
case TypeCode.Double:
prop.SetValue( v, GetDouble( dict, name ) );
break;
case TypeCode.Int16:
prop.SetValue( v, (short)GetLong( dict, name ) );
break;
case TypeCode.Int32:
prop.SetValue( v, (int)GetLong( dict, name ) );
break;
case TypeCode.Int64:
prop.SetValue( v, GetLong( dict, name ) );
break;
case TypeCode.SByte:
prop.SetValue( v, (sbyte)GetULong( dict, name ) );
break;
case TypeCode.Byte:
prop.SetValue( v, (byte)GetLong( dict, name ) );
break;
case TypeCode.UInt16:
prop.SetValue( v, (ushort)GetULong( dict, name ) );
break;
case TypeCode.UInt32:
prop.SetValue( v, (uint)GetULong( dict, name ) );
break;
case TypeCode.UInt64:
prop.SetValue( v, GetULong( dict, name ) );
break;
case TypeCode.Object:
{
if( propType.Name == "gen.IEnumerable`1" )
{
GD.Print( $"GetRefl Type Filling in gen.IEnumerable {name}: {propType.Name} {propType.GenericTypeArguments[0].Name}" );
var enumerableType = propType.GenericTypeArguments[0];
//*
if( enumerableType.Name == "String" )
{
enumerableType = typeof( string );
}
// */
var genericParseReflArrayMethod = parseArrayMethod.MakeGenericMethod( enumerableType );
var obj = genericParseReflArrayMethod.Invoke( null, new object[] {
dict,
name,
} );
prop.SetValue( v, obj );
}
else
{
var genericGetReflMethod = getReflMethod.MakeGenericMethod( propType );
var obj = genericGetReflMethod.Invoke( null, new object[] {
GetObject(dict, name)
} );
prop.SetValue( v, obj );
}
}
break;
case TypeCode.String:
prop.SetValue( v, GetString( dict, name ) );
break;
}
}
catch( ArgumentException ex )
{
GD.Print( $"While parsing {type.Name}: {name}" );
GD.Print( $"Caught {ex.GetType().Name} {ex.Message}" );
}
catch( Exception ex )
{
GD.Print( $"While parsing {type.Name}: {name}" );
GD.Print( $"Caught {ex.GetType().Name} {ex.Message}" );
}
}
return v;
}
public static string GetString( Godot.Collections.Dictionary dict, string name )
{
var v = (string)dict[name];
return v;
}
public static long GetLong( Godot.Collections.Dictionary dict, string name )
{
var val = (float)dict[name];
var v = (long)val;
return v;
}
public static ulong GetULong( Godot.Collections.Dictionary dict, string name )
{
var val = (float)dict[name];
var v = (ulong)val;
return v;
}
public static bool GetBool( Godot.Collections.Dictionary dict, string name )
{
var v = (bool)dict[name];
return v;
}
public static double GetDouble( Godot.Collections.Dictionary dict, string name )
{
var val = (float)dict[name];
return (double)val;
}
public static Godot.Collections.Array GetArray( Godot.Collections.Dictionary dict, string name )
{
var arr = (Godot.Collections.Array)dict[name];
return arr;
}
public static Godot.Collections.Dictionary GetObject( Godot.Collections.Dictionary dict, string name )
{
var d2 = (Godot.Collections.Dictionary)dict[name];
return d2;
}
public static gen.List<T> ParseArray<T>( Godot.Collections.Dictionary dict, string name, Func<Godot.Collections.Dictionary, T> fn )
{
var arr = new gen.List<T>();
var dictArr = GetArray( dict, name );
foreach( var arrObj in dictArr )
{
arr.Add( fn( (Godot.Collections.Dictionary)arrObj ) );
}
return arr;
}
public static gen.List<T> ParseReflArray<T>( Godot.Collections.Dictionary dict, string name )
where T : new()
{
var arr = new gen.List<T>();
var dictArr = GetArray( dict, name );
foreach( var arrObj in dictArr )
{
arr.Add( GetRefl<T>( (Godot.Collections.Dictionary)arrObj ) );
}
return arr;
}
}