|
|
@ -2,6 +2,7 @@ |
|
|
|
using System.Collections.Generic; |
|
|
|
using System.Collections.Generic; |
|
|
|
using System.Linq; |
|
|
|
using System.Linq; |
|
|
|
using System.Reflection; |
|
|
|
using System.Reflection; |
|
|
|
|
|
|
|
using System.Threading.Tasks; |
|
|
|
using TNode.TNodeGraphViewImpl.Editor.Cache; |
|
|
|
using TNode.TNodeGraphViewImpl.Editor.Cache; |
|
|
|
using TNode.TNodeGraphViewImpl.Editor.GraphBlackboard; |
|
|
|
using TNode.TNodeGraphViewImpl.Editor.GraphBlackboard; |
|
|
|
using TNode.TNodeGraphViewImpl.Editor.Inspector; |
|
|
|
using TNode.TNodeGraphViewImpl.Editor.Inspector; |
|
|
@ -16,6 +17,7 @@ using TNodeCore.Editor.Tools.NodeCreator; |
|
|
|
using TNodeCore.Runtime.Components; |
|
|
|
using TNodeCore.Runtime.Components; |
|
|
|
using TNodeCore.Runtime.Models; |
|
|
|
using TNodeCore.Runtime.Models; |
|
|
|
using TNodeCore.Runtime.RuntimeCache; |
|
|
|
using TNodeCore.Runtime.RuntimeCache; |
|
|
|
|
|
|
|
using Unity.VisualScripting; |
|
|
|
using UnityEditor; |
|
|
|
using UnityEditor; |
|
|
|
using UnityEditor.Experimental.GraphView; |
|
|
|
using UnityEditor.Experimental.GraphView; |
|
|
|
using UnityEngine; |
|
|
|
using UnityEngine; |
|
|
@ -25,16 +27,18 @@ using Edge = UnityEditor.Experimental.GraphView.Edge; |
|
|
|
|
|
|
|
|
|
|
|
namespace TNode.TNodeGraphViewImpl.Editor.NodeGraphView{ |
|
|
|
namespace TNode.TNodeGraphViewImpl.Editor.NodeGraphView{ |
|
|
|
public class BaseDataGraphView<T>:GraphView,IDataGraphView<T> where T:GraphData{ |
|
|
|
public class BaseDataGraphView<T>:GraphView,IDataGraphView<T> where T:GraphData{ |
|
|
|
|
|
|
|
#region const |
|
|
|
|
|
|
|
public const float RefreshRate = 1f; |
|
|
|
|
|
|
|
#endregion |
|
|
|
#region variables and properties |
|
|
|
#region variables and properties |
|
|
|
private T _data; |
|
|
|
private T _data; |
|
|
|
private RuntimeGraph _runtimeGraph; |
|
|
|
private RuntimeGraph _runtimeGraph; |
|
|
|
|
|
|
|
|
|
|
|
private bool _isInspectorOn; |
|
|
|
private bool _isInspectorOn; |
|
|
|
private NodeSearchWindowProvider _nodeSearchWindowProvider; |
|
|
|
private NodeSearchWindowProvider _nodeSearchWindowProvider; |
|
|
|
private NodeInspector _nodeInspector; |
|
|
|
private NodeInspector _nodeInspector; |
|
|
|
private Dictionary<string,Node> _nodeDict = new(); |
|
|
|
private Dictionary<string,Node> _nodeDict = new(); |
|
|
|
private IBlackboardView _blackboard; |
|
|
|
private IBlackboardView _blackboard; |
|
|
|
private bool _runtimeGraphUpdate; |
|
|
|
private bool _loaded; |
|
|
|
public T Data{ |
|
|
|
public T Data{ |
|
|
|
get{ return _data; } |
|
|
|
get{ return _data; } |
|
|
|
set{ |
|
|
|
set{ |
|
|
@ -98,15 +102,14 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeGraphView{ |
|
|
|
var res = DragAndDrop.objectReferences; |
|
|
|
var res = DragAndDrop.objectReferences; |
|
|
|
foreach (var obj in res){ |
|
|
|
foreach (var obj in res){ |
|
|
|
if (obj is T graphData){ |
|
|
|
if (obj is T graphData){ |
|
|
|
Data = graphData; |
|
|
|
|
|
|
|
IsRuntimeGraph = false; |
|
|
|
IsRuntimeGraph = false; |
|
|
|
|
|
|
|
Data = graphData; |
|
|
|
} |
|
|
|
} |
|
|
|
else{ |
|
|
|
else{ |
|
|
|
if (obj is GameObject gameObject){ |
|
|
|
if (obj is GameObject gameObject){ |
|
|
|
|
|
|
|
|
|
|
|
if (gameObject.GetComponent<RuntimeGraph>() != null){ |
|
|
|
if (gameObject.GetComponent<RuntimeGraph>() != null){ |
|
|
|
if (gameObject.GetComponent<RuntimeGraph>().graphData != null){ |
|
|
|
if (gameObject.GetComponent<RuntimeGraph>().graphData != null){ |
|
|
|
|
|
|
|
|
|
|
|
_runtimeGraph = gameObject.GetComponent<RuntimeGraph>(); |
|
|
|
_runtimeGraph = gameObject.GetComponent<RuntimeGraph>(); |
|
|
|
IsRuntimeGraph = true; |
|
|
|
IsRuntimeGraph = true; |
|
|
|
BuildRuntimeGraphBehaviour(); |
|
|
|
BuildRuntimeGraphBehaviour(); |
|
|
@ -114,7 +117,6 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeGraphView{ |
|
|
|
if(Data==null){ |
|
|
|
if(Data==null){ |
|
|
|
Debug.LogError($"Dragged a wrong graph data to editor,expected {typeof(T)} but got {gameObject.GetComponent<RuntimeGraph>().graphData.GetType()}"); |
|
|
|
Debug.LogError($"Dragged a wrong graph data to editor,expected {typeof(T)} but got {gameObject.GetComponent<RuntimeGraph>().graphData.GetType()}"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -147,25 +149,36 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeGraphView{ |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private void BuildRuntimeGraphBehaviour(){ |
|
|
|
private void BuildRuntimeGraphBehaviour(){ |
|
|
|
EditorApplication.update+= UpdateRuntimeGraphBehaviour; |
|
|
|
//EditorApplication.update+= UpdateRuntimeGraphBehaviour; |
|
|
|
|
|
|
|
UpdateRuntimeGraphBehaviourInTime(); |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private void UpdateRuntimeGraphBehaviour(){ |
|
|
|
private async void UpdateRuntimeGraphBehaviourInTime(){ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
while (_loaded){ |
|
|
|
|
|
|
|
await Task.Delay(TimeSpan.FromSeconds(RefreshRate)); |
|
|
|
if(_runtimeGraph != null){ |
|
|
|
if(_runtimeGraph != null){ |
|
|
|
if (_runtimeGraphUpdate){ |
|
|
|
if (AutoUpdate){ |
|
|
|
_runtimeGraphUpdate = false; |
|
|
|
|
|
|
|
_runtimeGraph.ResolveDependency(); |
|
|
|
_runtimeGraph.ResolveDependency(); |
|
|
|
|
|
|
|
AfterGraphResolved?.Invoke(); |
|
|
|
AfterRuntimeGraphUpdate?.Invoke(); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
else{ |
|
|
|
|
|
|
|
EditorApplication.update -= UpdateRuntimeGraphBehaviour; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// private void UpdateRuntimeGraphBehaviour(){ |
|
|
|
|
|
|
|
// if(_runtimeGraph != null){ |
|
|
|
|
|
|
|
// if (_runtimeGraphUpdate){ |
|
|
|
|
|
|
|
// _runtimeGraphUpdate = false; |
|
|
|
|
|
|
|
// _runtimeGraph.ResolveDependency(); |
|
|
|
|
|
|
|
// |
|
|
|
|
|
|
|
// AfterGraphResolved?.Invoke(); |
|
|
|
|
|
|
|
// } |
|
|
|
|
|
|
|
// } |
|
|
|
|
|
|
|
// else{ |
|
|
|
|
|
|
|
// EditorApplication.update -= UpdateRuntimeGraphBehaviour; |
|
|
|
|
|
|
|
// } |
|
|
|
|
|
|
|
// } |
|
|
|
|
|
|
|
|
|
|
|
private void CheckDataAfterInit(){ |
|
|
|
private void CheckDataAfterInit(){ |
|
|
|
if(Data == null){ |
|
|
|
if(Data == null){ |
|
|
@ -201,6 +214,18 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeGraphView{ |
|
|
|
OnGraphViewCreate(); |
|
|
|
OnGraphViewCreate(); |
|
|
|
|
|
|
|
|
|
|
|
BuildUndo(); |
|
|
|
BuildUndo(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_loaded = true; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SetDetachedFromPanel(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void SetDetachedFromPanel(){ |
|
|
|
|
|
|
|
this.RegisterCallback<DetachFromPanelEvent>(evt => { |
|
|
|
|
|
|
|
_loaded = false; |
|
|
|
|
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private void BuildUndo(){ |
|
|
|
private void BuildUndo(){ |
|
|
@ -227,22 +252,32 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeGraphView{ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//Add a toggle button to toggle test mode |
|
|
|
//Add a toggle button to toggle test mode |
|
|
|
var testModeToggle = new Toggle{ |
|
|
|
var autoUpdateToggle = new Toggle{ |
|
|
|
name = "TestModeToggle", |
|
|
|
name = "TestModeToggle", |
|
|
|
label = "Test Mode", |
|
|
|
label = "Test Mode", |
|
|
|
value = false |
|
|
|
value = AutoUpdate |
|
|
|
}; |
|
|
|
}; |
|
|
|
testModeToggle.RegisterValueChangedCallback(evt => { |
|
|
|
autoUpdateToggle.RegisterValueChangedCallback(evt => { |
|
|
|
if (evt.newValue){ |
|
|
|
if (evt.newValue){ |
|
|
|
TestMode = true; |
|
|
|
AutoUpdate = true; |
|
|
|
} |
|
|
|
} |
|
|
|
else{ |
|
|
|
else{ |
|
|
|
TestMode = false; |
|
|
|
AutoUpdate = false; |
|
|
|
} |
|
|
|
} |
|
|
|
}); |
|
|
|
}); |
|
|
|
visualElement.Add(testModeToggle); |
|
|
|
visualElement.Add(autoUpdateToggle); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var runButton = new Button{ |
|
|
|
|
|
|
|
name = "RunButton", |
|
|
|
|
|
|
|
text = "Run Once" |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
runButton.RegisterCallback<ClickEvent>(evt => { |
|
|
|
|
|
|
|
if (IsRuntimeGraph){ |
|
|
|
|
|
|
|
_runtimeGraph.ResolveDependency(); |
|
|
|
|
|
|
|
AfterGraphResolved?.Invoke(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
visualElement.Add(runButton); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public void RegisterDragEvent(){ |
|
|
|
public void RegisterDragEvent(){ |
|
|
@ -341,8 +376,7 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeGraphView{ |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private void AddPersistentNode(NodeData dataNode){ |
|
|
|
private void AddPersistentNode(NodeData dataNode){ |
|
|
|
var nodePos = Owner.graphEditorData.graphElementsData.FirstOrDefault(x => x.guid == dataNode.id)?.pos ?? |
|
|
|
var nodePos = dataNode.positionInView; |
|
|
|
new Rect(0, 0, 200, 200); |
|
|
|
|
|
|
|
AddTNode(dataNode, nodePos); |
|
|
|
AddTNode(dataNode, nodePos); |
|
|
|
} |
|
|
|
} |
|
|
|
//OnDataChanged event |
|
|
|
//OnDataChanged event |
|
|
@ -391,21 +425,21 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeGraphView{ |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public void SaveEditorData(GraphEditorData graphEditorData){ |
|
|
|
public void SaveEditorData(GraphEditorData graphEditorData){ |
|
|
|
graphEditorData.graphElementsData?.Clear(); |
|
|
|
// graphEditorData.graphElementsData?.Clear(); |
|
|
|
//iterator nodes |
|
|
|
// //iterator nodes |
|
|
|
if (graphEditorData.graphElementsData == null){ |
|
|
|
// if (graphEditorData.graphElementsData == null){ |
|
|
|
graphEditorData.graphElementsData = new List<GraphElementEditorData>(); |
|
|
|
// graphEditorData.graphElementsData = new List<GraphElementEditorData>(); |
|
|
|
} |
|
|
|
// } |
|
|
|
foreach (var node in this.nodes){ |
|
|
|
// foreach (var node in this.nodes){ |
|
|
|
var nodeEditorData = new GraphElementEditorData{ |
|
|
|
// var nodeEditorData = new GraphElementEditorData{ |
|
|
|
pos = node.GetPosition(), |
|
|
|
// pos = node.GetPosition(), |
|
|
|
}; |
|
|
|
// }; |
|
|
|
if (node is IBaseNodeView nodeView){ |
|
|
|
// if (node is IBaseNodeView nodeView){ |
|
|
|
nodeEditorData.guid = nodeView.GetNodeData().id; |
|
|
|
// nodeEditorData.guid = nodeView.GetNodeData().id; |
|
|
|
} |
|
|
|
// } |
|
|
|
graphEditorData.graphElementsData.Add(nodeEditorData); |
|
|
|
// graphEditorData.graphElementsData.Add(nodeEditorData); |
|
|
|
EditorUtility.SetDirty(graphEditorData); |
|
|
|
// EditorUtility.SetDirty(graphEditorData); |
|
|
|
} |
|
|
|
// } |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public void SaveWithEditorData(GraphEditorData graphEditorData){ |
|
|
|
public void SaveWithEditorData(GraphEditorData graphEditorData){ |
|
|
@ -499,8 +533,15 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeGraphView{ |
|
|
|
#region implement interfaces |
|
|
|
#region implement interfaces |
|
|
|
public void AddTNode(NodeData nodeData, Rect rect){ |
|
|
|
public void AddTNode(NodeData nodeData, Rect rect){ |
|
|
|
if (NodeEditorExtensions.CreateNodeViewFromNodeType(nodeData.GetType()) is Node nodeView){ |
|
|
|
if (NodeEditorExtensions.CreateNodeViewFromNodeType(nodeData.GetType()) is Node nodeView){ |
|
|
|
nodeView.SetPosition(rect); |
|
|
|
//convert rect at graph space |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var resPos = this.viewTransform.matrix.inverse.MultiplyPoint3x4(rect.position); |
|
|
|
|
|
|
|
rect.position = resPos; |
|
|
|
|
|
|
|
if(nodeView is IBaseNodeView nodeViewInterface){ |
|
|
|
|
|
|
|
nodeViewInterface.SetNodeData(nodeData); |
|
|
|
|
|
|
|
} |
|
|
|
AddElement(nodeView); |
|
|
|
AddElement(nodeView); |
|
|
|
|
|
|
|
((IBaseNodeView)nodeView).InitializePosition(rect); |
|
|
|
//Add a select callback to the nodeView |
|
|
|
//Add a select callback to the nodeView |
|
|
|
nodeView.RegisterCallback<MouseDownEvent>(evt => { |
|
|
|
nodeView.RegisterCallback<MouseDownEvent>(evt => { |
|
|
|
if (evt.clickCount == 1){ |
|
|
|
if (evt.clickCount == 1){ |
|
|
@ -510,14 +551,17 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeGraphView{ |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
}); |
|
|
|
}); |
|
|
|
if(nodeView is IBaseNodeView nodeViewInterface){ |
|
|
|
|
|
|
|
nodeViewInterface.SetNodeData(nodeData); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if(_nodeDict.ContainsKey(nodeData.id)==false) |
|
|
|
_nodeDict.Add(nodeData.id, nodeView); |
|
|
|
_nodeDict.Add(nodeData.id, nodeView); |
|
|
|
if (_data.NodeDictionary.ContainsKey(nodeData.id) == false){ |
|
|
|
if (_data.NodeDictionary.ContainsKey(nodeData.id) == false){ |
|
|
|
Undo.RegisterCompleteObjectUndo(_data,"Node Creation"); |
|
|
|
Undo.RegisterCompleteObjectUndo(_data,"Node Creation"); |
|
|
|
_data.NodeDictionary.Add(nodeData.id,nodeData); |
|
|
|
_data.NodeDictionary.Add(nodeData.id,nodeData); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//register an callback ,when right click context menu |
|
|
|
//register an callback ,when right click context menu |
|
|
|
nodeView.RegisterCallback<ContextClickEvent>(evt => { |
|
|
|
nodeView.RegisterCallback<ContextClickEvent>(evt => { |
|
|
|
var menu = new GenericMenu(); |
|
|
|
var menu = new GenericMenu(); |
|
|
@ -529,6 +573,8 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeGraphView{ |
|
|
|
}); |
|
|
|
}); |
|
|
|
menu.ShowAsContext(); |
|
|
|
menu.ShowAsContext(); |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -557,12 +603,21 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeGraphView{ |
|
|
|
_data.NodeLinks.Remove(nodeLink); |
|
|
|
_data.NodeLinks.Remove(nodeLink); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public bool TestMode{ get; set; } |
|
|
|
public bool AutoUpdate{ |
|
|
|
|
|
|
|
get=>Owner.graphEditorData.autoUpdate; set=>Owner.graphEditorData.autoUpdate = value; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public override EventPropagation DeleteSelection(){ |
|
|
|
|
|
|
|
Undo.RegisterCompleteObjectUndo(_data,"Delete Selection"); |
|
|
|
|
|
|
|
var res = base.DeleteSelection(); |
|
|
|
|
|
|
|
SaveGraphData(); |
|
|
|
|
|
|
|
ResetGraphView(); |
|
|
|
|
|
|
|
return res; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public void CreateBlackboard(){ |
|
|
|
public void CreateBlackboard(){ |
|
|
|
_blackboard = NodeEditorExtensions.CreateBlackboardWithGraphData(typeof(T)); |
|
|
|
_blackboard = NodeEditorExtensions.CreateBlackboardWithGraphData(typeof(T)); |
|
|
|
_blackboard.Setup(this,Owner); |
|
|
|
_blackboard.Setup(this,Owner); |
|
|
|
Debug.Log(Owner); |
|
|
|
|
|
|
|
var castedBlackboard = _blackboard as Blackboard; |
|
|
|
var castedBlackboard = _blackboard as Blackboard; |
|
|
|
Add(castedBlackboard); |
|
|
|
Add(castedBlackboard); |
|
|
|
Rect blackboardPos = new Rect(0,0,300,700); |
|
|
|
Rect blackboardPos = new Rect(0,0,300,700); |
|
|
@ -594,11 +649,9 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeGraphView{ |
|
|
|
|
|
|
|
|
|
|
|
public void NotifyRuntimeUpdate(){ |
|
|
|
public void NotifyRuntimeUpdate(){ |
|
|
|
|
|
|
|
|
|
|
|
_runtimeGraphUpdate = true; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public Action AfterGraphResolved{ get; set; } |
|
|
|
public Action AfterRuntimeGraphUpdate{ get; set; } |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#endregion |
|
|
|
#endregion |
|
|
|
} |
|
|
|
} |
|
|
|