mirror of
https://github.com/Siccity/xNode.git
synced 2026-03-26 22:49:02 +08:00
!O(Dynamic Port List) 默认实现存在潜规则,删除了潜规则
This commit is contained in:
parent
1fece9c7c5
commit
413f4e2f52
@ -6,6 +6,7 @@ using System.Reflection;
|
|||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
using UnityEditorInternal;
|
using UnityEditorInternal;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using XNode;
|
||||||
|
|
||||||
namespace XNodeEditor {
|
namespace XNodeEditor {
|
||||||
/// <summary> xNode-specific version of <see cref="EditorGUILayout"/> </summary>
|
/// <summary> xNode-specific version of <see cref="EditorGUILayout"/> </summary>
|
||||||
@ -302,23 +303,19 @@ namespace XNodeEditor {
|
|||||||
/// <param name="connectionType">Connection type of added dynamic ports</param>
|
/// <param name="connectionType">Connection type of added dynamic ports</param>
|
||||||
/// <param name="inputTypeConstraintBaseType">当<see cref="io"/>为<see cref="IO.Input"/>并且<see cref="typeConstraint"/>为<see cref="TypeConstraint.Inherited"/>时可用</param>
|
/// <param name="inputTypeConstraintBaseType">当<see cref="io"/>为<see cref="IO.Input"/>并且<see cref="typeConstraint"/>为<see cref="TypeConstraint.Inherited"/>时可用</param>
|
||||||
/// <param name="onCreation">Called on the list on creation. Use this if you want to customize the created ReorderableList</param>
|
/// <param name="onCreation">Called on the list on creation. Use this if you want to customize the created ReorderableList</param>
|
||||||
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<ReorderableList> 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<ReorderableList> onCreation = null) {
|
||||||
XNode.Node node = serializedObject.targetObject as XNode.Node;
|
XNode.Node node = serializedObject.targetObject as XNode.Node;
|
||||||
|
|
||||||
var indexedPorts = node.DynamicPorts.Select(x => {
|
var indexedPorts = node.DynamicPorts;
|
||||||
string[] split = x.fieldName.Split(' ');
|
|
||||||
if (split != null && split.Length == 2 && split[0] == fieldName) {
|
List<XNode.NodePort> dynamicPorts = indexedPorts.ToList();
|
||||||
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<XNode.NodePort> dynamicPorts = indexedPorts.OrderBy(x => x.index).Select(x => x.port).ToList();
|
|
||||||
|
|
||||||
ReorderableList list = null;
|
ReorderableList list = null;
|
||||||
Dictionary<string, ReorderableList> rlc;
|
Dictionary<string, ReorderableList> rlc;
|
||||||
|
//todo rename no update cache -- 2019年11月28日03点00分
|
||||||
if (reorderableListCache.TryGetValue(serializedObject.targetObject, out rlc)) {
|
if (reorderableListCache.TryGetValue(serializedObject.targetObject, out rlc)) {
|
||||||
if (!rlc.TryGetValue(fieldName, out list)) list = null;
|
if (!rlc.TryGetValue(fieldName, out list)) list = null;
|
||||||
}
|
}
|
||||||
@ -340,16 +337,22 @@ namespace XNodeEditor {
|
|||||||
string label = arrayData != null ? arrayData.displayName : ObjectNames.NicifyVariableName(fieldName);
|
string label = arrayData != null ? arrayData.displayName : ObjectNames.NicifyVariableName(fieldName);
|
||||||
|
|
||||||
list.drawElementCallback =
|
list.drawElementCallback =
|
||||||
(Rect rect, int index, bool isActive, bool isFocused) => {
|
(Rect rect, int index, bool isActive, bool isFocused) =>
|
||||||
XNode.NodePort port = node.GetPort(fieldName + " " + index);
|
{
|
||||||
if (hasArrayData) {
|
XNode.NodePort port = (NodePort) list.list[index];
|
||||||
|
|
||||||
|
if (hasArrayData)
|
||||||
|
{
|
||||||
if (arrayData.arraySize <= index) {
|
if (arrayData.arraySize <= index) {
|
||||||
EditorGUI.LabelField(rect, "Array[" + index + "] data out of range");
|
EditorGUI.LabelField(rect, "Array[" + index + "] data out of range");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SerializedProperty itemData = arrayData.GetArrayElementAtIndex(index);
|
SerializedProperty itemData = arrayData.GetArrayElementAtIndex(index);
|
||||||
EditorGUI.PropertyField(rect, itemData, true);
|
EditorGUI.PropertyField(rect, itemData, true);
|
||||||
} else EditorGUI.LabelField(rect, port != null ? port.fieldName : "");
|
}
|
||||||
|
else
|
||||||
|
EditorGUI.LabelField(rect, port != null ? port.fieldName : "");
|
||||||
|
|
||||||
if (port != null) {
|
if (port != null) {
|
||||||
Vector2 pos = rect.position + (port.IsOutput?new Vector2(rect.width + 6, 0) : new Vector2(-36, 0));
|
Vector2 pos = rect.position + (port.IsOutput?new Vector2(rect.width + 6, 0) : new Vector2(-36, 0));
|
||||||
NodeEditorGUILayout.PortField(pos, port);
|
NodeEditorGUILayout.PortField(pos, port);
|
||||||
@ -363,58 +366,43 @@ namespace XNodeEditor {
|
|||||||
return EditorGUI.GetPropertyHeight(itemData);
|
return EditorGUI.GetPropertyHeight(itemData);
|
||||||
} else return EditorGUIUtility.singleLineHeight;
|
} else return EditorGUIUtility.singleLineHeight;
|
||||||
};
|
};
|
||||||
|
|
||||||
list.drawHeaderCallback =
|
list.drawHeaderCallback =
|
||||||
(Rect rect) => {
|
(Rect rect) => {
|
||||||
EditorGUI.LabelField(rect, label);
|
EditorGUI.LabelField(rect, label);
|
||||||
};
|
};
|
||||||
|
|
||||||
list.onSelectCallback =
|
list.onSelectCallback =
|
||||||
(ReorderableList rl) => {
|
(ReorderableList rl) => {
|
||||||
reorderableListIndex = rl.index;
|
reorderableListIndex = rl.index;
|
||||||
};
|
};
|
||||||
list.onReorderCallback =
|
|
||||||
(ReorderableList rl) => {
|
|
||||||
|
|
||||||
// Move up
|
list.onReorderCallbackWithDetails = (reorderableList, index, newIndex) =>
|
||||||
if (rl.index > reorderableListIndex) {
|
{
|
||||||
for (int i = reorderableListIndex; i < rl.index; ++i) {
|
var port = serializedObject.FindProperty(Node.PortFieldName);
|
||||||
XNode.NodePort port = node.GetPort(fieldName + " " + i);
|
SerializedProperty keys = port.FindPropertyRelative(Node.KeysFieldName);
|
||||||
XNode.NodePort nextPort = node.GetPort(fieldName + " " + (i + 1));
|
SerializedProperty values = port.FindPropertyRelative(Node.ValuesFieldName);
|
||||||
port.SwapConnections(nextPort);
|
var count = 0;
|
||||||
|
|
||||||
// Swap cached positions to mitigate twitching
|
foreach (var nodePort in node.Ports)
|
||||||
Rect rect = NodeEditorWindow.current.portConnectionPoints[port];
|
{
|
||||||
NodeEditorWindow.current.portConnectionPoints[port] = NodeEditorWindow.current.portConnectionPoints[nextPort];
|
if (!reorderableList.list.Contains(nodePort))
|
||||||
NodeEditorWindow.current.portConnectionPoints[nextPort] = rect;
|
{
|
||||||
}
|
count++;
|
||||||
}
|
|
||||||
// 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);
|
|
||||||
|
|
||||||
// Swap cached positions to mitigate twitching
|
continue;
|
||||||
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
|
//list after May exist dynamic node so break
|
||||||
serializedObject.ApplyModifiedProperties();
|
break;
|
||||||
serializedObject.Update();
|
}
|
||||||
NodeEditorWindow.current.Repaint();
|
|
||||||
EditorApplication.delayCall += NodeEditorWindow.current.Repaint;
|
index += count;
|
||||||
};
|
newIndex += count;
|
||||||
|
keys.MoveArrayElement(index, newIndex);
|
||||||
|
values.MoveArrayElement(index, newIndex);
|
||||||
|
};
|
||||||
|
|
||||||
list.onAddCallback =
|
list.onAddCallback =
|
||||||
(ReorderableList rl) => {
|
(ReorderableList rl) => {
|
||||||
// Add dynamic port postfixed with an index number
|
// Add dynamic port postfixed with an index number
|
||||||
@ -432,19 +420,11 @@ namespace XNodeEditor {
|
|||||||
serializedObject.ApplyModifiedProperties();
|
serializedObject.ApplyModifiedProperties();
|
||||||
};
|
};
|
||||||
list.onRemoveCallback =
|
list.onRemoveCallback =
|
||||||
(ReorderableList rl) => {
|
(ReorderableList rl) =>
|
||||||
|
{
|
||||||
|
|
||||||
var indexedPorts = node.DynamicPorts.Select(x => {
|
var indexedPorts = node.DynamicPorts;
|
||||||
string[] split = x.fieldName.Split(' ');
|
dynamicPorts = indexedPorts.ToList();
|
||||||
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();
|
|
||||||
|
|
||||||
int index = rl.index;
|
int index = rl.index;
|
||||||
|
|
||||||
|
|||||||
@ -111,6 +111,12 @@ namespace XNode {
|
|||||||
/// <summary> It is recommended not to modify these at hand. Instead, see <see cref="InputAttribute"/> and <see cref="OutputAttribute"/> </summary>
|
/// <summary> It is recommended not to modify these at hand. Instead, see <see cref="InputAttribute"/> and <see cref="OutputAttribute"/> </summary>
|
||||||
[SerializeField] private NodePortDictionary ports = new NodePortDictionary();
|
[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
|
||||||
|
|
||||||
/// <summary> Used during node instantiation to fix null/misconfigured graph during OnEnable/Init. Set it before instantiating a node. Will automatically be unset during OnEnable </summary>
|
/// <summary> Used during node instantiation to fix null/misconfigured graph during OnEnable/Init. Set it before instantiating a node. Will automatically be unset during OnEnable </summary>
|
||||||
public static NodeGraph graphHotfix;
|
public static NodeGraph graphHotfix;
|
||||||
|
|
||||||
@ -366,6 +372,11 @@ namespace XNode {
|
|||||||
[SerializeField] private List<string> keys = new List<string>();
|
[SerializeField] private List<string> keys = new List<string>();
|
||||||
[SerializeField] private List<NodePort> values = new List<NodePort>();
|
[SerializeField] private List<NodePort> values = new List<NodePort>();
|
||||||
|
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
public const string KeyFieldName = nameof(keys);
|
||||||
|
public const string ValueFieldName = nameof(values);
|
||||||
|
#endif
|
||||||
|
|
||||||
public void OnBeforeSerialize() {
|
public void OnBeforeSerialize() {
|
||||||
keys.Clear();
|
keys.Clear();
|
||||||
values.Clear();
|
values.Clear();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user