1
0
mirror of https://github.com/Siccity/xNode.git synced 2026-03-26 22:49:02 +08:00

Example fix for the dynamic port "serialisation desync" problem.

Not tested much with non-array types where "dynamicPortList" is set to true. Recommend further testing if applicable.
This commit is contained in:
Lumos 2019-12-22 18:56:42 +01:00
parent 5005b5e4f9
commit ecc5b3e0e1
5 changed files with 62 additions and 9 deletions

View File

@ -457,8 +457,8 @@ namespace XNodeEditor {
XNode.Node newNodeIn, newNodeOut;
if (substitutes.TryGetValue(inputPort.node, out newNodeIn) && substitutes.TryGetValue(outputPort.node, out newNodeOut)) {
newNodeIn.UpdateStaticPorts();
newNodeOut.UpdateStaticPorts();
newNodeIn.UpdatePorts();
newNodeOut.UpdatePorts();
inputPort = newNodeIn.GetInputPort(inputPort.fieldName);
outputPort = newNodeOut.GetOutputPort(outputPort.fieldName);
}

View File

@ -326,6 +326,8 @@ namespace XNodeEditor {
}
list.list = dynamicPorts;
list.DoLayoutList();
node.UpdatePorts();
}
private static ReorderableList CreateReorderableList(string fieldName, List<XNode.NodePort> dynamicPorts, SerializedProperty arrayData, Type type, SerializedObject serializedObject, XNode.NodePort.IO io, XNode.Node.ConnectionType connectionType, XNode.Node.TypeConstraint typeConstraint, Action<ReorderableList> onCreation) {

View File

@ -119,12 +119,12 @@ namespace XNode {
protected void OnEnable() {
if (graphHotfix != null) graph = graphHotfix;
graphHotfix = null;
UpdateStaticPorts();
UpdatePorts();
Init();
}
/// <summary> Update static ports to reflect class fields. This happens automatically on enable. </summary>
public void UpdateStaticPorts() {
/// <summary> Update all ports to reflect class fields. This happens automatically on enable or on redrawing the list of ports. </summary>
public void UpdatePorts() {
NodeDataCache.UpdatePorts(this, ports);
}

View File

@ -1,6 +1,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEditor;
using UnityEngine;
namespace XNode {
@ -9,7 +10,7 @@ namespace XNode {
private static PortDataCache portDataCache;
private static bool Initialized { get { return portDataCache != null; } }
/// <summary> Update static ports to reflect class fields. </summary>
/// <summary> Update static and dynamic ports to reflect class fields. </summary>
public static void UpdatePorts(Node node, Dictionary<string, NodePort> ports) {
if (!Initialized) BuildCache();
@ -17,6 +18,8 @@ namespace XNode {
Dictionary<string, List<NodePort>> removedPorts = new Dictionary<string, List<NodePort>>();
System.Type nodeType = node.GetType();
List<NodePort> dynamicPorts = new List<NodePort>();
List<NodePort> typePortCache;
if (portDataCache.TryGetValue(nodeType, out typePortCache)) {
for (int i = 0; i < typePortCache.Count; i++) {
@ -25,6 +28,7 @@ namespace XNode {
}
// Cleanup port dict - Remove nonexisting static ports - update static port types
// AND update dynamic ports too!
// Loop through current node ports
foreach (NodePort port in ports.Values.ToList()) {
// If port still exists, check it it has been changed
@ -43,6 +47,10 @@ namespace XNode {
port.ClearConnections();
ports.Remove(port.fieldName);
}
// If the port is dynamic, flag it for reference updates
else {
dynamicPorts.Add(port);
}
}
// Add missing ports
foreach (NodePort staticPort in staticPorts.Values) {
@ -60,6 +68,31 @@ namespace XNode {
ports.Add(staticPort.fieldName, port);
}
}
// Finally, make sure dynamic port settings correspond to the settings of their backing field
foreach (NodePort dynamicPort in dynamicPorts) {
string[] parts = dynamicPort.fieldName.Split(' ');
if (parts.Length != 2) {
Debug.LogError("Dynamic port name " + dynamicPort.fieldName + " is invalid.");
continue;
}
string backingPortName = parts[0];
NodePort backingPort;
if (!staticPorts.TryGetValue(backingPortName, out backingPort)) {
Debug.LogError($"Could not find backing port \"{backingPortName}\" for port {dynamicPort.fieldName}");
continue;
}
// Update port constraints. Creating a new port instead will break the editor, mandating the need for setters.
dynamicPort.ValueType = backingPort.ValueType;
dynamicPort.direction = backingPort.direction;
dynamicPort.connectionType = backingPort.connectionType;
dynamicPort.typeConstraint = backingPort.typeConstraint;
}
}
/// <summary> Cache node types </summary>
@ -150,5 +183,10 @@ namespace XNode {
this.Add(keys[i], values[i]);
}
}
[MenuItem("TOOLS/LOL")]
public static void LOL() {
portDataCache = null;
}
}
}

View File

@ -19,9 +19,22 @@ namespace XNode {
}
}
public IO direction { get { return _direction; } }
public Node.ConnectionType connectionType { get { return _connectionType; } }
public Node.TypeConstraint typeConstraint { get { return _typeConstraint; } }
// public IO direction { get { return _direction; } }
// public Node.ConnectionType connectionType { get { return _connectionType; } }
// public Node.TypeConstraint typeConstraint { get { return _typeConstraint; } }
public IO direction {
get { return _direction; }
internal set { _direction = value; }
}
public Node.ConnectionType connectionType {
get { return _connectionType; }
internal set { _connectionType = value; }
}
public Node.TypeConstraint typeConstraint {
get { return _typeConstraint; }
internal set { _typeConstraint = value; }
}
/// <summary> Is this port connected to anytihng? </summary>
public bool IsConnected { get { return connections.Count != 0; } }