Editor Auto Change Listener

This commit is contained in:
Josef 2024-11-13 20:33:08 +01:00
parent 7949d675f8
commit ef06e01f4e
7 changed files with 317 additions and 0 deletions

View File

@ -0,0 +1,14 @@
using Godot;
using System.Text;
using System.Collections.Generic;
namespace Rokojori
{
public class GodotBuiltInDataLibrary
{
public static readonly List<GodotBuiltInSerializer> serializers = new List<GodotBuiltInSerializer>()
{
new SerializedGodotCurve()
};
}
}

View File

@ -0,0 +1,19 @@
using Godot;
using System.Text;
using System.Collections.Generic;
namespace Rokojori
{
public class GodotBuiltInSerializer
{
public virtual bool Handles( object obj )
{
return false;
}
public virtual object Serialize( object obj )
{
return null;
}
}
}

View File

@ -0,0 +1,44 @@
using Godot;
using System.Text;
using System.Collections.Generic;
namespace Rokojori
{
public class SerializedGodotCurve: GodotBuiltInSerializer
{
public override bool Handles( object obj )
{
return obj as Curve != null;
}
public override object Serialize( object obj )
{
if ( obj == null )
{
return null;
}
var curve = obj as Curve;
var curveData = new List<float>();
for ( int i = 0; i < curve.PointCount; i++ )
{
if ( i != 0 )
{
curveData.Add( curve.GetPointLeftTangent( i ) );
}
curveData.Add( curve.GetPointPosition( i ).X );
curveData.Add( curve.GetPointPosition( i ).Y );
if ( i != curve.PointCount -1 )
{
curveData.Add( curve.GetPointRightTangent( i ) );
}
}
return curveData;
}
}
}

View File

@ -0,0 +1,171 @@
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;
}
}
}

View File

@ -121,6 +121,8 @@ namespace Rokojori
[Export]
public Vector2 positionToFilter = new Vector2( 0, 0 );
SerializedGodotObject _cached;
public override void _Process( double delta )
{
if ( ! ( update || updateAlways ) )
@ -128,9 +130,21 @@ namespace Rokojori
return;
}
var current = SerializedGodotObject.Create( this );
var isEquals = _cached != null && _cached.Equals( current );
if ( _cached != null && _cached.Equals( current ) )
{
return;
}
update = false;
CreatePatch();
_cached = current;
}
float _maxWidth = 0;

View File

@ -47,5 +47,38 @@ namespace Rokojori
callback( it );
}
}
public static bool AreArraysAndEntriesEqual( object objA, object objB )
{
if ( ! ( objA.GetType().IsArray && objB.GetType().IsArray ) )
{
return false;
}
return Lists.AreEntriesEqual(
Lists.FromEnumerable<object>( objA as IEnumerable ),
Lists.FromEnumerable<object>( objA as IEnumerable )
);
}
public static bool AreEntriesEqual<T>( T[] a, T[] b )
{
if ( a.Length != b.Length )
{
return false;
}
for ( int i = 0; i < a.Length; i++ )
{
var isEqual = EqualityComparer<T>.Default.Equals( a[ i ], b[ i ]);
if ( ! isEqual )
{
return false;
}
}
return true;
}
}
}

View File

@ -250,6 +250,28 @@ namespace Rokojori
return result;
}
public static List<T> FromEnumerable<T>( IEnumerable enumerable )
{
var listA = new List<T>();
foreach ( var it in enumerable )
{
listA.Add( (T) it );
}
return listA;
}
public static bool AreListsAndEntriesEqual( object objA, object objB )
{
if ( ! ( ReflectionHelper.IsList( objA ) && ReflectionHelper.IsList( objB ) ) )
{
return false;
}
return AreEntriesEqual( FromEnumerable<object>( objA as IEnumerable ), FromEnumerable<object>( objB as IEnumerable ) );
}
public static bool AreEntriesEqual<T>( List<T> a, List<T> b )
{
if ( a.Count != b.Count )