257 lines
5.6 KiB
C#
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;
|
|
}
|
|
|
|
|
|
}
|