Browse Source

Fixed undo breaking rendering

flabbet 8 months ago
parent
commit
0f7e31c21c

+ 1 - 1
src/PixiEditor.ChangeableDocument/Changeables/Graph/FuncInputProperty.cs

@@ -18,7 +18,7 @@ public class FuncInputProperty<T> : InputProperty<Func<FuncContext, T>>, IFuncIn
         NonOverridenValue = _ => constantNonOverrideValue;
     }
 
-    protected override object FuncFactory(object toReturn)
+    protected internal override object FuncFactory(object toReturn)
     {
         Func<FuncContext, T> func = _ =>
         {

+ 1 - 33
src/PixiEditor.ChangeableDocument/Changeables/Graph/InputProperty.cs

@@ -63,7 +63,7 @@ public class InputProperty : IInputProperty
         }
     }
 
-    protected virtual object FuncFactory(object toReturn)
+    protected internal virtual object FuncFactory(object toReturn)
     {
         Func<FuncContext, object> func = _ => toReturn;
         return func;
@@ -131,38 +131,6 @@ public class InputProperty : IInputProperty
         Node = node;
         ValueType = valueType;
     }
-
-    public InputProperty Clone(Node forNode)
-    {
-        if(NonOverridenValue is ICloneable cloneable)
-            return new InputProperty(forNode, InternalPropertyName, DisplayName, cloneable.Clone(), ValueType);
-
-        if (NonOverridenValue is Enum enumVal)
-        {
-            return new InputProperty(forNode, InternalPropertyName, DisplayName, enumVal, ValueType);
-        }
-
-        if (NonOverridenValue is null || (!NonOverridenValue.GetType().IsValueType && NonOverridenValue.GetType() != typeof(string)))
-        {
-            object? nullValue = null;
-            if (ValueType.IsValueType)
-            {
-                nullValue = Activator.CreateInstance(ValueType);
-            }
-            
-            return new InputProperty(forNode, InternalPropertyName, DisplayName, nullValue, ValueType);
-        }
-        
-        /*if(!NonOverridenValue.GetType().IsValueType && NonOverridenValue.GetType() != typeof(string))
-            throw new InvalidOperationException($"Value of type {NonOverridenValue.GetType()} is not cloneable and not a primitive type");*/
-
-        if (!NonOverridenValue.GetType().IsValueType && NonOverridenValue.GetType() != typeof(string))
-        {
-            
-        }
-        
-        return new InputProperty(forNode, InternalPropertyName, DisplayName, NonOverridenValue, ValueType);
-    }
 }
 
 

+ 1 - 0
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/CombineSeparate/CombineVecDNode.cs

@@ -34,6 +34,7 @@ public class CombineVecDNode : Node
 
     protected override void OnExecute(RenderContext context)
     {
+        
     }
 
 

+ 1 - 0
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/MathNode.cs

@@ -22,6 +22,7 @@ public class MathNode : Node
     
     public FuncInputProperty<Float1> Y { get; }
     
