From 346bd84d8be21797d73075849c6f445ca2a44d67 Mon Sep 17 00:00:00 2001 From: taoria <445625470@qq.com> Date: Sat, 20 Aug 2022 16:37:04 +0800 Subject: [PATCH] feature:add a watcher to monitor the iteration situation --- Samples/AddNode.cs | 7 +- Samples/New HelloGraph.asset | 156 ++++++++++++++++-- TNodeCore/Editor/GraphWatcher.meta | 3 + TNodeCore/Editor/GraphWatcher/GraphWatcher.cs | 11 ++ .../Editor/GraphWatcher/GraphWatcher.cs.meta | 3 + .../NodeGraphView/IBaseDataGraphView.cs | 3 +- TNodeCore/Editor/Resources/GraphEditor.uxml | 4 +- TNodeCore/Runtime/Components/RuntimeGraph.cs | 9 +- .../Runtime/Extensions/NodeDataExtensions.cs | 10 ++ .../Extensions/NodeDataExtensions.cs.meta | 3 + .../RuntimeModels/IRuntimeNodeGraph.cs | 11 +- .../Runtime/RuntimeModels/StaticGraph.cs | 29 ++-- TNodeCore/Runtime/Tools/GraphTool.cs | 26 ++- .../Editor/GraphWatcherView.meta | 3 + .../GraphWatcherView/GraphWatcherView.cs | 58 +++++++ .../GraphWatcherView/GraphWatcherView.cs.meta | 3 + .../Editor/Inspector/NodeInspectorInNode.cs | 29 +--- .../Editor/NodeGraphView/DataGraphView.cs | 109 +++++++----- .../NodeGraphView/SimpleGraphSubWindow.cs | 6 - .../Editor/Resources/GraphWatcher.uxml | 21 +++ .../Editor/Resources/GraphWatcher.uxml.meta | 3 + .../Editor/Resources/GraphWatcherStyle.uss | 3 + .../Resources/GraphWatcherStyle.uss.meta | 3 + .../Editor/Resources/NodeViewHighlight.uss | 4 + .../Resources/NodeViewHighlight.uss.meta | 3 + Tests.meta | 8 + Tests/NodePortTest.cs | 59 +++++++ Tests/NodePortTest.cs.meta | 11 ++ Tests/StaticGraphTest.cs | 10 +- Tests/Tests.asmdef | 26 +++ Tests/Tests.asmdef.meta | 7 + 31 files changed, 514 insertions(+), 127 deletions(-) create mode 100644 TNodeCore/Editor/GraphWatcher.meta create mode 100644 TNodeCore/Editor/GraphWatcher/GraphWatcher.cs create mode 100644 TNodeCore/Editor/GraphWatcher/GraphWatcher.cs.meta create mode 100644 TNodeCore/Runtime/Extensions/NodeDataExtensions.cs create mode 100644 TNodeCore/Runtime/Extensions/NodeDataExtensions.cs.meta create mode 100644 TNodeGraphViewImpl/Editor/GraphWatcherView.meta create mode 100644 TNodeGraphViewImpl/Editor/GraphWatcherView/GraphWatcherView.cs create mode 100644 TNodeGraphViewImpl/Editor/GraphWatcherView/GraphWatcherView.cs.meta create mode 100644 TNodeGraphViewImpl/Editor/Resources/GraphWatcher.uxml create mode 100644 TNodeGraphViewImpl/Editor/Resources/GraphWatcher.uxml.meta create mode 100644 TNodeGraphViewImpl/Editor/Resources/GraphWatcherStyle.uss create mode 100644 TNodeGraphViewImpl/Editor/Resources/GraphWatcherStyle.uss.meta create mode 100644 TNodeGraphViewImpl/Editor/Resources/NodeViewHighlight.uss create mode 100644 TNodeGraphViewImpl/Editor/Resources/NodeViewHighlight.uss.meta create mode 100644 Tests.meta create mode 100644 Tests/NodePortTest.cs create mode 100644 Tests/NodePortTest.cs.meta create mode 100644 Tests/Tests.asmdef create mode 100644 Tests/Tests.asmdef.meta diff --git a/Samples/AddNode.cs b/Samples/AddNode.cs index 50f284d..4b651fc 100644 --- a/Samples/AddNode.cs +++ b/Samples/AddNode.cs @@ -16,15 +16,10 @@ namespace Samples{ public Vector2 B{ get; set; } [Output] public Vector3 Res{ get; set; } - - [Output(Group = true)] public List OutputList => new List{new Vector3(),new Vector3()}; - - public override void Process(){ Res = A + (Vector3)B; - Debug.Log(Res); - this.Log(Res.ToString()); + this.Log($"{Res}"); } } } \ No newline at end of file diff --git a/Samples/New HelloGraph.asset b/Samples/New HelloGraph.asset index cc4a8b8..b4c5b29 100644 --- a/Samples/New HelloGraph.asset +++ b/Samples/New HelloGraph.asset @@ -15,48 +15,172 @@ MonoBehaviour: nodeList: - id: 0 - id: 1 + - id: 2 + - id: 3 + - id: 4 + - id: 5 + - id: 6 nodeLinks: + - inPort: + portEntryName: B + nodeDataId: 94327133-34e1-47bb-a365-0782120c581e + outPort: + portEntryName: Value + nodeDataId: 07c1f545-719b-4f9b-9f4c-dc3883c02423 + - inPort: + portEntryName: A + nodeDataId: 94327133-34e1-47bb-a365-0782120c581e + outPort: + portEntryName: Value + nodeDataId: 72477a0c-2399-47c1-ba04-495add218335 - inPort: portEntryName: A + nodeDataId: 134adf78-f8ba-4888-8362-4a2ca0df2c69 + outPort: + portEntryName: Res nodeDataId: 94327133-34e1-47bb-a365-0782120c581e + - inPort: + portEntryName: B + nodeDataId: 134adf78-f8ba-4888-8362-4a2ca0df2c69 + outPort: + portEntryName: Value + nodeDataId: 9b6e59e3-cc30-4697-a310-8f1195631ec9 + - inPort: + portEntryName: A + nodeDataId: 8d01abf2-f69a-4884-a6a1-99903ed96b7a + outPort: + portEntryName: Value + nodeDataId: 72477a0c-2399-47c1-ba04-495add218335 + - inPort: + portEntryName: B + nodeDataId: 8d01abf2-f69a-4884-a6a1-99903ed96b7a + outPort: + portEntryName: Value + nodeDataId: 07c1f545-719b-4f9b-9f4c-dc3883c02423 + - inPort: + portEntryName: A + nodeDataId: d4ff4eb9-dd02-4712-90dc-898223d1758f + outPort: + portEntryName: Res + nodeDataId: 8d01abf2-f69a-4884-a6a1-99903ed96b7a + - inPort: + portEntryName: B + nodeDataId: d4ff4eb9-dd02-4712-90dc-898223d1758f outPort: - portEntryName: OutputList:1 - nodeDataId: 8289b5d6-f55f-480e-8c16-ae3af7a282dd + portEntryName: Value + nodeDataId: 07c1f545-719b-4f9b-9f4c-dc3883c02423 blackboardData: - id: 2 + id: 7 sceneReference: editorModels: [] graphViewModel: - id: 3 + id: 8 references: version: 1 00000000: + type: {class: BlackboardDragNode, ns: TNodeCore.Runtime.Models, asm: Taoria.TNodeCore.Runtime} + data: + positionInView: + serializedVersion: 2 + x: 550 + y: 218 + width: 0 + height: 0 + id: 72477a0c-2399-47c1-ba04-495add218335 + nodeName: + entryPoint: 0 + isTest: 0 + blackboardDragTypeString: UnityEngine.Vector3, UnityEngine.CoreModule, Version=0.0.0.0, + Culture=neutral, PublicKeyToken=null + blackDragData: V3S.0 + isListElement: 1 + 00000001: type: {class: AddNode, ns: Samples, asm: Assembly-CSharp} data: positionInView: serializedVersion: 2 - x: 396 - y: 215 + x: 906 + y: 29 width: 0 height: 0 - id: 8289b5d6-f55f-480e-8c16-ae3af7a282dd + id: d4ff4eb9-dd02-4712-90dc-898223d1758f nodeName: AddNode entryPoint: 0 isTest: 0 - 00000001: + 00000002: + type: {class: BlackboardDragNode, ns: TNodeCore.Runtime.Models, asm: Taoria.TNodeCore.Runtime} + data: + positionInView: + serializedVersion: 2 + x: 574 + y: 306 + width: 0 + height: 0 + id: 07c1f545-719b-4f9b-9f4c-dc3883c02423 + nodeName: + entryPoint: 0 + isTest: 0 + blackboardDragTypeString: UnityEngine.Vector2, UnityEngine.CoreModule, Version=0.0.0.0, + Culture=neutral, PublicKeyToken=null + blackDragData: V2S.0 + isListElement: 1 + 00000003: + type: {class: AddNode, ns: Samples, asm: Assembly-CSharp} + data: + positionInView: + serializedVersion: 2 + x: 733 + y: 52 + width: 0 + height: 0 + id: 8d01abf2-f69a-4884-a6a1-99903ed96b7a + nodeName: AddNode + entryPoint: 0 + isTest: 0 + 00000004: + type: {class: BlackboardDragNode, ns: TNodeCore.Runtime.Models, asm: Taoria.TNodeCore.Runtime} + data: + positionInView: + serializedVersion: 2 + x: 817 + y: 387 + width: 0 + height: 0 + id: 9b6e59e3-cc30-4697-a310-8f1195631ec9 + nodeName: + entryPoint: 0 + isTest: 0 + blackboardDragTypeString: UnityEngine.Vector2, UnityEngine.CoreModule, Version=0.0.0.0, + Culture=neutral, PublicKeyToken=null + blackDragData: V2S.0 + isListElement: 1 + 00000005: type: {class: AddNode, ns: Samples, asm: Assembly-CSharp} data: positionInView: serializedVersion: 2 - x: 569 - y: 215 + x: 669.5 + y: 198.5 width: 0 height: 0 id: 94327133-34e1-47bb-a365-0782120c581e nodeName: AddNode entryPoint: 0 isTest: 0 - 00000002: + 00000006: + type: {class: AddNode, ns: Samples, asm: Assembly-CSharp} + data: + positionInView: + serializedVersion: 2 + x: 1007 + y: 199 + width: 0 + height: 0 + id: 134adf78-f8ba-4888-8362-4a2ca0df2c69 + nodeName: AddNode + entryPoint: 0 + isTest: 0 + 00000007: type: {class: HelloBlackboard, ns: TNode.Samples, asm: Assembly-CSharp} data: positionInView: @@ -68,9 +192,11 @@ MonoBehaviour: id: HelloString: HelloGameObject: {fileID: 0} - V3S: [] - V2S: [] - 00000003: + V3S: + - {x: 0, y: 0, z: 0} + V2S: + - {x: 4, y: 4} + 00000008: type: {class: GraphViewModel, ns: TNode.TNodeCore.Editor.Models, asm: Taoria.TNodeCore.Runtime} data: positionInView: @@ -81,5 +207,5 @@ MonoBehaviour: height: 0 id: persistScale: 1 - persistOffset: {x: 0, y: 0} + persistOffset: {x: -169, y: 62} isBlackboardOn: 1 diff --git a/TNodeCore/Editor/GraphWatcher.meta b/TNodeCore/Editor/GraphWatcher.meta new file mode 100644 index 0000000..6f92ec7 --- /dev/null +++ b/TNodeCore/Editor/GraphWatcher.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: f530d96c0a1b4f3482c773cc8666a5e9 +timeCreated: 1660970766 \ No newline at end of file diff --git a/TNodeCore/Editor/GraphWatcher/GraphWatcher.cs b/TNodeCore/Editor/GraphWatcher/GraphWatcher.cs new file mode 100644 index 0000000..b80a603 --- /dev/null +++ b/TNodeCore/Editor/GraphWatcher/GraphWatcher.cs @@ -0,0 +1,11 @@ +using TNodeCore.Runtime.RuntimeModels; + +namespace TNodeCore.Editor.GraphWatcher{ + /// + /// Graph watcher is a tool watch the process of a graph.it don't modify the state. + /// + public class GraphWatcher{ + public IRuntimeNodeGraph WatchedGraph; + + } +} \ No newline at end of file diff --git a/TNodeCore/Editor/GraphWatcher/GraphWatcher.cs.meta b/TNodeCore/Editor/GraphWatcher/GraphWatcher.cs.meta new file mode 100644 index 0000000..4454b4f --- /dev/null +++ b/TNodeCore/Editor/GraphWatcher/GraphWatcher.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 43ac53b5c1a049869c57eec0f69abf59 +timeCreated: 1660970756 \ No newline at end of file diff --git a/TNodeCore/Editor/NodeGraphView/IBaseDataGraphView.cs b/TNodeCore/Editor/NodeGraphView/IBaseDataGraphView.cs index 1540f7c..814fc2e 100644 --- a/TNodeCore/Editor/NodeGraphView/IBaseDataGraphView.cs +++ b/TNodeCore/Editor/NodeGraphView/IBaseDataGraphView.cs @@ -2,6 +2,7 @@ using TNodeCore.Runtime; using TNodeCore.Runtime.Components; using TNodeCore.Runtime.Models; +using TNodeCore.Runtime.RuntimeModels; using UnityEngine; namespace TNodeCore.Editor.NodeGraphView{ @@ -65,7 +66,7 @@ namespace TNodeCore.Editor.NodeGraphView{ /// Null if it is not a runtime graph /// /// - public RuntimeGraph GetRuntimeGraph(); + public IRuntimeNodeGraph GetRuntimeNodeGraph(); /// /// Edit a graph data. /// diff --git a/TNodeCore/Editor/Resources/GraphEditor.uxml b/TNodeCore/Editor/Resources/GraphEditor.uxml index 0a2e40f..5d3257e 100644 --- a/TNodeCore/Editor/Resources/GraphEditor.uxml +++ b/TNodeCore/Editor/Resources/GraphEditor.uxml @@ -1,3 +1,5 @@ - + diff --git a/TNodeCore/Runtime/Components/RuntimeGraph.cs b/TNodeCore/Runtime/Components/RuntimeGraph.cs index bdc50fd..3159915 100644 --- a/TNodeCore/Runtime/Components/RuntimeGraph.cs +++ b/TNodeCore/Runtime/Components/RuntimeGraph.cs @@ -175,7 +175,7 @@ namespace TNodeCore.Runtime.Components{ } public NodeData CurrentNode(){ - return _runtimeNodeEnumerator.Current?.NodeData; + return CurrentRuntimeNode().NodeData; } public RuntimeNode MoveNext(){ @@ -184,6 +184,9 @@ namespace TNodeCore.Runtime.Components{ } public RuntimeNode CurrentRuntimeNode(){ + if (_runtimeNodeEnumerator.Current == null){ + _runtimeNodeEnumerator.MoveNext(); + } return _runtimeNodeEnumerator.Current; } @@ -283,6 +286,10 @@ namespace TNodeCore.Runtime.Components{ return null; } + public BlackboardData GetBlackboardData(){ + return runtimeBlackboardData; + } + public List GetRuntimeNodes(){ return RuntimeNodes.Values.ToList(); } diff --git a/TNodeCore/Runtime/Extensions/NodeDataExtensions.cs b/TNodeCore/Runtime/Extensions/NodeDataExtensions.cs new file mode 100644 index 0000000..a21e1eb --- /dev/null +++ b/TNodeCore/Runtime/Extensions/NodeDataExtensions.cs @@ -0,0 +1,10 @@ +using System.Linq; +using TNodeCore.Runtime.Models; + +namespace TNodeCore.Runtime.Extensions{ + public static class NodeDataExtensions{ + public static string[] GetDependentNodesId(this RuntimeNode runtimeNode){ + return runtimeNode.InputLinks.Select(x => x.outPort.nodeDataId).ToArray(); + } + } +} \ No newline at end of file diff --git a/TNodeCore/Runtime/Extensions/NodeDataExtensions.cs.meta b/TNodeCore/Runtime/Extensions/NodeDataExtensions.cs.meta new file mode 100644 index 0000000..c463c8f --- /dev/null +++ b/TNodeCore/Runtime/Extensions/NodeDataExtensions.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 251253baee3d4aa49bc739b8661b637a +timeCreated: 1660983683 \ No newline at end of file diff --git a/TNodeCore/Runtime/RuntimeModels/IRuntimeNodeGraph.cs b/TNodeCore/Runtime/RuntimeModels/IRuntimeNodeGraph.cs index c591c6b..fcce0b4 100644 --- a/TNodeCore/Runtime/RuntimeModels/IRuntimeNodeGraph.cs +++ b/TNodeCore/Runtime/RuntimeModels/IRuntimeNodeGraph.cs @@ -6,7 +6,7 @@ namespace TNodeCore.Runtime.RuntimeModels{ public interface IRuntimeNodeGraph{ public RuntimeNode GetRuntimeNode(NodeData nodeData); public RuntimeNode GetRuntimeNode(string id); - + public BlackboardData GetBlackboardData(); public List GetRuntimeNodes(); public Dictionary GetRuntimeNodesDictionary(); @@ -19,11 +19,10 @@ namespace TNodeCore.Runtime.RuntimeModels{ /// /// public void ResetState(); - public NodeData CurrentNode(); - public RuntimeNode MoveNext(); - public RuntimeNode CurrentRuntimeNode(); - - + + RuntimeNode MoveNext(); + NodeData CurrentNode(); + RuntimeNode CurrentRuntimeNode(); } } \ No newline at end of file diff --git a/TNodeCore/Runtime/RuntimeModels/StaticGraph.cs b/TNodeCore/Runtime/RuntimeModels/StaticGraph.cs index a5bac35..e184151 100644 --- a/TNodeCore/Runtime/RuntimeModels/StaticGraph.cs +++ b/TNodeCore/Runtime/RuntimeModels/StaticGraph.cs @@ -8,8 +8,10 @@ using TNodeCore.Runtime.Models; namespace TNodeCore.Runtime.RuntimeModels{ public class StaticGraph:IRuntimeNodeGraph{ private Dictionary _nodes; - private GraphTool _graphTool; - private IEnumerator BreathFirstEnumerator; + private IEnumerator _breathFirstEnumerator; + + private readonly GraphTool _graphTool; + private readonly GraphData _originalData; private void ModifyLinks(NodeLink linkData){ var outNodeId = linkData.outPort.nodeDataId; @@ -19,7 +21,10 @@ namespace TNodeCore.Runtime.RuntimeModels{ var inNode = _nodes[inNodeId]; inNode.InputLinks.Add(linkData); } - public StaticGraph(List nodes,List links){ + public StaticGraph(GraphData graphData){ + _originalData = graphData; + var nodes = graphData.NodeDictionary.Values.ToList(); + var links = graphData.NodeLinks; _nodes = new Dictionary(); @@ -42,11 +47,11 @@ namespace TNodeCore.Runtime.RuntimeModels{ ModifyLinks(link); } _graphTool = new GraphTool(this); - BreathFirstEnumerator = _graphTool.BreathFirstSearch(); + _breathFirstEnumerator = _graphTool.BreathFirstSearch(); } public void ResetState(){ - BreathFirstEnumerator = _graphTool.BreathFirstSearch(); + _breathFirstEnumerator = _graphTool.BreathFirstSearch(); } public RuntimeNode GetRuntimeNode(NodeData nodeData){ @@ -57,6 +62,10 @@ namespace TNodeCore.Runtime.RuntimeModels{ return _nodes[id]; } + public BlackboardData GetBlackboardData(){ + return _originalData.blackboardData; + } + public List GetRuntimeNodes(){ return _nodes.Values.ToList(); } @@ -83,15 +92,15 @@ namespace TNodeCore.Runtime.RuntimeModels{ } public RuntimeNode MoveNext(){ - BreathFirstEnumerator.MoveNext(); - return BreathFirstEnumerator.Current; + _breathFirstEnumerator.MoveNext(); + return _breathFirstEnumerator.Current; } public RuntimeNode CurrentRuntimeNode(){ - if (BreathFirstEnumerator.Current == null){ - BreathFirstEnumerator.MoveNext(); + if (_breathFirstEnumerator.Current == null){ + _breathFirstEnumerator.MoveNext(); } - return BreathFirstEnumerator.Current; + return _breathFirstEnumerator.Current; } } diff --git a/TNodeCore/Runtime/Tools/GraphTool.cs b/TNodeCore/Runtime/Tools/GraphTool.cs index ba628b0..392a6a5 100644 --- a/TNodeCore/Runtime/Tools/GraphTool.cs +++ b/TNodeCore/Runtime/Tools/GraphTool.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using TNodeCore.Runtime; using TNodeCore.Runtime.Components; +using TNodeCore.Runtime.Extensions; using TNodeCore.Runtime.Models; using TNodeCore.Runtime.RuntimeModels; using UnityEngine; @@ -81,23 +82,27 @@ namespace TNode.TNodeCore.Runtime.Tools{ } public IEnumerator BreathFirstSearch(){ Queue queue = new Queue(); + HashSet alreadyContained = new HashSet(); + HashSet visited = new HashSet(); foreach (var runtimeNode in NonDependencyNode){ queue.Enqueue(runtimeNode); + alreadyContained.Add(runtimeNode); } while (queue.Count > 0){ var node = queue.Dequeue(); + visited.Add(node); if (node is ConditionalRuntimeNode conditionalRuntimeNode){ var ids = conditionalRuntimeNode.GetConditionalNextIds(); var nextNodes = ids.Select(id=>RuntimeNodes[id]).ToList(); foreach (var runtimeNode in nextNodes){ - queue.Enqueue(runtimeNode); + AddNodeToQueueIfMeetCondition(alreadyContained, runtimeNode, queue); } } else{ foreach (var runtimeNode in node.OutputLinks.Select(link => RuntimeNodes[link.inPort.nodeDataId])){ - queue.Enqueue(runtimeNode); + AddNodeToQueueIfMeetCondition(alreadyContained, runtimeNode, queue); } node.OutputLinks.ForEach(HandlingLink); } @@ -105,9 +110,22 @@ namespace TNode.TNodeCore.Runtime.Tools{ yield return node; } } - - + private void AddNodeToQueueIfMeetCondition(HashSet alreadyContained, RuntimeNode runtimeNode, Queue queue){ + //Check if the node is already contained in the queue + if (alreadyContained.Contains(runtimeNode)) return; + + //Check if the visited node has all previous node of the node + var dependentNodes = runtimeNode.GetDependentNodesId().Select(x => RuntimeNodes[x]); + var allDependenciesVisited = dependentNodes.Aggregate(true, (a, b) => + alreadyContained.Contains(b) && a + ); + if (allDependenciesVisited == false) return; + + //If all conditions are met, add the node to the queue + queue.Enqueue(runtimeNode); + alreadyContained.Add(runtimeNode); + } /// diff --git a/TNodeGraphViewImpl/Editor/GraphWatcherView.meta b/TNodeGraphViewImpl/Editor/GraphWatcherView.meta new file mode 100644 index 0000000..6193a33 --- /dev/null +++ b/TNodeGraphViewImpl/Editor/GraphWatcherView.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 4a1dbd79f6d746ee830b851f2934c445 +timeCreated: 1660972144 \ No newline at end of file diff --git a/TNodeGraphViewImpl/Editor/GraphWatcherView/GraphWatcherView.cs b/TNodeGraphViewImpl/Editor/GraphWatcherView/GraphWatcherView.cs new file mode 100644 index 0000000..11812ea --- /dev/null +++ b/TNodeGraphViewImpl/Editor/GraphWatcherView/GraphWatcherView.cs @@ -0,0 +1,58 @@ +using System.Linq; +using TNodeCore.Editor.NodeGraphView; +using TNodeGraphViewImpl.Editor.NodeGraphView; +using TNodeGraphViewImpl.Editor.NodeViews; +using UnityEditor.Experimental.GraphView; +using UnityEngine; +using UnityEngine.UIElements; + +namespace TNodeGraphViewImpl.Editor.GraphWatcherView{ + public class GraphWatcherView:SimpleGraphSubWindow{ + private Node _highlightedNode; + + public GraphWatcherView() : base(Resources.Load("GraphWatcher")){ + styleSheets.Add(Resources.Load("GraphWatcherStyle")); + var button = this.Q