diff --git a/TNodeCore/Attribute/GraphUsageAttribute.cs b/TNodeCore/Attribute/GraphUsageAttribute.cs
index af08872..4eb9151 100644
--- a/TNodeCore/Attribute/GraphUsageAttribute.cs
+++ b/TNodeCore/Attribute/GraphUsageAttribute.cs
@@ -16,15 +16,14 @@ namespace TNodeCore.Attribute{
public class GraphUsageAttribute:System.Attribute{
public readonly Type GraphDataType;
public string Category;
- public GraphUsageAttribute(Type t,string category = null){
+ public GraphUsageAttribute(Type t,string category = "default"){
//check if the type t is graph
if(!typeof(GraphData).IsAssignableFrom(t)){
throw new Exception("The type used on Graph Usage must be a graph");
}
GraphDataType = t;
- if (category != null){
- Category = category;
- }
+ Category = category;
+
}
}
diff --git a/TNodeCore/DataWrapper.cs b/TNodeCore/DataWrapper.cs
index 64e96ea..92ba218 100644
--- a/TNodeCore/DataWrapper.cs
+++ b/TNodeCore/DataWrapper.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using UnityEditor;
using UnityEngine;
namespace TNodeCore{
@@ -34,6 +35,7 @@ namespace TNodeCore{
var fieldInfo = data.GetType().GetField(path);
return fieldInfo.GetValue(data);
}
+
public virtual TData GetData(){
return data;
}
diff --git a/TNodeCore/Models/BlackboardDragNodeData.cs b/TNodeCore/Models/BlackboardDragNodeData.cs
index 0f1622f..120fd77 100644
--- a/TNodeCore/Models/BlackboardDragNodeData.cs
+++ b/TNodeCore/Models/BlackboardDragNodeData.cs
@@ -7,17 +7,25 @@ using UnityEngine;
namespace TNodeCore.Models{
[Serializable]
[InternalModel]
- public class BlackboardDragNodeData:NodeData{
+ public class BlackboardDragNodeData:RuntimeNodeData{
public string blackDragData;
- [SerializeReference]
- public BlackboardData blackboardData;
-
- [Output("",PortNameHandling.MemberType,TypeHandling.Implemented)]
- public object Value => blackboardData.GetValue(blackDragData);
+
+ ///
+ /// it's very hacky way to get blackboard data ,even when the value is null,type info is not null!
+ ///
+ /// TODO : The type handling in a safer way in the future
+ [Output("",PortNameHandling.MemberType,TypeHandling.Implemented)]
+ public object Value => BlackboardData.GetValue(blackDragData);
public BlackboardDragNodeData(){
}
}
+ [Serializable]
+ public class RuntimeNodeData:NodeData{
+
+ public BlackboardData BlackboardData{ get; set; }
+
+ }
}
\ No newline at end of file
diff --git a/TNodeCore/Runtime/RuntimeGraph.cs b/TNodeCore/Runtime/RuntimeGraph.cs
index 235f792..11dd5c8 100644
--- a/TNodeCore/Runtime/RuntimeGraph.cs
+++ b/TNodeCore/Runtime/RuntimeGraph.cs
@@ -16,6 +16,9 @@ namespace TNodeCore.Runtime{
[NonSerialized]
public readonly List TopologicalOrder = new List();
public readonly List EntryNodes = new List();
+ ///
+ /// elements are read only ,do not modify them
+ ///
public readonly Dictionary RuntimeNodes;
public void DependencyTraversal(RuntimeNode runtimeNode){
var links = runtimeNode.InputLink;
@@ -26,7 +29,7 @@ namespace TNodeCore.Runtime{
}
runtimeNode.NodeData.Process();
}
-
+
public void HandlingLink(NodeLink nodeLink){
var inNode = RuntimeNodes[nodeLink.inPort.nodeDataId];
var outNode = RuntimeNodes[nodeLink.outPort.nodeDataId];
@@ -125,6 +128,12 @@ namespace TNodeCore.Runtime{
RuntimeNodes[inNode.id].InputLink.Add(linkData);
}
+ public List GetRuntimeNodesOfType(){
+ return RuntimeNodes.Values.Where(x => x.NodeType == typeof(T)).ToList();
+ }
+ public List GetRuntimeNodesOfType(Type type){
+ return RuntimeNodes.Values.Where(x => x.NodeType == type).ToList();
+ }
private void ModifyOrCreateOutNode(NodeLink linkData){
var outNodeId = linkData.outPort.nodeDataId;
var outNode = graphData.NodeDictionary[outNodeId];
diff --git a/TNodeCore/Runtime/RuntimeNode.cs b/TNodeCore/Runtime/RuntimeNode.cs
index 515f840..e4b435a 100644
--- a/TNodeCore/Runtime/RuntimeNode.cs
+++ b/TNodeCore/Runtime/RuntimeNode.cs
@@ -15,7 +15,7 @@ namespace TNodeCore.Runtime{
public List OutputLink = new List();
//Cache node data type for fast access
private readonly Type _type;
-
+ public Type NodeType => _type;
public void SetInput(string portName,object value){
_portAccessors[portName].SetValue(this.NodeData,value);
diff --git a/TNodeCore/RuntimeCache/RuntimeCache.cs b/TNodeCore/RuntimeCache/RuntimeCache.cs
index 5eb6068..932890b 100644
--- a/TNodeCore/RuntimeCache/RuntimeCache.cs
+++ b/TNodeCore/RuntimeCache/RuntimeCache.cs
@@ -80,10 +80,7 @@ namespace TNodeCore.RuntimeCache{
}
}
}
-
-
}
-
private void AddTypeToCache(Type type,System.Attribute attribute){
//Check if the type is a blackboard data type
if(typeof(BlackboardData).IsAssignableFrom(type)){
diff --git a/TNodeGraphViewImpl/Editor/Cache/NodeEditorExtensions.cs b/TNodeGraphViewImpl/Editor/Cache/NodeEditorExtensions.cs
index 5d55934..fcdcb48 100644
--- a/TNodeGraphViewImpl/Editor/Cache/NodeEditorExtensions.cs
+++ b/TNodeGraphViewImpl/Editor/Cache/NodeEditorExtensions.cs
@@ -18,8 +18,7 @@ namespace TNodeGraphViewImpl.Editor.Cache{
/// Internal singleton class for caching TNode reflection Data.
///
internal class NodeEditorTypeDictionary:Dictionary{
- private class NodeEditorTypeDictionaryComparer : IEqualityComparer
- {
+ private class NodeEditorTypeDictionaryComparer : IEqualityComparer{
public bool Equals(Type x, Type y){
return x?.ToString() == y?.ToString();
}
@@ -28,11 +27,9 @@ namespace TNodeGraphViewImpl.Editor.Cache{
return obj.ToString().GetHashCode();
}
}
-
public NodeEditorTypeDictionary():base(new NodeEditorTypeDictionaryComparer()){
}
-
}
internal class NodeEditorSingleton{
@@ -132,6 +129,10 @@ namespace TNodeGraphViewImpl.Editor.Cache{
var instance = (T)Activator.CreateInstance(implementedType);
return instance;
}
+ public static string GetTypeCategory(Type type){
+ var category = type.GetCustomAttribute();
+ return category?.Category ?? "";
+ }
///
/// by given a generic type t,return the implementation instance of the generic type
@@ -190,6 +191,13 @@ namespace TNodeGraphViewImpl.Editor.Cache{
}
return new List();
}
+
+ public static List GetGraphCategories(Type t){
+ var list = NodeEditorSingleton.Instance.GraphDataUsage[t];
+ //Merge same category
+ var res = list.Select(x=>x.GetCustomAttribute().Category).Distinct().ToList();
+ return res;
+ }
public static BlackboardData GetAppropriateBlackboardData(Type t){
if (NodeEditorSingleton.Instance.GraphBlackboard.ContainsKey(t)){
return (BlackboardData)Activator.CreateInstance(NodeEditorSingleton.Instance.GraphBlackboard[t]);
diff --git a/TNodeGraphViewImpl/Editor/GraphBlackboard/BlackboardField.cs b/TNodeGraphViewImpl/Editor/GraphBlackboard/BlackboardField.cs
index 93470ef..e37882f 100644
--- a/TNodeGraphViewImpl/Editor/GraphBlackboard/BlackboardField.cs
+++ b/TNodeGraphViewImpl/Editor/GraphBlackboard/BlackboardField.cs
@@ -1,9 +1,9 @@
using UnityEditor.Experimental.GraphView;
namespace TNodeGraphViewImpl.Editor.GraphBlackboard{
- public class BlackboardPropertyField:BlackboardField{
+ public class BlackboardField:UnityEditor.Experimental.GraphView.BlackboardField{
public BlackboardProperty.BlackboardProperty BlackboardProperty;
- public BlackboardPropertyField(BlackboardProperty.BlackboardProperty blackboardProperty):base(null,blackboardProperty.PropertyName,null){
+ public BlackboardField(BlackboardProperty.BlackboardProperty blackboardProperty):base(null,blackboardProperty.PropertyName,null){
BlackboardProperty = blackboardProperty;
}
diff --git a/TNodeGraphViewImpl/Editor/GraphBlackboard/DefaultGraphBlackboardView.cs b/TNodeGraphViewImpl/Editor/GraphBlackboard/DefaultGraphBlackboardView.cs
index 129d9ea..499bc5c 100644
--- a/TNodeGraphViewImpl/Editor/GraphBlackboard/DefaultGraphBlackboardView.cs
+++ b/TNodeGraphViewImpl/Editor/GraphBlackboard/DefaultGraphBlackboardView.cs
@@ -30,7 +30,7 @@ namespace TNodeGraphViewImpl.Editor.GraphBlackboard{
//skip if the field is a list or Ilist
if (!typeof(IList).IsAssignableFrom(field.FieldType)){
VisualElement visualElement = new VisualElement();
- var propertyField = new BlackboardPropertyField(new BlackboardProperty.BlackboardProperty(field.Name,field.FieldType));
+ var propertyField = new BlackboardField(new BlackboardProperty.BlackboardProperty(field.Name,field.FieldType));
var foldoutData = new Foldout{
text = field.Name
};
diff --git a/TNodeGraphViewImpl/Editor/NodeGraphView/DataGraphView.cs b/TNodeGraphViewImpl/Editor/NodeGraphView/DataGraphView.cs
index 216cb24..fcab94f 100644
--- a/TNodeGraphViewImpl/Editor/NodeGraphView/DataGraphView.cs
+++ b/TNodeGraphViewImpl/Editor/NodeGraphView/DataGraphView.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Reflection;
using TNode.Editor.Inspector;
using TNode.Editor.Search;
using TNodeCore.Editor.Blackboard;
@@ -12,13 +13,12 @@ using TNodeCore.Runtime;
using TNodeGraphViewImpl.Editor.Cache;
using TNodeGraphViewImpl.Editor.GraphBlackboard;
using TNodeGraphViewImpl.Editor.NodeViews;
+using TNodeGraphViewImpl.Editor.Search;
using UnityEditor;
using UnityEditor.Experimental.GraphView;
using UnityEngine;
using UnityEngine.UIElements;
-
-
-
+using BlackboardField = TNodeGraphViewImpl.Editor.GraphBlackboard.BlackboardField;
using Edge = UnityEditor.Experimental.GraphView.Edge;
namespace TNodeGraphViewImpl.Editor.NodeGraphView{
@@ -216,12 +216,12 @@ namespace TNodeGraphViewImpl.Editor.NodeGraphView{
private void OnDragPerform(DragPerformEvent evt){
if (DragAndDrop.GetGenericData("DragSelection") is List{Count: > 0} data){
- var blackboardFields = data.OfType();
+ var blackboardFields = data.OfType();
foreach (var selectable in blackboardFields){
if(selectable is { } field) {
//Make a constructor of BlackboardDragNodeData by reflection
var dragNodeData = NodeCreator.InstantiateNodeData();
- dragNodeData.blackboardData = GetBlackboardData();
+ dragNodeData.BlackboardData = GetBlackboardData();
dragNodeData.blackDragData = field.BlackboardProperty.PropertyName;
AddTNode(dragNodeData,new Rect(evt.mousePosition,new Vector2(200,200)));
}
@@ -231,17 +231,11 @@ namespace TNodeGraphViewImpl.Editor.NodeGraphView{
}
private void OnDragUpdated(DragUpdatedEvent evt){
-
//check if the drag data is BlackboardField
-
if (DragAndDrop.GetGenericData("DragSelection") is List{Count: > 0} data){
DragAndDrop.visualMode = DragAndDropVisualMode.Move;
-
}
-
-
}
-
#endregion
@@ -263,10 +257,12 @@ namespace TNodeGraphViewImpl.Editor.NodeGraphView{
//Get the node type
var nodeType = dataNode.GetType();
//Get the derived type of NodeAttribute View from the node type
-
+ if (dataNode is RuntimeNodeData runtimeNodeData){
+ runtimeNodeData.BlackboardData = GetBlackboardData();
+ }
var nodePos = Owner.graphEditorData.graphElementsData.
FirstOrDefault(x => x.guid == dataNode.id)?.pos??new Rect(0,0,200,200);
-
+
AddTNode(dataNode,nodePos);
}
@@ -403,10 +399,20 @@ namespace TNodeGraphViewImpl.Editor.NodeGraphView{
_data.blackboardData = NodeEditorExtensions.GetAppropriateBlackboardData(_data.GetType());
}
}
-
-
+ //TODO:Handling implicit conversion when two port types are different but compatible
+ private static bool HasImplicitConversion(Type baseType, Type targetType)
+ {
+ return baseType.GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .Where(mi => mi.Name == "op_Implicit" && mi.ReturnType == targetType)
+ .Any(mi => {
+ ParameterInfo pi = mi.GetParameters().FirstOrDefault();
+ return pi != null && pi.ParameterType == baseType;
+ });
+ }
public override List GetCompatiblePorts(Port startPort, NodeAdapter nodeAdapter){
- return ports.Where(x => x.portType == startPort.portType || x.portType.IsAssignableFrom(startPort.portType)).ToList();
+
+ return ports.Where(x => startPort!=x && (x.portType == startPort.portType || x.portType.IsAssignableFrom(startPort.portType))).ToList();
+
}
public virtual void OnGraphViewCreate(){
diff --git a/TNodeGraphViewImpl/Editor/NodeViews/DragNodeView.cs b/TNodeGraphViewImpl/Editor/NodeViews/DragNodeView.cs
index 8bce179..35ca0b0 100644
--- a/TNodeGraphViewImpl/Editor/NodeViews/DragNodeView.cs
+++ b/TNodeGraphViewImpl/Editor/NodeViews/DragNodeView.cs
@@ -1,6 +1,13 @@
using TNodeCore.Attribute;
+using TNodeCore.Editor.Serialization;
using TNodeCore.Models;
using TNodeGraphViewImpl.Editor.NodeViews;
+using UnityEditor;
+using UnityEditor.Experimental.GraphView;
+using UnityEditor.Graphs;
+using UnityEditor.UIElements;
+using UnityEngine;
+using UnityEngine.UIElements;
namespace TNode.Editor.NodeViews{
[ViewComponent]
@@ -8,6 +15,26 @@ namespace TNode.Editor.NodeViews{
public DragBaseNodeView() : base(){
this.titleContainer.visible = false;
this.titleContainer.RemoveFromHierarchy();
+ this.OnDataChanged += OnDataChangedHandler;
+ }
+
+ private void OnDataChangedHandler(BlackboardDragNodeData obj){
+ var port = this.Q();
+ var label = port.Q