feature:add a watcher to monitor the iteration situation

main
taoria 3 years ago
parent 92b3048f2b
commit 346bd84d8b
  1. 7
      Samples/AddNode.cs
  2. 156
      Samples/New HelloGraph.asset
  3. 3
      TNodeCore/Editor/GraphWatcher.meta
  4. 11
      TNodeCore/Editor/GraphWatcher/GraphWatcher.cs
  5. 3
      TNodeCore/Editor/GraphWatcher/GraphWatcher.cs.meta
  6. 3
      TNodeCore/Editor/NodeGraphView/IBaseDataGraphView.cs
  7. 4
      TNodeCore/Editor/Resources/GraphEditor.uxml
  8. 9
      TNodeCore/Runtime/Components/RuntimeGraph.cs
  9. 10
      TNodeCore/Runtime/Extensions/NodeDataExtensions.cs
  10. 3
      TNodeCore/Runtime/Extensions/NodeDataExtensions.cs.meta
  11. 11
      TNodeCore/Runtime/RuntimeModels/IRuntimeNodeGraph.cs
  12. 29
      TNodeCore/Runtime/RuntimeModels/StaticGraph.cs
  13. 26
      TNodeCore/Runtime/Tools/GraphTool.cs
  14. 3
      TNodeGraphViewImpl/Editor/GraphWatcherView.meta
  15. 58
      TNodeGraphViewImpl/Editor/GraphWatcherView/GraphWatcherView.cs
  16. 3
      TNodeGraphViewImpl/Editor/GraphWatcherView/GraphWatcherView.cs.meta
  17. 29
      TNodeGraphViewImpl/Editor/Inspector/NodeInspectorInNode.cs
  18. 109
      TNodeGraphViewImpl/Editor/NodeGraphView/DataGraphView.cs
  19. 6
      TNodeGraphViewImpl/Editor/NodeGraphView/SimpleGraphSubWindow.cs
  20. 21
      TNodeGraphViewImpl/Editor/Resources/GraphWatcher.uxml
  21. 3
      TNodeGraphViewImpl/Editor/Resources/GraphWatcher.uxml.meta
  22. 3
      TNodeGraphViewImpl/Editor/Resources/GraphWatcherStyle.uss
  23. 3
      TNodeGraphViewImpl/Editor/Resources/GraphWatcherStyle.uss.meta
  24. 4
      TNodeGraphViewImpl/Editor/Resources/NodeViewHighlight.uss
  25. 3
      TNodeGraphViewImpl/Editor/Resources/NodeViewHighlight.uss.meta
  26. 8
      Tests.meta
  27. 59
      Tests/NodePortTest.cs
  28. 11
      Tests/NodePortTest.cs.meta
  29. 10
      Tests/StaticGraphTest.cs
  30. 26
      Tests/Tests.asmdef
  31. 7
      Tests/Tests.asmdef.meta

@ -16,15 +16,10 @@ namespace Samples{
public Vector2 B{ get; set; }
[Output]
public Vector3 Res{ get; set; }
[Output(Group = true)] public List<Vector3> OutputList => new List<Vector3>{new Vector3(),new Vector3()};
public override void Process(){
Res = A + (Vector3)B;
Debug.Log(Res);
this.Log(Res.ToString());
this.Log($"{Res}");
}
}
}

@ -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

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: f530d96c0a1b4f3482c773cc8666a5e9
timeCreated: 1660970766

@ -0,0 +1,11 @@
using TNodeCore.Runtime.RuntimeModels;
namespace TNodeCore.Editor.GraphWatcher{
/// <summary>
/// Graph watcher is a tool watch the process of a graph.it don't modify the state.
/// </summary>
public class GraphWatcher{
public IRuntimeNodeGraph WatchedGraph;
}
}

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 43ac53b5c1a049869c57eec0f69abf59
timeCreated: 1660970756

@ -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
/// </summary>
/// <returns></returns>
public RuntimeGraph GetRuntimeGraph();
public IRuntimeNodeGraph GetRuntimeNodeGraph();
/// <summary>
/// Edit a graph data.
/// </summary>

