///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // 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( 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 ParseArray( Godot.Collections.Dictionary dict, string name, Func fn ) { var arr = new gen.List(); var dictArr = GetArray( dict, name ); foreach( var arrObj in dictArr ) { arr.Add( fn( (Godot.Collections.Dictionary)arrObj ) ); } return arr; } public static gen.List ParseReflArray( Godot.Collections.Dictionary dict, string name ) where T : new() { var arr = new gen.List(); var dictArr = GetArray( dict, name ); foreach( var arrObj in dictArr ) { arr.Add( GetRefl( (Godot.Collections.Dictionary)arrObj ) ); } return arr; } }