feature:run once button and a node logger

main
taoria 3 years ago
parent 8d6792ae58
commit fc2395fdf1
  1. 2
      TNode/TNodeCore/Editor/EditorPersistence/GraphEditorData.cs
  2. 9
      TNode/TNodeCore/Editor/NodeGraphView/IBaseDataGraphView.cs
  3. 6
      TNode/TNodeCore/Runtime/Attributes/HideInBlackboard.cs
  4. 3
      TNode/TNodeCore/Runtime/Attributes/HideInBlackboard.cs.meta
  5. 5
      TNode/TNodeCore/Runtime/Attributes/ModelColor.cs
  6. 3
      TNode/TNodeCore/Runtime/Attributes/ModelColor.cs.meta
  7. 3
      TNode/TNodeCore/Runtime/Attributes/Ports/InputAttribute.cs
  8. 8
      TNode/TNodeCore/Runtime/Attributes/Ports/OutputAttribute.cs
  9. 8
      TNode/TNodeCore/Runtime/Attributes/Ports/PortAttribute.cs
  10. 2
      TNode/TNodeCore/Runtime/Models/Model.cs
  11. 21
      TNode/TNodeCore/Runtime/NodeLogger.cs
  12. 3
      TNode/TNodeCore/Runtime/NodeLogger.cs.meta
  13. 4
      TNode/TNodeGraphViewImpl/Editor/GraphBlackboard/DefaultGraphBlackboardView.cs
  14. 2
      TNode/TNodeGraphViewImpl/Editor/Inspector/NodeInspectorInNode.cs
  15. 91
      TNode/TNodeGraphViewImpl/Editor/NodeGraphView/DataGraphView.cs
  16. 39
      TNode/TNodeGraphViewImpl/Editor/NodeViews/NodeView.cs