@ -1,3 +1,5 @@
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" xsi="http://www.w3.org/2001/XMLSchema-instance" engine="UnityEngine.UIElements" editor="UnityEditor.UIElements" noNamespaceSchemaLocation="../../../UIElementsSchema/UIElements.xsd" editor-extension-mode="True">
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" xsi="http://www.w3.org/2001/XMLSchema-instance"
engine="UnityEngine.UIElements" editor="UnityEditor.UIElements" noNamespaceSchemaLocation="../../../UIElementsSchema/UIElements.xsd"
editor-extension-mode="True">
</ui:UXML>

@ -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<RuntimeNode> GetRuntimeNodes(){
return RuntimeNodes.Values.ToList();
}

@ -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();
}
}
}

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 251253baee3d4aa49bc739b8661b637a
timeCreated: 1660983683

@ -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<RuntimeNode> GetRuntimeNodes();
public Dictionary<string,RuntimeNode> GetRuntimeNodesDictionary();
@ -19,11 +19,10 @@ namespace TNodeCore.Runtime.RuntimeModels{
/// </summary>
/// <returns></returns>
public void ResetState();
public NodeData CurrentNode();
public RuntimeNode MoveNext();
public RuntimeNode CurrentRuntimeNode();
RuntimeNode MoveNext();
NodeData CurrentNode();
RuntimeNode CurrentRuntimeNode();
}
}

@ -8,8 +8,10 @@ using TNodeCore.Runtime.Models;
namespace TNodeCore.Runtime.RuntimeModels{
public class StaticGraph:IRuntimeNodeGraph{
private Dictionary<string,RuntimeNode> _nodes;
private GraphTool _graphTool;
private IEnumerator<RuntimeNode> BreathFirstEnumerator;
private IEnumerator<RuntimeNode> _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<NodeData> nodes,List<NodeLink> links){
public StaticGraph(GraphData graphData){
_originalData = graphData;
var nodes = graphData.NodeDictionary.Values.ToList();
var links = graphData.NodeLinks;
_nodes = new Dictionary<string, RuntimeNode>();
@ -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<RuntimeNode> 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;
}
}

@ -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<RuntimeNode> BreathFirstSearch(){
Queue<RuntimeNode> queue = new Queue<RuntimeNode>();
HashSet<RuntimeNode> alreadyContained = new HashSet<RuntimeNode>();
HashSet<RuntimeNode> visited = new HashSet<RuntimeNode>();
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<RuntimeNode> alreadyContained, RuntimeNode runtimeNode, Queue<RuntimeNode> 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);
}
/// <summary>

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 4a1dbd79f6d746ee830b851f2934c445
timeCreated: 1660972144

@ -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<VisualTreeAsset>("GraphWatcher")){
styleSheets.Add(Resources.Load<StyleSheet>("GraphWatcherStyle"));
var button = this.Q<Button>("Next");
var button2 = this.Q<Button>("Reset");
var label = this.Q<Label>();
button.clicked += () => {
var graphView = GetFirstAncestorOfType<IBaseDataGraphView>();
var runtimeNodeGraph = graphView.GetRuntimeNodeGraph();
runtimeNodeGraph.MoveNext();
label.text = runtimeNodeGraph.CurrentNode().id;
if (graphView is GraphView gv){
if (_highlightedNode != null){
_highlightedNode.RemoveFromClassList("highlightNode");
_highlightedNode.style.borderBottomWidth = _highlightedNode.style.borderLeftWidth =
_highlightedNode.style.borderRightWidth = _highlightedNode.style.borderTopWidth = 0;
}
var baseNodeViews = gv.nodes.ToList().Select(x=>(IBaseNodeView)x);
var node = baseNodeViews.First(x=>x.GetNodeData().id==runtimeNodeGraph.CurrentNode().id);
Debug.Log(node.GetNodeData().id);
var nodeView = (Node)node;
_highlightedNode = nodeView;
_highlightedNode.AddToClassList("highlightNode");
_highlightedNode.style.borderBottomWidth
= _highlightedNode.style.borderLeftWidth
= _highlightedNode.style.borderRightWidth
= _highlightedNode.style.borderTopWidth = 2;
}
};
button2.clicked += () => {
var graphView = GetFirstAncestorOfType<IBaseDataGraphView>();
var runtimeNodeGraph = graphView.GetRuntimeNodeGraph();
label.text = runtimeNodeGraph.CurrentNode().id;
if (graphView is GraphView gv){
if (_highlightedNode != null){
_highlightedNode.RemoveFromClassList("highlightNode");
_highlightedNode.style.borderBottomWidth = _highlightedNode.style.borderLeftWidth =
_highlightedNode.style.borderRightWidth = _highlightedNode.style.borderTopWidth = 0;
}
runtimeNodeGraph.ResetState();
}
};
}
}
}

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 66a72db7130f42e08e54ca06a5017bbf
timeCreated: 1660972154

