171 lines
4.2 KiB
C#
171 lines
4.2 KiB
C#
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<SerializedGodotObjectMember> members = new List<SerializedGodotObjectMember>();
|
|
|
|
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<object,SerializedGodotObject> cache = null )
|
|
{
|
|
if ( cache == null )
|
|
{
|
|
cache = new Dictionary<object, SerializedGodotObject>();
|
|
}
|
|
|
|
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;
|
|
|
|
}
|
|
}
|
|
|
|
} |