@ -3,6 +3,7 @@ using System.Collections.Generic;
using TNodeCore.Editor.NodeGraphView; using TNodeCore.Editor.NodeGraphView;
using TNodeCore.Runtime.Models; using TNodeCore.Runtime.Models;
using UnityEngine; using UnityEngine;
using UnityEngine.Serialization;
namespace TNodeCore.Editor.EditorPersistence{ namespace TNodeCore.Editor.EditorPersistence{
@ -14,6 +15,7 @@ namespace TNodeCore.Editor.EditorPersistence{
public GraphImplType graphImplType = GraphImplType.GraphViewImpl; public GraphImplType graphImplType = GraphImplType.GraphViewImpl;
public static Func<Type,IBaseDataGraphView> GraphViewImplCreator; public static Func<Type,IBaseDataGraphView> GraphViewImplCreator;
public static Func<Type,IBaseDataGraphView> GtfImplCreator; public static Func<Type,IBaseDataGraphView> GtfImplCreator;
[FormerlySerializedAs("testMode")] public bool autoUpdate;
public IDataGraphView<T> GetGraphView<T> () where T:GraphData{ public IDataGraphView<T> GetGraphView<T> () where T:GraphData{
switch (graphImplType){ switch (graphImplType){

@ -14,7 +14,7 @@ namespace TNodeCore.Editor.NodeGraphView{
public void RemoveLink(NodeLink nodeLink); public void RemoveLink(NodeLink nodeLink);
public bool TestMode{ get; set; } public bool AutoUpdate{ get; set; }
public void CreateBlackboard(); public void CreateBlackboard();
public GraphData GetGraphData(); public GraphData GetGraphData();
public BlackboardData GetBlackboardData(); public BlackboardData GetBlackboardData();
@ -30,9 +30,12 @@ namespace TNodeCore.Editor.NodeGraphView{
public void SetGraphData(GraphData graph); public void SetGraphData(GraphData graph);
void NotifyRuntimeUpdate();
public Action AfterRuntimeGraphUpdate{ get; set; } public Action AfterGraphResolved{ get; set; }
void AfterEditorLoadGraphView(); void AfterEditorLoadGraphView();
//todo remove it later ,keep it now
void NotifyRuntimeUpdate();
} }
} }

@ -0,0 +1,6 @@
namespace TNodeCore.Runtime.Attributes{
public class HideInBlackboard:System.Attribute{
}
}

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 731893f9f7824b939cee169d61092ad3
timeCreated: 1659517588

@ -0,0 +1,5 @@
namespace TNodeCore.Runtime.Attributes{
public class ModelColor{
}
}

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: cdec5767969f4e11bbcfb245693796f9
timeCreated: 1659521617

@ -1,5 +1,6 @@
using System; using System;
using JetBrains.Annotations; using JetBrains.Annotations;
using UnityEngine;
namespace TNodeCore.Runtime.Attributes.Ports{ namespace TNodeCore.Runtime.Attributes.Ports{
[MeansImplicitUse] [MeansImplicitUse]
@ -7,5 +8,7 @@ namespace TNodeCore.Runtime.Attributes.Ports{
public class InputAttribute : PortAttribute{ public class InputAttribute : PortAttribute{
public InputAttribute(string name="", PortNameHandling nameHandling = PortNameHandling.Auto,TypeHandling typeHandling=TypeHandling.Declared) : base(name, nameHandling,typeHandling){ public InputAttribute(string name="", PortNameHandling nameHandling = PortNameHandling.Auto,TypeHandling typeHandling=TypeHandling.Declared) : base(name, nameHandling,typeHandling){
} }
public InputAttribute(Color color):base(color){
}
} }
} }

@ -1,8 +1,14 @@
namespace TNodeCore.Runtime.Attributes.Ports{ using UnityEngine;
namespace TNodeCore.Runtime.Attributes.Ports{
public class OutputAttribute:PortAttribute{ public class OutputAttribute:PortAttribute{
public OutputAttribute(string name="", PortNameHandling nameHandling = PortNameHandling.Auto,TypeHandling typeHandling = TypeHandling.Declared) : base(name, nameHandling,typeHandling){ public OutputAttribute(string name="", PortNameHandling nameHandling = PortNameHandling.Auto,TypeHandling typeHandling = TypeHandling.Declared) : base(name, nameHandling,typeHandling){
} }
public OutputAttribute(Color color):base(color){
}
} }
} }

@ -1,6 +1,8 @@
using System; using System;
using UnityEngine;
using JetBrains.Annotations; using JetBrains.Annotations;
namespace TNodeCore.Runtime.Attributes.Ports{ namespace TNodeCore.Runtime.Attributes.Ports{
public enum PortNameHandling{ public enum PortNameHandling{
@ -23,6 +25,7 @@ namespace TNodeCore.Runtime.Attributes.Ports{
public readonly PortNameHandling NameHandling; public readonly PortNameHandling NameHandling;
public Type HandledType; public Type HandledType;
public bool Multiple = true; public bool Multiple = true;
public Color PortColor = Color.black;
public TypeHandling TypeHandling{ get; set; } public TypeHandling TypeHandling{ get; set; }
public PortAttribute(string name,PortNameHandling nameHandling=PortNameHandling.Auto,TypeHandling typeHandling=TypeHandling.Declared){ public PortAttribute(string name,PortNameHandling nameHandling=PortNameHandling.Auto,TypeHandling typeHandling=TypeHandling.Declared){
this.Name = name; this.Name = name;
@ -30,6 +33,11 @@ namespace TNodeCore.Runtime.Attributes.Ports{
this.TypeHandling = typeHandling; this.TypeHandling = typeHandling;
} }
public PortAttribute(Color color):this("",PortNameHandling.Auto,TypeHandling.Declared){
PortColor = color;
}
} }
} }

@ -1,4 +1,5 @@
using System; using System;
using TNodeCore.Runtime.Attributes;
using UnityEngine; using UnityEngine;
using UnityEngine.Serialization; using UnityEngine.Serialization;
@ -6,6 +7,7 @@ namespace TNodeCore.Runtime.Models{
[Serializable] [Serializable]
public abstract class Model:ICloneable{ public abstract class Model:ICloneable{
#if UNITY_EDITOR #if UNITY_EDITOR
[HideInBlackboard]
public Rect positionInView; public Rect positionInView;
#endif #endif

@ -0,0 +1,21 @@
using System.Collections.Generic;
using TNodeCore.Runtime.Models;
using UnityEngine;
namespace TNodeCore.Runtime{
public static class NodeLogger{
public static Dictionary<string, INodeLoggerImpl> Loggers = new ();
public static void Log(this NodeData t,string message){
if (!Loggers.ContainsKey(t.id)) return;
var nodeLoggerImpl = Loggers[t.id];
nodeLoggerImpl.Log(message);
Debug.Log(message);
}
}
public interface INodeLoggerImpl{
public void Log(string message);
}
}

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 48be07a2cf064167b15d378ac41757c4
timeCreated: 1659592209

@ -6,6 +6,7 @@ using TNodeCore.Editor.NodeGraphView;
using TNodeCore.Editor.Serialization; using TNodeCore.Editor.Serialization;
using TNodeCore.Runtime.Attributes; using TNodeCore.Runtime.Attributes;
using TNodeCore.Runtime.Models; using TNodeCore.Runtime.Models;
using Unity.VisualScripting;
using UnityEditor; using UnityEditor;
using UnityEditor.Experimental.GraphView; using UnityEditor.Experimental.GraphView;
using UnityEditor.UIElements; using UnityEditor.UIElements;
@ -22,8 +23,8 @@ namespace TNode.TNodeGraphViewImpl.Editor.GraphBlackboard{
} }
protected override void UpdateBlackboard(BlackboardData data){ protected override void UpdateBlackboard(BlackboardData data){
Clear();
if (data == null) return; if (data == null) return;
this.Clear();
var serializedObject = new SerializedObject((BlackboardDataWrapper)data); var serializedObject = new SerializedObject((BlackboardDataWrapper)data);
var currentGraphView = graphView as IBaseDataGraphView; var currentGraphView = graphView as IBaseDataGraphView;
var isRuntimeGraph = currentGraphView?.IsRuntimeGraph ?? false; var isRuntimeGraph = currentGraphView?.IsRuntimeGraph ?? false;
@ -33,6 +34,7 @@ namespace TNode.TNodeGraphViewImpl.Editor.GraphBlackboard{
Add(blackboardGlobalSection); Add(blackboardGlobalSection);
foreach (var field in data.GetType() foreach (var field in data.GetType()
.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)){ .GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)){
if(field.HasAttribute(typeof(HideInBlackboard))) continue;
//if the field is MonoBehaviour,add a property field for blackboard //if the field is MonoBehaviour,add a property field for blackboard
//skip if the field is a list or Ilist //skip if the field is a list or Ilist
if (!typeof(IList).IsAssignableFrom(field.FieldType)&&!field.FieldType.IsArray){ if (!typeof(IList).IsAssignableFrom(field.FieldType)&&!field.FieldType.IsArray){

@ -67,7 +67,7 @@ namespace TNode.TNodeGraphViewImpl.Editor.Inspector{
Add(drawer); Add(drawer);
} }
var globalTest = GetFirstAncestorOfType<IBaseDataGraphView>()?.TestMode; var globalTest = GetFirstAncestorOfType<IBaseDataGraphView>()?.AutoUpdate;
if(globalTest??false){ if(globalTest??false){
CreateTestButton(); CreateTestButton();
} }

@ -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{
@ -145,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(){
if(_runtimeGraph != null){
if (_runtimeGraphUpdate){
_runtimeGraphUpdate = false;
_runtimeGraph.ResolveDependency();
AfterRuntimeGraphUpdate?.Invoke(); while (_loaded){
await Task.Delay(TimeSpan.FromSeconds(RefreshRate));
if(_runtimeGraph != null){
if (AutoUpdate){
_runtimeGraph.ResolveDependency();
AfterGraphResolved?.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){
@ -199,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(){
@ -225,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(){
@ -536,6 +573,8 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeGraphView{
}); });
menu.ShowAsContext(); menu.ShowAsContext();
}); });
} }
} }
@ -564,11 +603,14 @@ 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(){ public override EventPropagation DeleteSelection(){
Undo.RegisterCompleteObjectUndo(_data,"Delete Selection"); Undo.RegisterCompleteObjectUndo(_data,"Delete Selection");
var res = base.DeleteSelection(); var res = base.DeleteSelection();
SaveGraphData();
ResetGraphView(); ResetGraphView();
return res; return res;
} }
@ -576,7 +618,6 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeGraphView{
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);
@ -608,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
} }

@ -18,6 +18,27 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeViews{
public abstract class BaseNodeView<T> : Node,INodeView<T> where T:NodeData,new(){ public abstract class BaseNodeView<T> : Node,INodeView<T> where T:NodeData,new(){
protected T _data; protected T _data;
private readonly NodeInspectorInNode _nodeInspectorInNode; private readonly NodeInspectorInNode _nodeInspectorInNode;
private NodeViewLogger _viewLogger;
private class NodeViewLogger:INodeLoggerImpl{
public BaseNodeView<T> NodeView { get; set; }
public void Log(string message){
var loggerAreaParent = NodeView.extensionContainer;
if (loggerAreaParent == null){
return;
}
var loggerArea = loggerAreaParent.Q<TextField>("loggerArea");
if(loggerArea == null){
loggerArea = new TextField();
loggerArea.name = "loggerArea";
loggerArea.AddToClassList("loggerArea");
loggerAreaParent.Add(loggerArea);
}
loggerArea.multiline = true;
loggerArea.value = message;
}
}
public IBaseDataGraphView BaseDataGraphView{ public IBaseDataGraphView BaseDataGraphView{
get{ get{
@ -31,18 +52,22 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeViews{
if(_data!=null) if(_data!=null)
((NodeDataWrapper)_data).OnValueChanged -= OnDataValueChanged; ((NodeDataWrapper)_data).OnValueChanged -= OnDataValueChanged;
_data = value; _data = value;
OnDataChanged?.Invoke(value); OnDataChanged?.Invoke(value);
if(_data!=null) if(_data!=null)
((NodeDataWrapper)_data).OnValueChanged += OnDataValueChanged; ((NodeDataWrapper)_data).OnValueChanged += OnDataValueChanged;
} }
} }
private void OnDataValueChanged(DataWrapper<NodeDataWrapper, NodeData> obj){ private void OnDataValueChanged(DataWrapper<NodeDataWrapper, NodeData> obj){
Refresh(); Refresh();
if (BaseDataGraphView == null) return;
if (BaseDataGraphView.IsRuntimeGraph){ if (BaseDataGraphView.IsRuntimeGraph){
BaseDataGraphView.NotifyRuntimeUpdate(); BaseDataGraphView.NotifyRuntimeUpdate();
} }
} }
public sealed override string title{ public sealed override string title{
get => base.title; get => base.title;
@ -65,6 +90,13 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeViews{
if (_nodeInspectorInNode != null){ if (_nodeInspectorInNode != null){
_nodeInspectorInNode.Data = obj; _nodeInspectorInNode.Data = obj;
} }
_viewLogger ??= new NodeViewLogger{NodeView = this};
if (NodeLogger.Loggers.ContainsKey(obj.id)){
NodeLogger.Loggers[obj.id] = _viewLogger;
}
else{
NodeLogger.Loggers.Add(obj.id,_viewLogger);
}
BuildInputAndOutputPort(); BuildInputAndOutputPort();
this.expanded = true; this.expanded = true;
this.RefreshExpandedState(); this.RefreshExpandedState();
@ -106,7 +138,6 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeViews{
foreach (var propertyInfo in propertyInfos){ foreach (var propertyInfo in propertyInfos){
if (propertyInfo.GetCustomAttributes(typeof(OutputAttribute),true).FirstOrDefault() is OutputAttribute attribute){ if (propertyInfo.GetCustomAttributes(typeof(OutputAttribute),true).FirstOrDefault() is OutputAttribute attribute){
Port port = new CustomPort(Orientation.Horizontal, Direction.Output, Port port = new CustomPort(Orientation.Horizontal, Direction.Output,
attribute.Multiple ? Port.Capacity.Multi : Port.Capacity.Single, attribute.Multiple ? Port.Capacity.Multi : Port.Capacity.Single,
BuildPortType(attribute, propertyInfo)); BuildPortType(attribute, propertyInfo));
@ -115,16 +146,18 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeViews{
var portName = ObjectNames.NicifyVariableName(BuildPortName(attribute,propertyInfo)); var portName = ObjectNames.NicifyVariableName(BuildPortName(attribute,propertyInfo));
port.portName = portName; port.portName = portName;
port.name = propertyInfo.Name; port.name = propertyInfo.Name;
} }
} }
foreach (var propertyInfo in propertyInfos){ foreach (var propertyInfo in propertyInfos){
if(propertyInfo.GetCustomAttributes(typeof(InputAttribute),true).FirstOrDefault() is InputAttribute attribute){ if(propertyInfo.GetCustomAttributes(typeof(InputAttribute),true).FirstOrDefault() is InputAttribute attribute){
Port port = new CustomPort(Orientation.Horizontal, Direction.Input,attribute.Multiple?Port.Capacity.Multi:Port.Capacity.Single,BuildPortType(attribute,propertyInfo)); Port port = new CustomPort(Orientation.Horizontal, Direction.Input,attribute.Multiple?Port.Capacity.Multi:Port.Capacity.Single,BuildPortType(attribute,propertyInfo));
this.inputContainer.Add(port); this.inputContainer.Add(port);
var portName = BuildPortName(attribute,propertyInfo); var portName = BuildPortName(attribute,propertyInfo);
port.portName = portName; port.portName = portName;
port.name = propertyInfo.Name; port.name = propertyInfo.Name;
} }
} }
} }

Loading…
Cancel
Save