+
     public MathNode()
     {
         Result = CreateFuncOutput<Float1>(nameof(Result), "RESULT", Calculate);

+ 42 - 8
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/Node.cs

@@ -9,6 +9,7 @@ using PixiEditor.Common;
 using Drawie.Backend.Core;
 using Drawie.Backend.Core.ColorsImpl;
 using Drawie.Backend.Core.Shaders;
+using Drawie.Backend.Core.Shaders.Generation;
 using Drawie.Numerics;
 
 namespace PixiEditor.ChangeableDocument.Changeables.Graph.Nodes;
@@ -347,23 +348,26 @@ public abstract class Node : IReadOnlyNode, IDisposable
     public Node Clone()
     {
         var clone = CreateCopy();
+
         clone.DisplayName = DisplayName;
         clone.Id = Guid.NewGuid();
         clone.Position = Position;
 
         for (var i = 0; i < clone.inputs.Count; i++)
         {
-            var cloneInput = inputs[i];
-            var newInput = cloneInput.Clone(clone);
-            clone.inputs[i].NonOverridenValue = newInput.NonOverridenValue;
+            var toClone = inputs[i];
+            object value = CloneValue(toClone.NonOverridenValue, clone.inputs[i]);
+            clone.inputs[i].NonOverridenValue = value;
         }
-
-        for (var i = 0; i < clone.outputs.Count; i++)
+        
+        // This makes shader outputs copy old delegate, also I don't think it's required because output is calculated based on inputs,
+        // leaving commented in case I'm wrong
+        
+        /*for (var i = 0; i < clone.outputs.Count; i++)
         {
             var cloneOutput = outputs[i];
-            var newOutput = cloneOutput.Clone(clone);
-            clone.outputs[i].Value = newOutput.Value;
-        }
+            clone.outputs[i].Value = CloneValue(cloneOutput.Value, null);
+        }*/
 
         foreach (var keyFrame in keyFrames)
         {
@@ -421,4 +425,34 @@ public abstract class Node : IReadOnlyNode, IDisposable
     {
         return new None();
     }
+    
+    private static object CloneValue(object? value, InputProperty? input)
+    {
+        if (value is null)
+        {
+            return null;
+        }
+
+        if (input != null && value is Delegate del)
+        {
+            object constant = del.DynamicInvoke(FuncContext.NoContext);
+            if (constant is ShaderExpressionVariable expr)
+            {
+                return input.FuncFactory(expr.GetConstant());
+            }
+        }
+        
+        if (value is ICloneable cloneable)
+        {
+            return cloneable.Clone();
+        }
+
+        Type type = value.GetType();
+        if (type.IsValueType || type == typeof(string))
+        {
+            return value;
+        }
+        
+        return default;
+    }
 }

+ 0 - 25
src/PixiEditor.ChangeableDocument/Changeables/Graph/OutputProperty.cs

@@ -65,31 +65,6 @@ public class OutputProperty : IOutputProperty
 
         Disconnected?.Invoke(property, this);
     }
-
-    public OutputProperty Clone(Node clone)
-    {
-        if (Value is null || (Value is not ICloneable && !Value.GetType().IsPrimitive && Value.GetType() != typeof(string)))
-        {
-            object defaultValue = null;
-            if(ValueType.IsValueType)
-                defaultValue = Activator.CreateInstance(ValueType);
-            return new OutputProperty(clone, InternalPropertyName, DisplayName, defaultValue, ValueType);
-        }
-
-        if (Value is Enum enumVal)
-        {
-            return new OutputProperty(clone, InternalPropertyName, DisplayName, enumVal, ValueType);
-        }
-
-        /*if (Value is not ICloneable && !Value.GetType().IsPrimitive && Value.GetType() != typeof(string))
-            throw new InvalidOperationException("Value is not cloneable and not a primitive type");*/
-     
-        object value = Value is ICloneable cloneableValue ? cloneableValue.Clone() : Value;
-        
-        var newOutput = new OutputProperty(clone, InternalPropertyName, DisplayName, value, ValueType);
-
-        return newOutput;
-    }
 }
 
 public class OutputProperty<T> : OutputProperty, INodeProperty<T>

+ 3 - 0
src/PixiEditor.ChangeableDocument/Changes/NodeGraph/DeleteNode_Change.cs

@@ -68,6 +68,8 @@ internal class DeleteNode_Change : Change
             target.AnimationData.RemoveKeyFrame(savedKeyFrameGroup.Id);
             changes.Add(new DeleteKeyFrame_ChangeInfo(savedKeyFrameGroup.Id));
         }
+        
+        node.Dispose();
 
         return changes;
     }
@@ -90,6 +92,7 @@ internal class DeleteNode_Change : Change
 
         changes.Add(createChange);
 
+        changes.AddRange(NodeOperations.CreateUpdateInputs(copy));
         changes.AddRange(NodeOperations.ConnectStructureNodeProperties(originalConnections, copy, doc.NodeGraph));
 
         RevertKeyFrames(doc, savedKeyFrameGroup, changes);

+ 23 - 0
src/PixiEditor.ChangeableDocument/Changes/NodeGraph/NodeOperations.cs

@@ -7,7 +7,9 @@ using PixiEditor.ChangeableDocument.Changeables.Interfaces;
 using PixiEditor.ChangeableDocument.ChangeInfos.NodeGraph;
 using PixiEditor.ChangeableDocument.Changes.Structure;
 using Drawie.Backend.Core;
+using Drawie.Backend.Core.Shaders.Generation;
 using Drawie.Backend.Core.Surfaces;
+using PixiEditor.ChangeableDocument.Changeables.Graph.Context;
 
 namespace PixiEditor.ChangeableDocument.Changes.NodeGraph;
 
@@ -229,6 +231,27 @@ public static class NodeOperations
 
         return changes;
     }
+
+    public static List<IChangeInfo> CreateUpdateInputs(Node copy)
+    {
+        List<IChangeInfo> changes = new();
+        foreach (var input in copy.InputProperties)
+        {
+            object value = input.NonOverridenValue;
+            if (value is Delegate del)
+            {
+                value = del.DynamicInvoke(FuncContext.NoContext);
+                if (value is ShaderExpressionVariable expressionVariable)
+                {
+                    value = expressionVariable.GetConstant();
+                }
+            }
+            
+            changes.Add(new PropertyValueUpdated_ChangeInfo(copy.Id, input.InternalPropertyName, value));
+        }
+
+        return changes;
+    }
 }
 
 public record PropertyConnection(Guid? NodeId, string? PropertyName);