using Godot; using System.Text; using System.Collections.Generic; namespace Rokojori { public class SerializedGodotObjectMember { public string name; public object value; public override string ToString() { return "{" + name + ":" + RJLog.Stringify( value ) + "}"; } public static bool debug = false; public override bool Equals( object? obj ) { var other = obj as SerializedGodotObjectMember; if ( other == null ) { if ( debug ){ RJLog.Log( "Other is null..." ); } return false; } if ( name != other.name ) { if ( debug ){ RJLog.Log( "Names are different" ); } return false; } if ( value == null && other.value == null ) { if ( debug ){ RJLog.Log( "Both null" ); } return true; } var result = value == other.value || value.Equals( other.value ) || Lists.AreListsAndEntriesEqual( value, other.value ) || Arrays.AreArraysAndEntriesEqual( value, other.value ); if ( ! result && debug ) { if ( debug ) { RJLog.Log( name, "values not equals", value, other.value, value == other.value, value.Equals( other.value ) ); } } return result; } } public class SerializedGodotObject { public List members = new List(); public override string ToString() { return "SerializedGodotObject" + RJLog.Stringify( members ); } public override bool Equals( object? obj ) { var other = obj as SerializedGodotObject; if ( members.Count != other.members.Count ) { // RJLog.Log( "Members not equals count" ); return false; } for ( int i = 0; i < members.Count; i++ ) { var member = members[ i ]; var otherMember = other.members.Find( m => m.name == member.name ); if ( otherMember == null || ! member.Equals( otherMember ) ) { // if ( otherMember == null ) // { // RJLog.Log( member.name + " is not present" ); // } // else // { // SerializedGodotObjectMember.debug = true; // var eq = member.Equals( otherMember ); // SerializedGodotObjectMember.debug = false; // RJLog.Log( eq, member.name + " is different, should be:", member.value, "but is: " + otherMember.value ); // } return false; } } return true; } public static SerializedGodotObject Create( object obj, Dictionary cache = null ) { if ( cache == null ) { cache = new Dictionary(); } var objectData = new SerializedGodotObject(); var serializer = GodotBuiltInDataLibrary.serializers.Find( s => s.Handles( obj ) ); if ( serializer != null ) { var serialized = new SerializedGodotObjectMember(); serialized.name = "data"; serialized.value = serializer.Serialize( obj ); objectData.members.Add( serialized ); return objectData; } var nodeType = obj.GetType(); var fields = nodeType.GetFields(); for ( int i = 0; i < fields.Length; i++ ) { var isExportedVariable = System.Attribute.IsDefined( fields[ i ], typeof( Godot.ExportAttribute ) ); if ( ! isExportedVariable ) { continue; } var name = fields[ i ].Name; if ( name.StartsWith( "X_" ) || name.StartsWith( "x_" ) ) { continue; } var value = fields[ i ].GetValue( obj ); var resourceValue = value as Resource; if ( resourceValue != null ) { value = cache.ContainsKey( resourceValue ) ? cache[ resourceValue ] : SerializedGodotObject.Create( resourceValue, cache ); } var member = new SerializedGodotObjectMember(); member.name = name; member.value = value; objectData.members.Add( member ); } return objectData; } } }