From 8d6792ae5845a2ed1d3138afee92d920e2d671c0 Mon Sep 17 00:00:00 2001
From: taoria <445625470@qq.com>
Date: Wed, 3 Aug 2022 17:02:45 +0800
Subject: [PATCH 1/2] fix:Node create at correct position
---
README.md | 15 ++---
.../Runtime/Attributes/GraphUsageAttribute.cs | 2 +-
.../Runtime/Models/BlackboardData.cs | 10 +--
TNode/TNodeCore/Runtime/Models/IModel.cs | 7 --
TNode/TNodeCore/Runtime/Models/Model.cs | 17 +++++
.../Models/{IModel.cs.meta => Model.cs.meta} | 0
TNode/TNodeCore/Runtime/Models/NodeData.cs | 7 +-
.../Runtime/RuntimeCache/RuntimeCache.cs | 14 ++--
.../Editor/Cache/NodeEditorExtensions.cs | 2 +-
.../Editor/NodeGraphView/DataGraphView.cs | 64 +++++++++++--------
.../Editor/NodeViews/NodeView.cs | 14 ++++
TNode/TNodeGtfImpl/Editor.meta | 3 +
12 files changed, 97 insertions(+), 58 deletions(-)
delete mode 100644 TNode/TNodeCore/Runtime/Models/IModel.cs
create mode 100644 TNode/TNodeCore/Runtime/Models/Model.cs
rename TNode/TNodeCore/Runtime/Models/{IModel.cs.meta => Model.cs.meta} (100%)
create mode 100644 TNode/TNodeGtfImpl/Editor.meta
diff --git a/README.md b/README.md
index 73c46e9..20868e5 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,10 @@
# T-Node
Node graph creation tool based on unity experimental graphview and if possible latter,GTF.
+
the main goal of the repo is to make graph creation easier and more intuitive.
Note **it's not usable and productive on current stage** and need a better
development .
-and it's mainly for my own use now.
The tool separate its graph editor implementation and the graph creation logic.
@@ -12,25 +12,24 @@ The tool separate its graph editor implementation and the graph creation logic.
currently under development
-# Main Features
+# Some Features
-* Create graph script by the creator tool
+* Create graph script a the creator tool
* Node creation based on specified type of graph
* Easy port creation via attribute
* Runtime graph
* Blackboard for runtime graph as exposed parameters
* Runtime graph execution
* An easy test mode (Runtime graph only)
+* Scene object nodes hold scene objects
# Some To-dos
-* Caching runtime state for faster execution
-* Undo redo support
* Function as port
-* Better blackboard support
+* Circular dependency support for some situations such as FSM
+* Edge colors customization
# Usage
-No ,It's better not to use TNode at current stage until it's stable.
-
+Not yet documented
### Convention
diff --git a/TNode/TNodeCore/Runtime/Attributes/GraphUsageAttribute.cs b/TNode/TNodeCore/Runtime/Attributes/GraphUsageAttribute.cs
index c58a82b..9b29815 100644
--- a/TNode/TNodeCore/Runtime/Attributes/GraphUsageAttribute.cs
+++ b/TNode/TNodeCore/Runtime/Attributes/GraphUsageAttribute.cs
@@ -4,7 +4,7 @@ using TNodeCore.Runtime.Models;
namespace TNodeCore.Runtime.Attributes{
///
- /// Use this attribute to claim the usage of a type derived IModel IModel
+ /// Use this attribute to claim the usage of a type derived Model Model
/// it can be applied to the same node multiple times.
///
/// [GraphUsage(DialogueGraph)]
diff --git a/TNode/TNodeCore/Runtime/Models/BlackboardData.cs b/TNode/TNodeCore/Runtime/Models/BlackboardData.cs
index a5d95a9..4d67b50 100644
--- a/TNode/TNodeCore/Runtime/Models/BlackboardData.cs
+++ b/TNode/TNodeCore/Runtime/Models/BlackboardData.cs
@@ -1,4 +1,5 @@
using System;
+using UnityEngine;
namespace TNodeCore.Runtime.Models{
///
@@ -6,11 +7,10 @@ namespace TNodeCore.Runtime.Models{
///
[Serializable]
- public class BlackboardData:IModel,ICloneable{
- public object Clone(){
- return this.MemberwiseClone();
- }
+ public class BlackboardData:Model,ICloneable{
-
+
+
+
}
}
\ No newline at end of file
diff --git a/TNode/TNodeCore/Runtime/Models/IModel.cs b/TNode/TNodeCore/Runtime/Models/IModel.cs
deleted file mode 100644
index c4ea9e9..0000000
--- a/TNode/TNodeCore/Runtime/Models/IModel.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-using System;
-
-namespace TNodeCore.Runtime.Models{
- public interface IModel:ICloneable{
-
- }
-}
\ No newline at end of file
diff --git a/TNode/TNodeCore/Runtime/Models/Model.cs b/TNode/TNodeCore/Runtime/Models/Model.cs
new file mode 100644
index 0000000..06b99dc
--- /dev/null
+++ b/TNode/TNodeCore/Runtime/Models/Model.cs
@@ -0,0 +1,17 @@
+using System;
+using UnityEngine;
+using UnityEngine.Serialization;
+
+namespace TNodeCore.Runtime.Models{
+ [Serializable]
+ public abstract class Model:ICloneable{
+ #if UNITY_EDITOR
+ public Rect positionInView;
+ #endif
+
+ public object Clone(){
+ var memberwiseClone = this.MemberwiseClone();
+ return memberwiseClone;
+ }
+ }
+}
\ No newline at end of file
diff --git a/TNode/TNodeCore/Runtime/Models/IModel.cs.meta b/TNode/TNodeCore/Runtime/Models/Model.cs.meta
similarity index 100%
rename from TNode/TNodeCore/Runtime/Models/IModel.cs.meta
rename to TNode/TNodeCore/Runtime/Models/Model.cs.meta
diff --git a/TNode/TNodeCore/Runtime/Models/NodeData.cs b/TNode/TNodeCore/Runtime/Models/NodeData.cs
index 7fc1ae0..f685a13 100644
--- a/TNode/TNodeCore/Runtime/Models/NodeData.cs
+++ b/TNode/TNodeCore/Runtime/Models/NodeData.cs
@@ -12,7 +12,7 @@ namespace TNodeCore.Runtime.Models{
///
///
[Serializable]
- public class NodeData:IModel{
+ public class NodeData:Model{
public NodeData() : base(){
//Object Registration
@@ -37,8 +37,7 @@ namespace TNodeCore.Runtime.Models{
}
#endif
- public object Clone(){
- return this.MemberwiseClone();
- }
+
+
}
}
\ No newline at end of file
diff --git a/TNode/TNodeCore/Runtime/RuntimeCache/RuntimeCache.cs b/TNode/TNodeCore/Runtime/RuntimeCache/RuntimeCache.cs
index 16636a7..c2db650 100644
--- a/TNode/TNodeCore/Runtime/RuntimeCache/RuntimeCache.cs
+++ b/TNode/TNodeCore/Runtime/RuntimeCache/RuntimeCache.cs
@@ -64,8 +64,8 @@ namespace TNodeCore.Runtime.RuntimeCache{
get{ return _instance ??= new RuntimeCache(); }
}
//delegate return a value from a nodedata
- public delegate object GetValueDelegate(IModel nodeData);
- public delegate void SetValueDelegate(IModel nodeData,object value);
+ public delegate object GetValueDelegate(Model nodeData);
+ public delegate void SetValueDelegate(Model nodeData,object value);
@@ -258,11 +258,11 @@ namespace TNodeCore.Runtime.RuntimeCache{
public static class RuntimeExtension{
//todo latter on i will try some way caching reflection more efficiently
- public static T GetValue(this IModel data,string path,Type type=null){
+ public static T GetValue(this Model data,string path,Type type=null){
var method = RuntimeCache.Instance.CachedDelegatesForGettingValue[type??data.GetType()][path];
return (T) method.Invoke(data);
}
- public static object GetValue(this IModel data, string path,Type type=null){
+ public static object GetValue(this Model data, string path,Type type=null){
if(!RuntimeCache.Instance.CachedDelegatesForGettingValue.ContainsKey(type??data.GetType())){
return null;
}
@@ -270,7 +270,7 @@ namespace TNodeCore.Runtime.RuntimeCache{
var method = dic.ContainsKey(path) ? dic[path] : null;
return method?.Invoke(data);
}
- public static object GetListValue(this IModel data,string path,int index,Type type=null){
+ public static object GetListValue(this Model data,string path,int index,Type type=null){
if(!RuntimeCache.Instance.CachedDelegatesForGettingValue.ContainsKey(type??data.GetType())){
return null;
}
@@ -286,11 +286,11 @@ namespace TNodeCore.Runtime.RuntimeCache{
return list[index];
}
- public static void SetValue(this IModel data,string path,T value,Type type=null){
+ public static void SetValue(this Model data,string path,T value,Type type=null){
var method = RuntimeCache.Instance.CachedDelegatesForSettingValue[type??data.GetType()][path];
method.Invoke(data,value);
}
- public static void SetValue(this IModel data,string path,object value,Type type=null){
+ public static void SetValue(this Model data,string path,object value,Type type=null){
var method = RuntimeCache.Instance.CachedDelegatesForSettingValue[type??data.GetType()][path];
method.Invoke(data,value);
}
diff --git a/TNode/TNodeGraphViewImpl/Editor/Cache/NodeEditorExtensions.cs b/TNode/TNodeGraphViewImpl/Editor/Cache/NodeEditorExtensions.cs
index 5947bfc..598fe9d 100644
--- a/TNode/TNodeGraphViewImpl/Editor/Cache/NodeEditorExtensions.cs
+++ b/TNode/TNodeGraphViewImpl/Editor/Cache/NodeEditorExtensions.cs
@@ -89,7 +89,7 @@ namespace TNode.TNodeGraphViewImpl.Editor.Cache{
private void SetGraphUsageAttribute(Type type){
foreach (var attribute in type.GetCustomAttributes(typeof(GraphUsageAttribute), true)){
var parent = type.BaseType;
- if (typeof(IModel).IsAssignableFrom(type.BaseType)){
+ if (typeof(Model).IsAssignableFrom(type.BaseType)){
//Check if GraphDataUsage dictionary has GraphDataType of attribute
if (typeof(NodeData).IsAssignableFrom(type)){
diff --git a/TNode/TNodeGraphViewImpl/Editor/NodeGraphView/DataGraphView.cs b/TNode/TNodeGraphViewImpl/Editor/NodeGraphView/DataGraphView.cs
index a595919..e6929fe 100644
--- a/TNode/TNodeGraphViewImpl/Editor/NodeGraphView/DataGraphView.cs
+++ b/TNode/TNodeGraphViewImpl/Editor/NodeGraphView/DataGraphView.cs
@@ -98,15 +98,14 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeGraphView{
var res = DragAndDrop.objectReferences;
foreach (var obj in res){
if (obj is T graphData){
- Data = graphData;
IsRuntimeGraph = false;
+ Data = graphData;
}
else{
if (obj is GameObject gameObject){
if (gameObject.GetComponent() != null){
if (gameObject.GetComponent().graphData != null){
-
_runtimeGraph = gameObject.GetComponent();
IsRuntimeGraph = true;
BuildRuntimeGraphBehaviour();
@@ -114,7 +113,6 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeGraphView{
if(Data==null){
Debug.LogError($"Dragged a wrong graph data to editor,expected {typeof(T)} but got {gameObject.GetComponent().graphData.GetType()}");
}
-
}
}
}
@@ -341,8 +339,7 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeGraphView{
}
private void AddPersistentNode(NodeData dataNode){
- var nodePos = Owner.graphEditorData.graphElementsData.FirstOrDefault(x => x.guid == dataNode.id)?.pos ??
- new Rect(0, 0, 200, 200);
+ var nodePos = dataNode.positionInView;
AddTNode(dataNode, nodePos);
}
//OnDataChanged event
@@ -391,21 +388,21 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeGraphView{
}
public void SaveEditorData(GraphEditorData graphEditorData){
- graphEditorData.graphElementsData?.Clear();
- //iterator nodes
- if (graphEditorData.graphElementsData == null){
- graphEditorData.graphElementsData = new List();
- }
- foreach (var node in this.nodes){
- var nodeEditorData = new GraphElementEditorData{
- pos = node.GetPosition(),
- };
- if (node is IBaseNodeView nodeView){
- nodeEditorData.guid = nodeView.GetNodeData().id;
- }
- graphEditorData.graphElementsData.Add(nodeEditorData);
- EditorUtility.SetDirty(graphEditorData);
- }
+ // graphEditorData.graphElementsData?.Clear();
+ // //iterator nodes
+ // if (graphEditorData.graphElementsData == null){
+ // graphEditorData.graphElementsData = new List();
+ // }
+ // foreach (var node in this.nodes){
+ // var nodeEditorData = new GraphElementEditorData{
+ // pos = node.GetPosition(),
+ // };
+ // if (node is IBaseNodeView nodeView){
+ // nodeEditorData.guid = nodeView.GetNodeData().id;
+ // }
+ // graphEditorData.graphElementsData.Add(nodeEditorData);
+ // EditorUtility.SetDirty(graphEditorData);
+ // }
}
public void SaveWithEditorData(GraphEditorData graphEditorData){
@@ -499,8 +496,15 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeGraphView{
#region implement interfaces
public void AddTNode(NodeData nodeData, Rect rect){
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);
+ ((IBaseNodeView)nodeView).InitializePosition(rect);
//Add a select callback to the nodeView
nodeView.RegisterCallback(evt => {
if (evt.clickCount == 1){
@@ -510,14 +514,17 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeGraphView{
}
}
});
- if(nodeView is IBaseNodeView nodeViewInterface){
- nodeViewInterface.SetNodeData(nodeData);
- }
- _nodeDict.Add(nodeData.id, nodeView);
+
+
+
+ if(_nodeDict.ContainsKey(nodeData.id)==false)
+ _nodeDict.Add(nodeData.id, nodeView);
if (_data.NodeDictionary.ContainsKey(nodeData.id) == false){
Undo.RegisterCompleteObjectUndo(_data,"Node Creation");
_data.NodeDictionary.Add(nodeData.id,nodeData);
}
+
+
//register an callback ,when right click context menu
nodeView.RegisterCallback(evt => {
var menu = new GenericMenu();
@@ -558,6 +565,13 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeGraphView{
}
public bool TestMode{ get; set; }
+
+ public override EventPropagation DeleteSelection(){
+ Undo.RegisterCompleteObjectUndo(_data,"Delete Selection");
+ var res = base.DeleteSelection();
+ ResetGraphView();
+ return res;
+ }
public void CreateBlackboard(){
_blackboard = NodeEditorExtensions.CreateBlackboardWithGraphData(typeof(T));
diff --git a/TNode/TNodeGraphViewImpl/Editor/NodeViews/NodeView.cs b/TNode/TNodeGraphViewImpl/Editor/NodeViews/NodeView.cs
index c36a3b1..ca5ddfc 100644
--- a/TNode/TNodeGraphViewImpl/Editor/NodeViews/NodeView.cs
+++ b/TNode/TNodeGraphViewImpl/Editor/NodeViews/NodeView.cs
@@ -184,6 +184,18 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeViews{
Refresh();
}
+ public override void SetPosition(Rect newPos){
+ var graphView = (GraphView)BaseDataGraphView;
+ //Cast newPos s position to global space
+ var globalPos = graphView.contentViewContainer.LocalToWorld(newPos.position);
+ _data.positionInView.position = globalPos;
+ base.SetPosition(newPos);
+ }
+
+ public void InitializePosition(Rect pos){
+ base.SetPosition(pos);
+ }
+
public void Refresh(){
title = _data.nodeName;
}
@@ -195,6 +207,8 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeViews{
public void OnDataModified();
IBaseDataGraphView BaseDataGraphView{ get; }
+
+ public void InitializePosition(Rect pos);
}
public interface INodeView:IBaseNodeView where T:NodeData,new(){
diff --git a/TNode/TNodeGtfImpl/Editor.meta b/TNode/TNodeGtfImpl/Editor.meta
new file mode 100644
index 0000000..802b624
--- /dev/null
+++ b/TNode/TNodeGtfImpl/Editor.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: fa7dcd53ede6483793978d44af911270
+timeCreated: 1659437565
\ No newline at end of file
From fc2395fdf1daf219f781f42037d99b8ef9527192 Mon Sep 17 00:00:00 2001
From: taoria <445625470@qq.com>
Date: Thu, 4 Aug 2022 15:35:35 +0800
Subject: [PATCH 2/2] feature:run once button and a node logger
---
.../EditorPersistence/GraphEditorData.cs | 4 +-
.../NodeGraphView/IBaseDataGraphView.cs | 9 +-
.../Runtime/Attributes/HideInBlackboard.cs | 6 ++
.../Attributes/HideInBlackboard.cs.meta | 3 +
.../Runtime/Attributes/ModelColor.cs | 5 +
.../Runtime/Attributes/ModelColor.cs.meta | 3 +
.../Attributes/Ports/InputAttribute.cs | 3 +
.../Attributes/Ports/OutputAttribute.cs | 8 +-
.../Runtime/Attributes/Ports/PortAttribute.cs | 8 ++
TNode/TNodeCore/Runtime/Models/Model.cs | 2 +
TNode/TNodeCore/Runtime/NodeLogger.cs | 21 ++++
TNode/TNodeCore/Runtime/NodeLogger.cs.meta | 3 +
.../DefaultGraphBlackboardView.cs | 4 +-
.../Editor/Inspector/NodeInspectorInNode.cs | 2 +-
.../Editor/NodeGraphView/DataGraphView.cs | 97 +++++++++++++------
.../Editor/NodeViews/NodeView.cs | 39 +++++++-
16 files changed, 178 insertions(+), 39 deletions(-)
create mode 100644 TNode/TNodeCore/Runtime/Attributes/HideInBlackboard.cs
create mode 100644 TNode/TNodeCore/Runtime/Attributes/HideInBlackboard.cs.meta
create mode 100644 TNode/TNodeCore/Runtime/Attributes/ModelColor.cs
create mode 100644 TNode/TNodeCore/Runtime/Attributes/ModelColor.cs.meta
create mode 100644 TNode/TNodeCore/Runtime/NodeLogger.cs
create mode 100644 TNode/TNodeCore/Runtime/NodeLogger.cs.meta
diff --git a/TNode/TNodeCore/Editor/EditorPersistence/GraphEditorData.cs b/TNode/TNodeCore/Editor/EditorPersistence/GraphEditorData.cs
index 7d85841..10414d7 100644
--- a/TNode/TNodeCore/Editor/EditorPersistence/GraphEditorData.cs
+++ b/TNode/TNodeCore/Editor/EditorPersistence/GraphEditorData.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using TNodeCore.Editor.NodeGraphView;
using TNodeCore.Runtime.Models;
using UnityEngine;
+using UnityEngine.Serialization;
namespace TNodeCore.Editor.EditorPersistence{
@@ -14,7 +15,8 @@ namespace TNodeCore.Editor.EditorPersistence{
public GraphImplType graphImplType = GraphImplType.GraphViewImpl;
public static Func GraphViewImplCreator;
public static Func GtfImplCreator;
-
+ [FormerlySerializedAs("testMode")] public bool autoUpdate;
+
public IDataGraphView GetGraphView () where T:GraphData{
switch (graphImplType){
case GraphImplType.GraphViewImpl:{
diff --git a/TNode/TNodeCore/Editor/NodeGraphView/IBaseDataGraphView.cs b/TNode/TNodeCore/Editor/NodeGraphView/IBaseDataGraphView.cs
index d907b4b..ee45cfc 100644
--- a/TNode/TNodeCore/Editor/NodeGraphView/IBaseDataGraphView.cs
+++ b/TNode/TNodeCore/Editor/NodeGraphView/IBaseDataGraphView.cs
@@ -14,7 +14,7 @@ namespace TNodeCore.Editor.NodeGraphView{
public void RemoveLink(NodeLink nodeLink);
- public bool TestMode{ get; set; }
+ public bool AutoUpdate{ get; set; }
public void CreateBlackboard();
public GraphData GetGraphData();
public BlackboardData GetBlackboardData();
@@ -30,9 +30,12 @@ namespace TNodeCore.Editor.NodeGraphView{
public void SetGraphData(GraphData graph);
- void NotifyRuntimeUpdate();
- public Action AfterRuntimeGraphUpdate{ get; set; }
+ public Action AfterGraphResolved{ get; set; }
void AfterEditorLoadGraphView();
+
+ //todo remove it later ,keep it now
+ void NotifyRuntimeUpdate();
+
}
}
\ No newline at end of file
diff --git a/TNode/TNodeCore/Runtime/Attributes/HideInBlackboard.cs b/TNode/TNodeCore/Runtime/Attributes/HideInBlackboard.cs
new file mode 100644
index 0000000..b7268ce
--- /dev/null
+++ b/TNode/TNodeCore/Runtime/Attributes/HideInBlackboard.cs
@@ -0,0 +1,6 @@
+namespace TNodeCore.Runtime.Attributes{
+
+ public class HideInBlackboard:System.Attribute{
+
+ }
+}
\ No newline at end of file
diff --git a/TNode/TNodeCore/Runtime/Attributes/HideInBlackboard.cs.meta b/TNode/TNodeCore/Runtime/Attributes/HideInBlackboard.cs.meta
new file mode 100644
index 0000000..5daa766
--- /dev/null
+++ b/TNode/TNodeCore/Runtime/Attributes/HideInBlackboard.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 731893f9f7824b939cee169d61092ad3
+timeCreated: 1659517588
\ No newline at end of file
diff --git a/TNode/TNodeCore/Runtime/Attributes/ModelColor.cs b/TNode/TNodeCore/Runtime/Attributes/ModelColor.cs
new file mode 100644
index 0000000..ae7106c
--- /dev/null
+++ b/TNode/TNodeCore/Runtime/Attributes/ModelColor.cs
@@ -0,0 +1,5 @@
+namespace TNodeCore.Runtime.Attributes{
+ public class ModelColor{
+
+ }
+}
\ No newline at end of file
diff --git a/TNode/TNodeCore/Runtime/Attributes/ModelColor.cs.meta b/TNode/TNodeCore/Runtime/Attributes/ModelColor.cs.meta
new file mode 100644
index 0000000..e0cce46
--- /dev/null
+++ b/TNode/TNodeCore/Runtime/Attributes/ModelColor.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: cdec5767969f4e11bbcfb245693796f9
+timeCreated: 1659521617
\ No newline at end of file
diff --git a/TNode/TNodeCore/Runtime/Attributes/Ports/InputAttribute.cs b/TNode/TNodeCore/Runtime/Attributes/Ports/InputAttribute.cs
index 6b8ba37..676f6db 100644
--- a/TNode/TNodeCore/Runtime/Attributes/Ports/InputAttribute.cs
+++ b/TNode/TNodeCore/Runtime/Attributes/Ports/InputAttribute.cs
@@ -1,5 +1,6 @@
using System;
using JetBrains.Annotations;
+using UnityEngine;
namespace TNodeCore.Runtime.Attributes.Ports{
[MeansImplicitUse]
@@ -7,5 +8,7 @@ namespace TNodeCore.Runtime.Attributes.Ports{
public class InputAttribute : PortAttribute{
public InputAttribute(string name="", PortNameHandling nameHandling = PortNameHandling.Auto,TypeHandling typeHandling=TypeHandling.Declared) : base(name, nameHandling,typeHandling){
}
+ public InputAttribute(Color color):base(color){
+ }
}
}
\ No newline at end of file
diff --git a/TNode/TNodeCore/Runtime/Attributes/Ports/OutputAttribute.cs b/TNode/TNodeCore/Runtime/Attributes/Ports/OutputAttribute.cs
index b11340d..47eb6c9 100644
--- a/TNode/TNodeCore/Runtime/Attributes/Ports/OutputAttribute.cs
+++ b/TNode/TNodeCore/Runtime/Attributes/Ports/OutputAttribute.cs
@@ -1,8 +1,14 @@
-namespace TNodeCore.Runtime.Attributes.Ports{
+using UnityEngine;
+
+namespace TNodeCore.Runtime.Attributes.Ports{
public class OutputAttribute:PortAttribute{
public OutputAttribute(string name="", PortNameHandling nameHandling = PortNameHandling.Auto,TypeHandling typeHandling = TypeHandling.Declared) : base(name, nameHandling,typeHandling){
}
+ public OutputAttribute(Color color):base(color){
+ }
+
+
}
}
\ No newline at end of file
diff --git a/TNode/TNodeCore/Runtime/Attributes/Ports/PortAttribute.cs b/TNode/TNodeCore/Runtime/Attributes/Ports/PortAttribute.cs
index b27710e..9146a79 100644
--- a/TNode/TNodeCore/Runtime/Attributes/Ports/PortAttribute.cs
+++ b/TNode/TNodeCore/Runtime/Attributes/Ports/PortAttribute.cs
@@ -1,6 +1,8 @@
using System;
+using UnityEngine;
using JetBrains.Annotations;
+
namespace TNodeCore.Runtime.Attributes.Ports{
public enum PortNameHandling{
@@ -23,6 +25,7 @@ namespace TNodeCore.Runtime.Attributes.Ports{
public readonly PortNameHandling NameHandling;
public Type HandledType;
public bool Multiple = true;
+ public Color PortColor = Color.black;
public TypeHandling TypeHandling{ get; set; }
public PortAttribute(string name,PortNameHandling nameHandling=PortNameHandling.Auto,TypeHandling typeHandling=TypeHandling.Declared){
this.Name = name;
@@ -30,6 +33,11 @@ namespace TNodeCore.Runtime.Attributes.Ports{
this.TypeHandling = typeHandling;
}
+ public PortAttribute(Color color):this("",PortNameHandling.Auto,TypeHandling.Declared){
+
+ PortColor = color;
+ }
+
}
}
\ No newline at end of file
diff --git a/TNode/TNodeCore/Runtime/Models/Model.cs b/TNode/TNodeCore/Runtime/Models/Model.cs
index 06b99dc..6571aa0 100644
--- a/TNode/TNodeCore/Runtime/Models/Model.cs
+++ b/TNode/TNodeCore/Runtime/Models/Model.cs
@@ -1,4 +1,5 @@
using System;
+using TNodeCore.Runtime.Attributes;
using UnityEngine;
using UnityEngine.Serialization;
@@ -6,6 +7,7 @@ namespace TNodeCore.Runtime.Models{
[Serializable]
public abstract class Model:ICloneable{
#if UNITY_EDITOR
+ [HideInBlackboard]
public Rect positionInView;
#endif
diff --git a/TNode/TNodeCore/Runtime/NodeLogger.cs b/TNode/TNodeCore/Runtime/NodeLogger.cs
new file mode 100644
index 0000000..d967e62
--- /dev/null
+++ b/TNode/TNodeCore/Runtime/NodeLogger.cs
@@ -0,0 +1,21 @@
+using System.Collections.Generic;
+using TNodeCore.Runtime.Models;
+using UnityEngine;
+
+namespace TNodeCore.Runtime{
+ public static class NodeLogger{
+ public static Dictionary 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);
+ }
+}
\ No newline at end of file
diff --git a/TNode/TNodeCore/Runtime/NodeLogger.cs.meta b/TNode/TNodeCore/Runtime/NodeLogger.cs.meta
new file mode 100644
index 0000000..1d16c7b
--- /dev/null
+++ b/TNode/TNodeCore/Runtime/NodeLogger.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 48be07a2cf064167b15d378ac41757c4
+timeCreated: 1659592209
\ No newline at end of file
diff --git a/TNode/TNodeGraphViewImpl/Editor/GraphBlackboard/DefaultGraphBlackboardView.cs b/TNode/TNodeGraphViewImpl/Editor/GraphBlackboard/DefaultGraphBlackboardView.cs
index 36bd89c..ac89773 100644
--- a/TNode/TNodeGraphViewImpl/Editor/GraphBlackboard/DefaultGraphBlackboardView.cs
+++ b/TNode/TNodeGraphViewImpl/Editor/GraphBlackboard/DefaultGraphBlackboardView.cs
@@ -6,6 +6,7 @@ using TNodeCore.Editor.NodeGraphView;
using TNodeCore.Editor.Serialization;
using TNodeCore.Runtime.Attributes;
using TNodeCore.Runtime.Models;
+using Unity.VisualScripting;
using UnityEditor;
using UnityEditor.Experimental.GraphView;
using UnityEditor.UIElements;
@@ -22,8 +23,8 @@ namespace TNode.TNodeGraphViewImpl.Editor.GraphBlackboard{
}
protected override void UpdateBlackboard(BlackboardData data){
+ Clear();
if (data == null) return;
- this.Clear();
var serializedObject = new SerializedObject((BlackboardDataWrapper)data);
var currentGraphView = graphView as IBaseDataGraphView;
var isRuntimeGraph = currentGraphView?.IsRuntimeGraph ?? false;
@@ -33,6 +34,7 @@ namespace TNode.TNodeGraphViewImpl.Editor.GraphBlackboard{
Add(blackboardGlobalSection);
foreach (var field in data.GetType()
.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)){
+ if(field.HasAttribute(typeof(HideInBlackboard))) continue;
//if the field is MonoBehaviour,add a property field for blackboard
//skip if the field is a list or Ilist
if (!typeof(IList).IsAssignableFrom(field.FieldType)&&!field.FieldType.IsArray){
diff --git a/TNode/TNodeGraphViewImpl/Editor/Inspector/NodeInspectorInNode.cs b/TNode/TNodeGraphViewImpl/Editor/Inspector/NodeInspectorInNode.cs
index f54a4c6..66eb4f9 100644
--- a/TNode/TNodeGraphViewImpl/Editor/Inspector/NodeInspectorInNode.cs
+++ b/TNode/TNodeGraphViewImpl/Editor/Inspector/NodeInspectorInNode.cs
@@ -67,7 +67,7 @@ namespace TNode.TNodeGraphViewImpl.Editor.Inspector{
Add(drawer);
}
- var globalTest = GetFirstAncestorOfType()?.TestMode;
+ var globalTest = GetFirstAncestorOfType()?.AutoUpdate;
if(globalTest??false){
CreateTestButton();
}
diff --git a/TNode/TNodeGraphViewImpl/Editor/NodeGraphView/DataGraphView.cs b/TNode/TNodeGraphViewImpl/Editor/NodeGraphView/DataGraphView.cs
index e6929fe..8a1459d 100644
--- a/TNode/TNodeGraphViewImpl/Editor/NodeGraphView/DataGraphView.cs
+++ b/TNode/TNodeGraphViewImpl/Editor/NodeGraphView/DataGraphView.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
+using System.Threading.Tasks;
using TNode.TNodeGraphViewImpl.Editor.Cache;
using TNode.TNodeGraphViewImpl.Editor.GraphBlackboard;
using TNode.TNodeGraphViewImpl.Editor.Inspector;
@@ -16,6 +17,7 @@ using TNodeCore.Editor.Tools.NodeCreator;
using TNodeCore.Runtime.Components;
using TNodeCore.Runtime.Models;
using TNodeCore.Runtime.RuntimeCache;
+using Unity.VisualScripting;
using UnityEditor;
using UnityEditor.Experimental.GraphView;
using UnityEngine;
@@ -25,16 +27,18 @@ using Edge = UnityEditor.Experimental.GraphView.Edge;
namespace TNode.TNodeGraphViewImpl.Editor.NodeGraphView{
public class BaseDataGraphView:GraphView,IDataGraphView where T:GraphData{
+ #region const
+ public const float RefreshRate = 1f;
+ #endregion
#region variables and properties
private T _data;
private RuntimeGraph _runtimeGraph;
-
private bool _isInspectorOn;
private NodeSearchWindowProvider _nodeSearchWindowProvider;
private NodeInspector _nodeInspector;
private Dictionary _nodeDict = new();
private IBlackboardView _blackboard;
- private bool _runtimeGraphUpdate;
+ private bool _loaded;
public T Data{
get{ return _data; }
set{
@@ -145,25 +149,36 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeGraphView{
}
private void BuildRuntimeGraphBehaviour(){
- EditorApplication.update+= UpdateRuntimeGraphBehaviour;
+ //EditorApplication.update+= UpdateRuntimeGraphBehaviour;
+ UpdateRuntimeGraphBehaviourInTime();
}
-
- private void UpdateRuntimeGraphBehaviour(){
- if(_runtimeGraph != null){
- if (_runtimeGraphUpdate){
- _runtimeGraphUpdate = false;
- _runtimeGraph.ResolveDependency();
-
- AfterRuntimeGraphUpdate?.Invoke();
+
+ private async void UpdateRuntimeGraphBehaviourInTime(){
+
+ 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(){
if(Data == null){
@@ -199,6 +214,18 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeGraphView{
OnGraphViewCreate();
BuildUndo();
+
+ _loaded = true;
+
+ SetDetachedFromPanel();
+
+
+ }
+
+ private void SetDetachedFromPanel(){
+ this.RegisterCallback(evt => {
+ _loaded = false;
+ });
}
private void BuildUndo(){
@@ -225,22 +252,32 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeGraphView{
//Add a toggle button to toggle test mode
- var testModeToggle = new Toggle{
+ var autoUpdateToggle = new Toggle{
name = "TestModeToggle",
label = "Test Mode",
- value = false
+ value = AutoUpdate
};
- testModeToggle.RegisterValueChangedCallback(evt => {
+ autoUpdateToggle.RegisterValueChangedCallback(evt => {
if (evt.newValue){
- TestMode = true;
+ AutoUpdate = true;
}
else{
- TestMode = false;
+ AutoUpdate = false;
}
});
- visualElement.Add(testModeToggle);
+ visualElement.Add(autoUpdateToggle);
-
+ var runButton = new Button{
+ name = "RunButton",
+ text = "Run Once"
+ };
+ runButton.RegisterCallback(evt => {
+ if (IsRuntimeGraph){
+ _runtimeGraph.ResolveDependency();
+ AfterGraphResolved?.Invoke();
+ }
+ });
+ visualElement.Add(runButton);
}
public void RegisterDragEvent(){
@@ -536,6 +573,8 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeGraphView{
});
menu.ShowAsContext();
});
+
+
}
}
@@ -564,11 +603,14 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeGraphView{
_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;
}
@@ -576,7 +618,6 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeGraphView{
public void CreateBlackboard(){
_blackboard = NodeEditorExtensions.CreateBlackboardWithGraphData(typeof(T));
_blackboard.Setup(this,Owner);
- Debug.Log(Owner);
var castedBlackboard = _blackboard as Blackboard;
Add(castedBlackboard);
Rect blackboardPos = new Rect(0,0,300,700);
@@ -608,11 +649,9 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeGraphView{
public void NotifyRuntimeUpdate(){
- _runtimeGraphUpdate = true;
}
-
-
- public Action AfterRuntimeGraphUpdate{ get; set; }
+
+ public Action AfterGraphResolved{ get; set; }
#endregion
}
diff --git a/TNode/TNodeGraphViewImpl/Editor/NodeViews/NodeView.cs b/TNode/TNodeGraphViewImpl/Editor/NodeViews/NodeView.cs
index ca5ddfc..a94b9cf 100644
--- a/TNode/TNodeGraphViewImpl/Editor/NodeViews/NodeView.cs
+++ b/TNode/TNodeGraphViewImpl/Editor/NodeViews/NodeView.cs
@@ -18,6 +18,27 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeViews{
public abstract class BaseNodeView : Node,INodeView where T:NodeData,new(){
protected T _data;
private readonly NodeInspectorInNode _nodeInspectorInNode;
+ private NodeViewLogger _viewLogger;
+
+ private class NodeViewLogger:INodeLoggerImpl{
+ public BaseNodeView NodeView { get; set; }
+ public void Log(string message){
+ var loggerAreaParent = NodeView.extensionContainer;
+ if (loggerAreaParent == null){
+ return;
+ }
+ var loggerArea = loggerAreaParent.Q("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{
get{
@@ -31,18 +52,22 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeViews{
if(_data!=null)
((NodeDataWrapper)_data).OnValueChanged -= OnDataValueChanged;
_data = value;
+
OnDataChanged?.Invoke(value);
if(_data!=null)
((NodeDataWrapper)_data).OnValueChanged += OnDataValueChanged;
-
}
}
private void OnDataValueChanged(DataWrapper obj){
+
Refresh();
+ if (BaseDataGraphView == null) return;
if (BaseDataGraphView.IsRuntimeGraph){
BaseDataGraphView.NotifyRuntimeUpdate();
}
+
+
}
public sealed override string title{
get => base.title;
@@ -65,6 +90,13 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeViews{
if (_nodeInspectorInNode != null){
_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();
this.expanded = true;
this.RefreshExpandedState();
@@ -106,7 +138,6 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeViews{
foreach (var propertyInfo in propertyInfos){
if (propertyInfo.GetCustomAttributes(typeof(OutputAttribute),true).FirstOrDefault() is OutputAttribute attribute){
-
Port port = new CustomPort(Orientation.Horizontal, Direction.Output,
attribute.Multiple ? Port.Capacity.Multi : Port.Capacity.Single,
BuildPortType(attribute, propertyInfo));
@@ -115,16 +146,18 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeViews{
var portName = ObjectNames.NicifyVariableName(BuildPortName(attribute,propertyInfo));
port.portName = portName;
port.name = propertyInfo.Name;
-
}
}
foreach (var propertyInfo in propertyInfos){
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));
this.inputContainer.Add(port);
var portName = BuildPortName(attribute,propertyInfo);
port.portName = portName;
port.name = propertyInfo.Name;
+
}
}
}