diff --git a/Scripts/Editor/NodeEditorGUILayout.cs b/Scripts/Editor/NodeEditorGUILayout.cs
index 295caa1..9e715ad 100644
--- a/Scripts/Editor/NodeEditorGUILayout.cs
+++ b/Scripts/Editor/NodeEditorGUILayout.cs
@@ -6,6 +6,7 @@ using System.Reflection;
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;
+using XNode;
namespace XNodeEditor {
/// xNode-specific version of
@@ -302,23 +303,19 @@ namespace XNodeEditor {
/// Connection type of added dynamic ports
/// 当为并且为时可用
/// Called on the list on creation. Use this if you want to customize the created ReorderableList
- public static void DynamicPortList(string fieldName, Type type, SerializedObject serializedObject, XNode.NodePort.IO io, XNode.Node.ConnectionType connectionType = XNode.Node.ConnectionType.Multiple, XNode.Node.TypeConstraint typeConstraint = XNode.Node.TypeConstraint.None,Type inputTypeConstraintBaseType = null, Action onCreation = null) {
+ public static void DynamicPortList(string fieldName, Type type, SerializedObject serializedObject, XNode.NodePort.IO io,
+ XNode.Node.ConnectionType connectionType = XNode.Node.ConnectionType.Multiple,
+ XNode.Node.TypeConstraint typeConstraint = XNode.Node.TypeConstraint.None,Type inputTypeConstraintBaseType = null,
+ Action onCreation = null) {
XNode.Node node = serializedObject.targetObject as XNode.Node;
- var indexedPorts = node.DynamicPorts.Select(x => {
- string[] split = x.fieldName.Split(' ');
- if (split != null && split.Length == 2 && split[0] == fieldName) {
- int i = -1;
- if (int.TryParse(split[1], out i)) {
- return new { index = i, port = x };
- }
- }
- return new { index = -1, port = (XNode.NodePort) null };
- }).Where(x => x.port != null);
- List dynamicPorts = indexedPorts.OrderBy(x => x.index).Select(x => x.port).ToList();
+ var indexedPorts = node.DynamicPorts;
+
+ List dynamicPorts = indexedPorts.ToList();
ReorderableList list = null;
Dictionary rlc;
+ //todo rename no update cache -- 2019年11月28日03点00分
if (reorderableListCache.TryGetValue(serializedObject.targetObject, out rlc)) {
if (!rlc.TryGetValue(fieldName, out list)) list = null;
}
@@ -340,16 +337,22 @@ namespace XNodeEditor {
string label = arrayData != null ? arrayData.displayName : ObjectNames.NicifyVariableName(fieldName);
list.drawElementCallback =
- (Rect rect, int index, bool isActive, bool isFocused) => {
- XNode.NodePort port = node.GetPort(fieldName + " " + index);
- if (hasArrayData) {
+ (Rect rect, int index, bool isActive, bool isFocused) =>
+ {
+ XNode.NodePort port = (NodePort) list.list[index];
+
+ if (hasArrayData)
+ {
if (arrayData.arraySize <= index) {
EditorGUI.LabelField(rect, "Array[" + index + "] data out of range");
return;
}
SerializedProperty itemData = arrayData.GetArrayElementAtIndex(index);
EditorGUI.PropertyField(rect, itemData, true);
- } else EditorGUI.LabelField(rect, port != null ? port.fieldName : "");
+ }
+ else
+ EditorGUI.LabelField(rect, port != null ? port.fieldName : "");
+
if (port != null) {
Vector2 pos = rect.position + (port.IsOutput?new Vector2(rect.width + 6, 0) : new Vector2(-36, 0));
NodeEditorGUILayout.PortField(pos, port);
@@ -363,58 +366,43 @@ namespace XNodeEditor {
return EditorGUI.GetPropertyHeight(itemData);
} else return EditorGUIUtility.singleLineHeight;
};
+
list.drawHeaderCallback =
(Rect rect) => {
EditorGUI.LabelField(rect, label);
};
+
list.onSelectCallback =
(ReorderableList rl) => {
reorderableListIndex = rl.index;
};
- list.onReorderCallback =
- (ReorderableList rl) => {
- // Move up
- if (rl.index > reorderableListIndex) {
- for (int i = reorderableListIndex; i < rl.index; ++i) {
- XNode.NodePort port = node.GetPort(fieldName + " " + i);
- XNode.NodePort nextPort = node.GetPort(fieldName + " " + (i + 1));
- port.SwapConnections(nextPort);
-
- // Swap cached positions to mitigate twitching
- Rect rect = NodeEditorWindow.current.portConnectionPoints[port];
- NodeEditorWindow.current.portConnectionPoints[port] = NodeEditorWindow.current.portConnectionPoints[nextPort];
- NodeEditorWindow.current.portConnectionPoints[nextPort] = rect;
- }
+ list.onReorderCallbackWithDetails = (reorderableList, index, newIndex) =>
+ {
+ var port = serializedObject.FindProperty(Node.PortFieldName);
+ SerializedProperty keys = port.FindPropertyRelative(Node.KeysFieldName);
+ SerializedProperty values = port.FindPropertyRelative(Node.ValuesFieldName);
+ var count = 0;
+
+ foreach (var nodePort in node.Ports)
+ {
+ if (!reorderableList.list.Contains(nodePort))
+ {
+ count++;
+
+ continue;
}
- // Move down
- else {
- for (int i = reorderableListIndex; i > rl.index; --i) {
- XNode.NodePort port = node.GetPort(fieldName + " " + i);
- XNode.NodePort nextPort = node.GetPort(fieldName + " " + (i - 1));
- port.SwapConnections(nextPort);
+
+ //list after May exist dynamic node so break
+ break;
+ }
+
+ index += count;
+ newIndex += count;
+ keys.MoveArrayElement(index, newIndex);
+ values.MoveArrayElement(index, newIndex);
+ };
- // Swap cached positions to mitigate twitching
- Rect rect = NodeEditorWindow.current.portConnectionPoints[port];
- NodeEditorWindow.current.portConnectionPoints[port] = NodeEditorWindow.current.portConnectionPoints[nextPort];
- NodeEditorWindow.current.portConnectionPoints[nextPort] = rect;
- }
- }
- // Apply changes
- serializedObject.ApplyModifiedProperties();
- serializedObject.Update();
-
- // Move array data if there is any
- if (hasArrayData) {
- arrayData.MoveArrayElement(reorderableListIndex, rl.index);
- }
-
- // Apply changes
- serializedObject.ApplyModifiedProperties();
- serializedObject.Update();
- NodeEditorWindow.current.Repaint();
- EditorApplication.delayCall += NodeEditorWindow.current.Repaint;
- };
list.onAddCallback =
(ReorderableList rl) => {
// Add dynamic port postfixed with an index number
@@ -432,19 +420,11 @@ namespace XNodeEditor {
serializedObject.ApplyModifiedProperties();
};
list.onRemoveCallback =
- (ReorderableList rl) => {
+ (ReorderableList rl) =>
+ {
- var indexedPorts = node.DynamicPorts.Select(x => {
- string[] split = x.fieldName.Split(' ');
- if (split != null && split.Length == 2 && split[0] == fieldName) {
- int i = -1;
- if (int.TryParse(split[1], out i)) {
- return new { index = i, port = x };
- }
- }
- return new { index = -1, port = (XNode.NodePort) null };
- }).Where(x => x.port != null);
- dynamicPorts = indexedPorts.OrderBy(x => x.index).Select(x => x.port).ToList();
+ var indexedPorts = node.DynamicPorts;
+ dynamicPorts = indexedPorts.ToList();
int index = rl.index;
diff --git a/Scripts/Node.cs b/Scripts/Node.cs
index 7fbf4c1..9996e73 100644
--- a/Scripts/Node.cs
+++ b/Scripts/Node.cs
@@ -111,6 +111,12 @@ namespace XNode {
/// It is recommended not to modify these at hand. Instead, see and
[SerializeField] private NodePortDictionary ports = new NodePortDictionary();
+#if UNITY_EDITOR
+ public const string PortFieldName = nameof(ports);
+ public const string KeysFieldName = NodePortDictionary.KeyFieldName;
+ public const string ValuesFieldName = NodePortDictionary.ValueFieldName;
+#endif
+
/// Used during node instantiation to fix null/misconfigured graph during OnEnable/Init. Set it before instantiating a node. Will automatically be unset during OnEnable
public static NodeGraph graphHotfix;
@@ -366,6 +372,11 @@ namespace XNode {
[SerializeField] private List keys = new List();
[SerializeField] private List values = new List();
+#if UNITY_EDITOR
+ public const string KeyFieldName = nameof(keys);
+ public const string ValueFieldName = nameof(values);
+#endif
+
public void OnBeforeSerialize() {
keys.Clear();
values.Clear();