@ -2,6 +2,7 @@
using TNodeCore.Editor.NodeGraphView;
using TNodeCore.Editor.Serialization;
using TNodeCore.Runtime.Attributes;
using TNodeCore.Runtime.Components;
using TNodeCore.Runtime.Models;
using UnityEditor;
using UnityEditor.UIElements;
@ -66,34 +67,6 @@ namespace TNodeGraphViewImpl.Editor.Inspector{
drawer.Bind(serializedObject);
Add(drawer);
}
var globalTest = GetFirstAncestorOfType<IBaseDataGraphView>()?.AutoUpdate;
if(globalTest??false){
CreateTestButton();
}
else if (_data.isTest){
//Add a test button for the node
CreateTestButton();
}
}
private void CreateTestButton(){
var testButton = new Button(() => {
var test = GetFirstAncestorOfType<IBaseDataGraphView>();
if (test != null){
if(!test.IsRuntimeGraph) return;
var runtimeGraph = test.GetRuntimeGraph();
if (runtimeGraph != null){
var res = runtimeGraph.RunOnDependency(_data);
}
_data.OnTest();
}
}){
text = "Test"
};
Add(testButton);
}
}
}

@ -15,6 +15,7 @@ using TNodeCore.Editor.Tools.NodeCreator;
using TNodeCore.Runtime.Components;
using TNodeCore.Runtime.Models;
using TNodeCore.Runtime.RuntimeCache;
using TNodeCore.Runtime.RuntimeModels;
using TNodeGraphViewImpl.Editor.Cache;
using TNodeGraphViewImpl.Editor.GraphBlackboard;
using TNodeGraphViewImpl.Editor.Inspector;
@ -35,15 +36,16 @@ namespace TNodeGraphViewImpl.Editor.NodeGraphView{
#endregion
#region variables and properties
private T _data;
private RuntimeGraph _runtimeGraph;
private bool _loaded;
private bool _isInspectorOn;
private IRuntimeNodeGraph _runtimeNodeGraph;
private NodeSearchWindowProvider _nodeSearchWindowProvider;
private NodeInspector _nodeInspector;
private Dictionary<string,Node> _nodeDict = new Dictionary<string,Node>();
private IBlackboardView _blackboard;
private bool _loaded;
private GraphViewModel _graphViewModel;
private List<Comment> _comments;
private GraphWatcherView.GraphWatcherView _graphWatcher;
public T Data{
get{ return _data; }
@ -70,6 +72,7 @@ namespace TNodeGraphViewImpl.Editor.NodeGraphView{
#region construct default behaviour
public BaseDataGraphView(){
styleSheets.Add(Resources.Load<StyleSheet>("GraphViewBackground"));
styleSheets.Add(Resources.Load<StyleSheet>("NodeViewHighlight"));
var grid = new GridBackground();
Insert(0,grid);
grid.StretchToParentSize();
@ -85,13 +88,13 @@ namespace TNodeGraphViewImpl.Editor.NodeGraphView{
/// <summary>
/// Probably reusable in later GTFs version
/// </summary>
private void WaitingForAGraph(){
private void WaitingForAGraphDragOnView(){
VisualElement visualElement = new VisualElement();
//Set background color to white
visualElement.style.backgroundColor = new StyleColor(new Color(0.1f, 0.1f, 0.1f, 1));
visualElement.StretchToParentSize();
visualElement.name = "WaitingForAGraph";
visualElement.name = "WaitingForAGraphDragOnView";
Add(visualElement);
visualElement.BringToFront();
@ -110,19 +113,18 @@ namespace TNodeGraphViewImpl.Editor.NodeGraphView{
if (obj is T graphData){
IsRuntimeGraph = false;
Data = graphData;
_runtimeNodeGraph = new StaticGraph(Data);
}
else{
if (obj is GameObject gameObject){
if (gameObject.GetComponent<RuntimeGraph>() != null){
if (gameObject.GetComponent<RuntimeGraph>().graphData != null){
_runtimeGraph = gameObject.GetComponent<RuntimeGraph>();
IsRuntimeGraph = true;
BuildRuntimeGraphBehaviour();
Data = gameObject.GetComponent<RuntimeGraph>().graphData as T;
if(Data==null){
Debug.LogError($"Dragged a wrong graph model to editor,expected {typeof(T)} but got {gameObject.GetComponent<RuntimeGraph>().graphData.GetType()}");
}
}
if (obj is GameObject gameObject
&& gameObject.GetComponent<RuntimeGraph>() != null
&& gameObject.GetComponent<RuntimeGraph>().graphData != null){
_runtimeNodeGraph = gameObject.GetComponent<RuntimeGraph>();
IsRuntimeGraph = true;
BuildRuntimeGraphBehaviour();
Data = gameObject.GetComponent<RuntimeGraph>().graphData as T;
if(Data==null){
Debug.LogError($"Dragged a wrong graph model to editor,expected {typeof(T)} but got {gameObject.GetComponent<RuntimeGraph>().graphData.GetType()}");
}
}
}
@ -164,9 +166,9 @@ namespace TNodeGraphViewImpl.Editor.NodeGraphView{
while (_loaded){
await Task.Delay(TimeSpan.FromSeconds(RefreshRate));
if(_runtimeGraph != null){
if (AutoUpdate){
_runtimeGraph.TraverseAll();
if(_runtimeNodeGraph != null){
if (AutoUpdate && _runtimeNodeGraph is RuntimeGraph runtimeGraph){
runtimeGraph.TraverseAll();
AfterGraphResolved?.Invoke();
}
}
@ -175,25 +177,27 @@ namespace TNodeGraphViewImpl.Editor.NodeGraphView{
private void CheckDataAfterInit(){
if(Data == null){
WaitingForAGraph();
WaitingForAGraphDragOnView();
}
}
private void ConstructDefaultBehaviour(){
private void ConstructView(){
//Register a right click context menu
ConstructViewContextualMenu();
ConstructContextMenu();
}
public void ConstructViewContextualMenu(){
public void ConstructContextMenu(){
RegisterCallback<ContextualMenuPopulateEvent>(evt => {
Vector2 editorPosition = Owner==null?Vector2.zero:Owner.position.position;
//Remove all the previous menu items
evt.menu.MenuItems().Clear();
evt.menu.AppendAction("CreateProp Node", dma => {
var dmaPos = dma.eventInfo.mousePosition+editorPosition;
SearchWindowContext searchWindowContext = new SearchWindowContext(dmaPos,200,200);
var searchWindow = ScriptableObject.CreateInstance<NodeSearchWindowProvider>();
var targetPos = this.viewTransform.matrix.inverse.MultiplyPoint(dma.eventInfo.localMousePosition);
SearchWindowContext searchWindowContext = new SearchWindowContext(dmaPos,200,200);
searchWindow.Setup(typeof(T),this,Owner,targetPos);
Debug.Log(targetPos);
@ -201,10 +205,10 @@ namespace TNodeGraphViewImpl.Editor.NodeGraphView{
});
evt.menu.AppendAction("CreateProp PlacematModel",dma=> {
//find placemat container
var placematContainer = GetPlacematContainer();
var container = GetPlacematContainer();
var targetPos = this.viewTransform.matrix.inverse.MultiplyPoint(dma.eventInfo.localMousePosition);
var dmaPosRect = new Rect(targetPos,new Vector2(500,500));
var placemat = placematContainer.CreatePlacemat<PlacematView>(dmaPosRect,1,"Title");
var placemat = container.CreatePlacemat<PlacematView>(dmaPosRect,1,"Title");
var placematData = new PlacematModel{
title = "Title",
positionInView = dmaPosRect
@ -213,7 +217,7 @@ namespace TNodeGraphViewImpl.Editor.NodeGraphView{
AddPlacemat(placematData);
});
if (this.selection.Any()){
if (selection.Any()){
evt.menu.AppendAction("Comment", dma => {
BuildCommentForSelected();
});
@ -229,9 +233,7 @@ namespace TNodeGraphViewImpl.Editor.NodeGraphView{
var selection = this.selection.OfType<IBaseNodeView>().ToList();
foreach (var baseNodeView in selection){
var comment = new CommentView();
comment.Bind(new Comment(){
});
comment.Bind(new Comment());
((GraphElement)baseNodeView).Add(comment);
comment.Data.CommentedModel = baseNodeView.GetNodeData();
this._data.EditorModels.Add(comment.Data);
@ -257,17 +259,19 @@ namespace TNodeGraphViewImpl.Editor.NodeGraphView{
}
private void OnInit(){
ConstructDefaultBehaviour();
ConstructView();
CheckDataAfterInit();
OnGraphViewCreate();
BuildUndo();
SetDetachedFromPanel();
_loaded = true;
SetDetachedFromPanel();
}
@ -290,10 +294,12 @@ namespace TNodeGraphViewImpl.Editor.NodeGraphView{
}
protected void CreateMenu(){
if (this.Q("TopMenu") != null) return;
var visualElement = new VisualElement{
name = "TopMenu"
};
visualElement.Clear();
visualElement.style.position = Position.Absolute;
visualElement.style.top = 0;
visualElement.style.backgroundColor = new StyleColor(new Color(0.1f, 0.1f, 0.1f, 1));
@ -323,9 +329,9 @@ namespace TNodeGraphViewImpl.Editor.NodeGraphView{
};
runButton.RegisterCallback<ClickEvent>(evt => {
if (IsRuntimeGraph){
if (IsRuntimeGraph && _runtimeNodeGraph is RuntimeGraph runtimeGraph){
_runtimeGraph.TraverseAll();
runtimeGraph.TraverseAll();
AfterGraphResolved?.Invoke();
}
});
@ -340,8 +346,25 @@ namespace TNodeGraphViewImpl.Editor.NodeGraphView{
CreateBlackboard();
});
visualElement.Add(blackboardButton);
//Add a button to toggle the GraphWatcher
var graphWatcherButton = new Button{
name = "graphWatcherButton",
text = "Graph Watcher"
};
graphWatcherButton.RegisterCallback<ClickEvent>(evt => {
if(_graphWatcher==null)
CreateGraphWatcher();
});
visualElement.Add(graphWatcherButton);
}
private void CreateGraphWatcher(){
_graphWatcher = new GraphWatcherView.GraphWatcherView();
this.AddElement(_graphWatcher);
}
public void RegisterDragEvent(){
RegisterCallback<DragUpdatedEvent>(OnDragUpdated);
RegisterCallback<DragPerformEvent>(OnDragPerform);
@ -440,7 +463,7 @@ namespace TNodeGraphViewImpl.Editor.NodeGraphView{
}
else{
var node = _runtimeGraph.GetRuntimeNode(runtimeNodeData.id).NodeData as SceneNode;
var node = _runtimeNodeGraph.GetRuntimeNode(runtimeNodeData.id).NodeData as SceneNode;
AddPersistentNode(node);
}
}
@ -480,6 +503,10 @@ namespace TNodeGraphViewImpl.Editor.NodeGraphView{
node.Add(res);
}
}
if (IsRuntimeGraph == false){
_runtimeNodeGraph = new StaticGraph(_data);
}
_nodeDict.Clear();
}
@ -656,7 +683,6 @@ namespace TNodeGraphViewImpl.Editor.NodeGraphView{
}
else{
var inputPorts = ports.ToList().Where(x => x.direction == Direction.Input).ToList();
foreach (var inputPort in inputPorts){
//check if start port could implicitly convert to input port type
if (HasImplicitConversion(startPort.portType,inputPort.portType)){
@ -669,11 +695,6 @@ namespace TNodeGraphViewImpl.Editor.NodeGraphView{
}
}
return compatiblePorts;
@ -803,15 +824,15 @@ namespace TNodeGraphViewImpl.Editor.NodeGraphView{
public BlackboardData GetBlackboardData(){
if (IsRuntimeGraph){
return _runtimeGraph.runtimeBlackboardData;
return _runtimeNodeGraph.GetBlackboardData();
}
return _data.blackboardData;
}
public bool IsRuntimeGraph{ get; set; }
public RuntimeGraph GetRuntimeGraph(){
return _runtimeGraph;
public IRuntimeNodeGraph GetRuntimeNodeGraph(){
return _runtimeNodeGraph;
}
public void SetGraphData(GraphData graph){

@ -32,12 +32,6 @@ namespace TNodeGraphViewImpl.Editor.NodeGraphView{
ConstructWindowBasicSetting();
BuildWindow(visualTreeAsset);
}
public string GetPersistenceId(){
throw new System.NotImplementedException();
}
}

@ -0,0 +1,21 @@
<ui:UXML xmlns:ui="UnityEngine.UIElements"
xmlns:uie="UnityEditor.UIElements"
xsi="http://www.w3.org/2001/XMLSchema-instance"
engine="UnityEngine.UIElements"
editor="UnityEditor.UIElements"
noNamespaceSchemaLocation="../../../../UIElementsSchema/UIElements.xsd" editor-extension-mode="True">
<ui:VisualElement name="GraphWatcher" style="height: 300px; width: 300px; background-color: rgb(65, 65, 65);">
<ui:VisualElement name="GraphOptions" >
<ui:Button name="Next" text="Next">
</ui:Button>
<ui:Button name="Reset" text="Reset">
</ui:Button>
</ui:VisualElement>
<ui:Label name="CurrentNode">
</ui:Label>
</ui:VisualElement>
</ui:UXML>

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 208b885f8b1f43b790dd400dd9ee32bb
timeCreated: 1660972278

@ -0,0 +1,3 @@
#GraphOptions{
flex-direction: row;
}

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 26717cfb931940c9ae019876e9ba1293
timeCreated: 1660980852

@ -0,0 +1,4 @@
.highlightNode{
border-color: lightseagreen;
border-width: 2;
}

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 289aee0d98d04cf5851bf92411e326e1
timeCreated: 1660975039

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 61d88b1f3fc14972aa28c22a5afaa53e
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

@ -0,0 +1,59 @@
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using TNodeCore.Editor.Tools.NodeCreator;
using TNodeCore.Runtime;
using TNodeCore.Runtime.Attributes;
using TNodeCore.Runtime.Attributes.Ports;
using TNodeCore.Runtime.Models;
using TNodeGraphViewImpl.Editor.NodeGraphView;
using UnityEngine;
using UnityEngine.TestTools;
namespace Tests{
public class NodePortTest
{
internal class GraphDataForTest:GraphData{
}
[GraphUsage(typeof(GraphDataForTest))]
internal class PortNameNodeData:NodeData{
[Input(Group = true)]
public List<string> Inputs{
get => _inputs;
set => _inputs = value;
}
private List<string> _inputs = new List<string>{"Input1", "Input2"};
}
[Test]
public void TestWithPortName(){
var graphView = new BaseDataGraphView<GraphData>();
var node = NodeCreator.InstantiateNodeData<PortNameNodeData>();
graphView.AddTNode(node,new Rect());
Assert.AreEqual(graphView.nodes.ToList().Count, 1);
Assert.AreEqual(graphView.ports.ToList().Count, 2);
Debug.Log(graphView.ports.ToList().Aggregate("",(total,port)=> total + port.name));
}
[Test]
public void TestWithRuntimeNodeAccessPort(){
var node = NodeCreator.InstantiateNodeData<PortNameNodeData>();
RuntimeNode runtimeNode = new RuntimeNode(node);
runtimeNode.SetInput("Inputs:0", "Hello");
Assert.AreEqual("Hello",node.Inputs[0]);
}
// A UnityTest behaves like a coroutine in Play Mode. In Edit Mode you can use
// `yield return null;` to skip a frame.
[UnityTest]
public IEnumerator NodeViewTestWithEnumeratorPasses()
{
// Use the Assert class to test conditions.
// Use yield to skip a frame.
yield return null;
}
}
}

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6acca7b72bb21204d8eaa67ccd45bf4a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

@ -38,7 +38,7 @@ namespace Tests{
graphData.NodeDictionary.Add(node.id,node);
Assert.AreEqual(1,graphData.NodeDictionary.Count);
var staticGraph = new StaticGraph(graphData.NodeDictionary.Values.ToList(),graphData.NodeLinks);
var staticGraph = new StaticGraph(graphData);
Assert.NotNull(staticGraph);
Assert.AreEqual(1,staticGraph.GetRuntimeNodes().Count);
}
@ -50,7 +50,7 @@ namespace Tests{
graphData.NodeDictionary.Add(node.id,node);
var staticGraph = new StaticGraph(graphData.NodeDictionary.Values.ToList(),graphData.NodeLinks);
var staticGraph = new StaticGraph(graphData);
Assert.AreEqual(staticGraph.GetRuntimeNodes().First(),staticGraph.CurrentRuntimeNode());
@ -97,7 +97,7 @@ namespace Tests{
var staticGraph = new StaticGraph(graphData.NodeDictionary.Values.ToList(),graphData.NodeLinks);
var staticGraph = new StaticGraph(graphData);
Assert.AreEqual(node1,staticGraph.CurrentNode());
staticGraph.MoveNext();
@ -157,7 +157,7 @@ namespace Tests{
node3.TestCondition = true;
var staticGraph = new StaticGraph(graphData.NodeDictionary.Values.ToList(),graphData.NodeLinks);
var staticGraph = new StaticGraph(graphData);
Assert.AreEqual(node1,staticGraph.CurrentNode());
staticGraph.MoveNext();
Assert.AreEqual(node4,staticGraph.CurrentNode());
@ -172,7 +172,7 @@ namespace Tests{
node3.TestCondition = false;
var staticGraph2 = new StaticGraph(graphData.NodeDictionary.Values.ToList(),graphData.NodeLinks);
var staticGraph2 = new StaticGraph(graphData);
Assert.AreEqual(node1,staticGraph2.CurrentNode());
staticGraph2.MoveNext();
Assert.AreEqual(node4,staticGraph2.CurrentNode());

@ -0,0 +1,26 @@
{
"name": "Tests",
"rootNamespace": "",
"references": [
"UnityEngine.TestRunner",
"UnityEditor.TestRunner",
"TNodeGraphViewImpl",
"Taoria.TNodeCore.Runtime",
"Taoria.TNodeCore.Editor"
],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": true,
"precompiledReferences": [
"nunit.framework.dll"
],
"autoReferenced": false,
"defineConstraints": [
"UNITY_INCLUDE_TESTS"
],
"versionDefines": [],
"noEngineReferences": false
}

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 8a8ac2349fdacb047b9081e8a9e533f9
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
Loading…
Cancel
Save