rj-action-library/Runtime/Godot/Editor/GodotNodeData.cs

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;
}
}
}