From 9c5a734ad70114513f9fc59ea009a904285da4db Mon Sep 17 00:00:00 2001 From: taoria <445625470@qq.com> Date: Thu, 4 Aug 2022 16:28:58 +0800 Subject: [PATCH 1/4] refactor:rename [ShowInNodeView] Attribute to [ShowInNode] and start to make a better graph creator tool --- TNode/GraphCreator.meta | 3 +++ TNode/GraphCreator/Editor.meta | 3 +++ TNode/GraphCreator/Editor/GraphCreator.cs | 7 +++++++ TNode/GraphCreator/Editor/GraphCreator.cs.meta | 3 +++ TNode/GraphCreator/Runtime.meta | 3 +++ TNode/GraphCreator/Runtime/Blackboard.meta | 3 +++ .../Runtime/Blackboard/GraphMetaBlackboard.cs | 9 +++++++++ .../Blackboard/GraphMetaBlackboard.cs.meta | 3 +++ TNode/GraphCreator/Runtime/GraphMetaNode.cs | 1 + .../GraphCreator/Runtime/GraphMetaNode.cs.meta | 3 +++ TNode/GraphCreator/Runtime/MetaGraph.cs | 6 ++++++ TNode/GraphCreator/Runtime/MetaGraph.cs.meta | 3 +++ TNode/GraphCreator/Runtime/Nodes.meta | 3 +++ .../GraphCreator/Runtime/Nodes/GraphMetaNode.cs | 17 +++++++++++++++++ .../Runtime/Nodes/GraphMetaNode.cs.meta | 3 +++ TNode/TNodeCore/Editor/GraphCreatorEditor.cs | 8 ++++++++ .../TNodeCore/Editor/GraphCreatorEditor.cs.meta | 3 +++ ...ShowInNodeViewAttribute.cs => ShowInNode.cs} | 2 +- ...ViewAttribute.cs.meta => ShowInNode.cs.meta} | 0 .../Editor/Inspector/NodeInspectorInNode.cs | 2 +- 20 files changed, 83 insertions(+), 2 deletions(-) create mode 100644 TNode/GraphCreator.meta create mode 100644 TNode/GraphCreator/Editor.meta create mode 100644 TNode/GraphCreator/Editor/GraphCreator.cs create mode 100644 TNode/GraphCreator/Editor/GraphCreator.cs.meta create mode 100644 TNode/GraphCreator/Runtime.meta create mode 100644 TNode/GraphCreator/Runtime/Blackboard.meta create mode 100644 TNode/GraphCreator/Runtime/Blackboard/GraphMetaBlackboard.cs create mode 100644 TNode/GraphCreator/Runtime/Blackboard/GraphMetaBlackboard.cs.meta create mode 100644 TNode/GraphCreator/Runtime/GraphMetaNode.cs create mode 100644 TNode/GraphCreator/Runtime/GraphMetaNode.cs.meta create mode 100644 TNode/GraphCreator/Runtime/MetaGraph.cs create mode 100644 TNode/GraphCreator/Runtime/MetaGraph.cs.meta create mode 100644 TNode/GraphCreator/Runtime/Nodes.meta create mode 100644 TNode/GraphCreator/Runtime/Nodes/GraphMetaNode.cs create mode 100644 TNode/GraphCreator/Runtime/Nodes/GraphMetaNode.cs.meta create mode 100644 TNode/TNodeCore/Editor/GraphCreatorEditor.cs create mode 100644 TNode/TNodeCore/Editor/GraphCreatorEditor.cs.meta rename TNode/TNodeCore/Runtime/Attributes/{ShowInNodeViewAttribute.cs => ShowInNode.cs} (72%) rename TNode/TNodeCore/Runtime/Attributes/{ShowInNodeViewAttribute.cs.meta => ShowInNode.cs.meta} (100%) diff --git a/TNode/GraphCreator.meta b/TNode/GraphCreator.meta new file mode 100644 index 0000000..ba7ab38 --- /dev/null +++ b/TNode/GraphCreator.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: b880945b54834ff892ab441f95ebf64a +timeCreated: 1659601013 \ No newline at end of file diff --git a/TNode/GraphCreator/Editor.meta b/TNode/GraphCreator/Editor.meta new file mode 100644 index 0000000..f7c19cb --- /dev/null +++ b/TNode/GraphCreator/Editor.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 088ae3752f0e44ad91bf019cc64536fc +timeCreated: 1659601180 \ No newline at end of file diff --git a/TNode/GraphCreator/Editor/GraphCreator.cs b/TNode/GraphCreator/Editor/GraphCreator.cs new file mode 100644 index 0000000..3d407ee --- /dev/null +++ b/TNode/GraphCreator/Editor/GraphCreator.cs @@ -0,0 +1,7 @@ +using TNodeCore.Editor; + +namespace TNode.GraphCreator.Editor{ + public class GraphCreator:GraphEditor{ + + } +} \ No newline at end of file diff --git a/TNode/GraphCreator/Editor/GraphCreator.cs.meta b/TNode/GraphCreator/Editor/GraphCreator.cs.meta new file mode 100644 index 0000000..154b52a --- /dev/null +++ b/TNode/GraphCreator/Editor/GraphCreator.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: b727fc33cca34734bff028a952645808 +timeCreated: 1659601005 \ No newline at end of file diff --git a/TNode/GraphCreator/Runtime.meta b/TNode/GraphCreator/Runtime.meta new file mode 100644 index 0000000..54ae4bd --- /dev/null +++ b/TNode/GraphCreator/Runtime.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: e10ab803f7cf4762b5e72874dc3a69a0 +timeCreated: 1659601201 \ No newline at end of file diff --git a/TNode/GraphCreator/Runtime/Blackboard.meta b/TNode/GraphCreator/Runtime/Blackboard.meta new file mode 100644 index 0000000..e9c39d9 --- /dev/null +++ b/TNode/GraphCreator/Runtime/Blackboard.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 3a0683e43c164065927b50fc72d9065c +timeCreated: 1659601323 \ No newline at end of file diff --git a/TNode/GraphCreator/Runtime/Blackboard/GraphMetaBlackboard.cs b/TNode/GraphCreator/Runtime/Blackboard/GraphMetaBlackboard.cs new file mode 100644 index 0000000..77fc56b --- /dev/null +++ b/TNode/GraphCreator/Runtime/Blackboard/GraphMetaBlackboard.cs @@ -0,0 +1,9 @@ +using TNodeCore.Editor.EditorPersistence; +using TNodeCore.Runtime.Models; + +namespace TNode.GraphCreator.Runtime.Blackboard{ + public class GraphMetaBlackboard:BlackboardData{ + + + } +} \ No newline at end of file diff --git a/TNode/GraphCreator/Runtime/Blackboard/GraphMetaBlackboard.cs.meta b/TNode/GraphCreator/Runtime/Blackboard/GraphMetaBlackboard.cs.meta new file mode 100644 index 0000000..34c15a3 --- /dev/null +++ b/TNode/GraphCreator/Runtime/Blackboard/GraphMetaBlackboard.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 33c75ee828f4484abbe9009859357182 +timeCreated: 1659601335 \ No newline at end of file diff --git a/TNode/GraphCreator/Runtime/GraphMetaNode.cs b/TNode/GraphCreator/Runtime/GraphMetaNode.cs new file mode 100644 index 0000000..5f28270 --- /dev/null +++ b/TNode/GraphCreator/Runtime/GraphMetaNode.cs @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/TNode/GraphCreator/Runtime/GraphMetaNode.cs.meta b/TNode/GraphCreator/Runtime/GraphMetaNode.cs.meta new file mode 100644 index 0000000..12301c7 --- /dev/null +++ b/TNode/GraphCreator/Runtime/GraphMetaNode.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: e4bc602c13c042819a553d6142faf3ba +timeCreated: 1659601223 \ No newline at end of file diff --git a/TNode/GraphCreator/Runtime/MetaGraph.cs b/TNode/GraphCreator/Runtime/MetaGraph.cs new file mode 100644 index 0000000..61e8d3c --- /dev/null +++ b/TNode/GraphCreator/Runtime/MetaGraph.cs @@ -0,0 +1,6 @@ +using TNodeCore.Runtime.Models; + +namespace TNode.GraphCreator.Editor{ + public class MetaGraph : GraphData{ + } +} \ No newline at end of file diff --git a/TNode/GraphCreator/Runtime/MetaGraph.cs.meta b/TNode/GraphCreator/Runtime/MetaGraph.cs.meta new file mode 100644 index 0000000..cf1d517 --- /dev/null +++ b/TNode/GraphCreator/Runtime/MetaGraph.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: e0047d8d81f646128eab9c94957129f4 +timeCreated: 1659601169 \ No newline at end of file diff --git a/TNode/GraphCreator/Runtime/Nodes.meta b/TNode/GraphCreator/Runtime/Nodes.meta new file mode 100644 index 0000000..13eef7b --- /dev/null +++ b/TNode/GraphCreator/Runtime/Nodes.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: a54e22f7a85c4befbf19d09e14259869 +timeCreated: 1659601272 \ No newline at end of file diff --git a/TNode/GraphCreator/Runtime/Nodes/GraphMetaNode.cs b/TNode/GraphCreator/Runtime/Nodes/GraphMetaNode.cs new file mode 100644 index 0000000..6accd68 --- /dev/null +++ b/TNode/GraphCreator/Runtime/Nodes/GraphMetaNode.cs @@ -0,0 +1,17 @@ +using System; +using TNode.GraphCreator.Editor; +using TNodeCore.Runtime.Attributes; + +namespace TNode.GraphCreator.Runtime.Nodes{ + using TNodeCore.Runtime.Models; + + namespace TNode.GraphCreator.Runtime{ + [GraphUsage(typeof(MetaGraph))] + [Serializable] + public class GraphMetaNode:NodeData{ + [ShowInNode] + public string createNodeName; + + } + } +} \ No newline at end of file diff --git a/TNode/GraphCreator/Runtime/Nodes/GraphMetaNode.cs.meta b/TNode/GraphCreator/Runtime/Nodes/GraphMetaNode.cs.meta new file mode 100644 index 0000000..fc03282 --- /dev/null +++ b/TNode/GraphCreator/Runtime/Nodes/GraphMetaNode.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 3f00e9ec34ac442da5e7b7b21042e37b +timeCreated: 1659601280 \ No newline at end of file diff --git a/TNode/TNodeCore/Editor/GraphCreatorEditor.cs b/TNode/TNodeCore/Editor/GraphCreatorEditor.cs new file mode 100644 index 0000000..6839b2a --- /dev/null +++ b/TNode/TNodeCore/Editor/GraphCreatorEditor.cs @@ -0,0 +1,8 @@ +using UnityEditor; + +namespace TNodeCore.Editor{ + public class GraphCreatorEditor:EditorWindow{ + + + } +} \ No newline at end of file diff --git a/TNode/TNodeCore/Editor/GraphCreatorEditor.cs.meta b/TNode/TNodeCore/Editor/GraphCreatorEditor.cs.meta new file mode 100644 index 0000000..6f01de2 --- /dev/null +++ b/TNode/TNodeCore/Editor/GraphCreatorEditor.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 059e73589b764d7db8e53b75c86d634d +timeCreated: 1659600695 \ No newline at end of file diff --git a/TNode/TNodeCore/Runtime/Attributes/ShowInNodeViewAttribute.cs b/TNode/TNodeCore/Runtime/Attributes/ShowInNode.cs similarity index 72% rename from TNode/TNodeCore/Runtime/Attributes/ShowInNodeViewAttribute.cs rename to TNode/TNodeCore/Runtime/Attributes/ShowInNode.cs index 405c6e8..43eae09 100644 --- a/TNode/TNodeCore/Runtime/Attributes/ShowInNodeViewAttribute.cs +++ b/TNode/TNodeCore/Runtime/Attributes/ShowInNode.cs @@ -3,7 +3,7 @@ namespace TNodeCore.Runtime.Attributes{ [AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = false)] - public class ShowInNodeViewAttribute:System.Attribute{ + public class ShowInNode:System.Attribute{ } } \ No newline at end of file diff --git a/TNode/TNodeCore/Runtime/Attributes/ShowInNodeViewAttribute.cs.meta b/TNode/TNodeCore/Runtime/Attributes/ShowInNode.cs.meta similarity index 100% rename from TNode/TNodeCore/Runtime/Attributes/ShowInNodeViewAttribute.cs.meta rename to TNode/TNodeCore/Runtime/Attributes/ShowInNode.cs.meta diff --git a/TNode/TNodeGraphViewImpl/Editor/Inspector/NodeInspectorInNode.cs b/TNode/TNodeGraphViewImpl/Editor/Inspector/NodeInspectorInNode.cs index 66eb4f9..a8ce005 100644 --- a/TNode/TNodeGraphViewImpl/Editor/Inspector/NodeInspectorInNode.cs +++ b/TNode/TNodeGraphViewImpl/Editor/Inspector/NodeInspectorInNode.cs @@ -46,7 +46,7 @@ namespace TNode.TNodeGraphViewImpl.Editor.Inspector{ foreach (var field in _data.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public|BindingFlags.NonPublic)){ //Create corresponding property field //check if the field has ShowInNodeView attribute - var showInNodeViewAttribute = field.GetCustomAttribute() != null; + var showInNodeViewAttribute = field.GetCustomAttribute() != null; if (!showInNodeViewAttribute) continue; var drawer = new PropertyField(serializedObject.FindProperty("data").FindPropertyRelative(field.Name)); From 2d1bd4ba1a75ffe7f8e4f3f103140dcb128103b5 Mon Sep 17 00:00:00 2001 From: taoria <445625470@qq.com> Date: Fri, 5 Aug 2022 17:46:17 +0800 Subject: [PATCH 2/4] feature:port color support --- TNode/GraphCreator/Editor/GraphCreator.cs | 3 +- TNode/GraphCreator/Runtime/MetaGraph.cs | 2 +- .../Runtime/Nodes/GraphMetaNode.cs | 1 - .../EditorPersistence/GraphEditorData.cs | 2 -- .../ScriptTemplates/ExampleGraph.cs.txt | 4 +++ .../ScriptTemplates/ExampleGraph.cs.txt.meta | 3 ++ .../Resources/ScriptTemplates/NewGraph.cs.txt | 5 ++- .../ScriptTemplates/NewGraphEditor.cs.txt | 33 ++++++++++-------- .../GraphEditorCreator/GraphEditorCreator.cs | 8 ++--- .../Runtime/Attributes/ModelColor.cs | 5 --- .../TNodeCore/Runtime/Attributes/PortColor.cs | 17 ++++++++++ .../{ModelColor.cs.meta => PortColor.cs.meta} | 0 TNode/TNodeCore/Runtime/Logger.meta | 3 ++ .../Runtime/{ => Logger}/NodeLogger.cs | 0 .../Runtime/{ => Logger}/NodeLogger.cs.meta | 0 .../Editor/Cache/NodeEditorExtensions.cs | 4 +++ .../GraphBlackboard/BlackboardDataEntry.cs | 26 +++++++------- .../Editor/NodeViews/NodeView.cs | 34 +++++++++++-------- .../Editor/Resources/BlackboardDataEntry.uss | 16 +++++++-- 19 files changed, 103 insertions(+), 63 deletions(-) create mode 100644 TNode/TNodeCore/Editor/Resources/ScriptTemplates/ExampleGraph.cs.txt create mode 100644 TNode/TNodeCore/Editor/Resources/ScriptTemplates/ExampleGraph.cs.txt.meta delete mode 100644 TNode/TNodeCore/Runtime/Attributes/ModelColor.cs create mode 100644 TNode/TNodeCore/Runtime/Attributes/PortColor.cs rename TNode/TNodeCore/Runtime/Attributes/{ModelColor.cs.meta => PortColor.cs.meta} (100%) create mode 100644 TNode/TNodeCore/Runtime/Logger.meta rename TNode/TNodeCore/Runtime/{ => Logger}/NodeLogger.cs (100%) rename TNode/TNodeCore/Runtime/{ => Logger}/NodeLogger.cs.meta (100%) diff --git a/TNode/GraphCreator/Editor/GraphCreator.cs b/TNode/GraphCreator/Editor/GraphCreator.cs index 3d407ee..18a3656 100644 --- a/TNode/GraphCreator/Editor/GraphCreator.cs +++ b/TNode/GraphCreator/Editor/GraphCreator.cs @@ -1,4 +1,5 @@ -using TNodeCore.Editor; +using TNode.GraphCreator.Runtime; +using TNodeCore.Editor; namespace TNode.GraphCreator.Editor{ public class GraphCreator:GraphEditor{ diff --git a/TNode/GraphCreator/Runtime/MetaGraph.cs b/TNode/GraphCreator/Runtime/MetaGraph.cs index 61e8d3c..3f0c953 100644 --- a/TNode/GraphCreator/Runtime/MetaGraph.cs +++ b/TNode/GraphCreator/Runtime/MetaGraph.cs @@ -1,6 +1,6 @@ using TNodeCore.Runtime.Models; -namespace TNode.GraphCreator.Editor{ +namespace TNode.GraphCreator.Runtime{ public class MetaGraph : GraphData{ } } \ No newline at end of file diff --git a/TNode/GraphCreator/Runtime/Nodes/GraphMetaNode.cs b/TNode/GraphCreator/Runtime/Nodes/GraphMetaNode.cs index 6accd68..4b4241a 100644 --- a/TNode/GraphCreator/Runtime/Nodes/GraphMetaNode.cs +++ b/TNode/GraphCreator/Runtime/Nodes/GraphMetaNode.cs @@ -1,5 +1,4 @@ using System; -using TNode.GraphCreator.Editor; using TNodeCore.Runtime.Attributes; namespace TNode.GraphCreator.Runtime.Nodes{ diff --git a/TNode/TNodeCore/Editor/EditorPersistence/GraphEditorData.cs b/TNode/TNodeCore/Editor/EditorPersistence/GraphEditorData.cs index 10414d7..5f5f5ac 100644 --- a/TNode/TNodeCore/Editor/EditorPersistence/GraphEditorData.cs +++ b/TNode/TNodeCore/Editor/EditorPersistence/GraphEditorData.cs @@ -23,8 +23,6 @@ namespace TNodeCore.Editor.EditorPersistence{ return (IDataGraphView)GraphViewImplCreator.Invoke(typeof(T)); } - - case GraphImplType.GraphToolsFoundationImpl: throw new NotImplementedException(); default: diff --git a/TNode/TNodeCore/Editor/Resources/ScriptTemplates/ExampleGraph.cs.txt b/TNode/TNodeCore/Editor/Resources/ScriptTemplates/ExampleGraph.cs.txt new file mode 100644 index 0000000..4c1f292 --- /dev/null +++ b/TNode/TNodeCore/Editor/Resources/ScriptTemplates/ExampleGraph.cs.txt @@ -0,0 +1,4 @@ + +public class Example$GraphClassName$Node:NodeData{ + +} diff --git a/TNode/TNodeCore/Editor/Resources/ScriptTemplates/ExampleGraph.cs.txt.meta b/TNode/TNodeCore/Editor/Resources/ScriptTemplates/ExampleGraph.cs.txt.meta new file mode 100644 index 0000000..a6ca584 --- /dev/null +++ b/TNode/TNodeCore/Editor/Resources/ScriptTemplates/ExampleGraph.cs.txt.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 608d45120d7a4f5ca5091a1427d8843a +timeCreated: 1659602294 \ No newline at end of file diff --git a/TNode/TNodeCore/Editor/Resources/ScriptTemplates/NewGraph.cs.txt b/TNode/TNodeCore/Editor/Resources/ScriptTemplates/NewGraph.cs.txt index 913d60c..112aa49 100644 --- a/TNode/TNodeCore/Editor/Resources/ScriptTemplates/NewGraph.cs.txt +++ b/TNode/TNodeCore/Editor/Resources/ScriptTemplates/NewGraph.cs.txt @@ -1,7 +1,6 @@ -using TNode.Models; -using UnityEngine; -using UnityEditor; +using UnityEngine; using System; +using TNodeCore.Runtime.Models; [CreateAssetMenu(fileName = "New $GraphClassName$", menuName = "TNode/$GraphClassName$")] [Serializable] public class $GraphClassName$ : GraphData{ diff --git a/TNode/TNodeCore/Editor/Resources/ScriptTemplates/NewGraphEditor.cs.txt b/TNode/TNodeCore/Editor/Resources/ScriptTemplates/NewGraphEditor.cs.txt index 1f5ad7e..c8f187e 100644 --- a/TNode/TNodeCore/Editor/Resources/ScriptTemplates/NewGraphEditor.cs.txt +++ b/TNode/TNodeCore/Editor/Resources/ScriptTemplates/NewGraphEditor.cs.txt @@ -1,22 +1,25 @@ -using TNode.Editor; -using UnityEditor; +using UnityEditor; using UnityEditor.Callbacks; -using UnityEditor.Experimental.GraphView; using UnityEngine; -using UnityEngine.UIElements; -using System; +using TNodeCore.Editor; public class $EditorClassName$ : GraphEditor<$GraphClassName$>{ [OnOpenAsset] public static bool OnOpenAsset(int instanceID, int line){ - var graph = EditorUtility.InstanceIDToObject(instanceID) as $GraphClassName$; - if (graph != null) - { - var wnd = GetWindow<$EditorClassName$>(); - wnd.titleContent = new GUIContent("$GraphClassName$ Editor"); - wnd.CreateGUI(); - wnd._graphView.Data = graph; - return true; - } - return false; + var graph = EditorUtility.InstanceIDToObject(instanceID) as $GraphClassName$; + if (graph != null) { + var wnd = GetWindow<$EditorClassName$>(); + wnd.titleContent = new GUIContent("$GraphClassName$ Editor"); + wnd.Show(); + wnd.SetupNonRuntime(graph); + return true; + } + return false; } + [MenuItem("Window/$EditorClassName$")] + public static void ShowWindow(){ + var res = GetWindow<$EditorClassName$>(); + res.titleContent = new GUIContent("$GraphClassName$ Editor"); + res.Show(); + } + } \ No newline at end of file diff --git a/TNode/TNodeCore/Editor/Tools/GraphEditorCreator/GraphEditorCreator.cs b/TNode/TNodeCore/Editor/Tools/GraphEditorCreator/GraphEditorCreator.cs index 0d166b1..c845d76 100644 --- a/TNode/TNodeCore/Editor/Tools/GraphEditorCreator/GraphEditorCreator.cs +++ b/TNode/TNodeCore/Editor/Tools/GraphEditorCreator/GraphEditorCreator.cs @@ -26,7 +26,7 @@ namespace TNodeCore.Editor.Tools.GraphEditorCreator{ GraphEditorCreator wnd = GetWindow(); wnd.titleContent = new GUIContent("GraphEditorCreator"); //Set position to the center of the screen - wnd.position = new(Screen.width / 2, Screen.height / 2, 500, 300); + wnd.position = new(Screen.width / 2.0f, Screen.height / 2.0f, 500, 300); //set this window non resizable wnd.minSize = new Vector2(500, 300); wnd.maxSize = new Vector2(500, 300); @@ -125,13 +125,13 @@ namespace TNodeCore.Editor.Tools.GraphEditorCreator{ var source = _sourceGeneratorForGraphEditor.GenerateGraphEditor(editorName, graphName); var sourceGraph = _sourceGeneratorForGraphEditor.GenerateGraph(graphName); - var sourceGraphView = _sourceGeneratorForGraphEditor.GenerateGraphView(graphViewName, graphName); + //var sourceGraphView = _sourceGeneratorForGraphEditor.GenerateGraphView(graphViewName, graphName); string editorPath = Path.Combine(path, editorName + ".cs"); string graphPath = Path.Combine(pathBeforeEditor, graphName + ".cs"); - string graphViewPath = Path.Combine(path, graphViewName + ".cs"); + //string graphViewPath = Path.Combine(path, graphViewName + ".cs"); File.WriteAllText(editorPath, source); File.WriteAllText(graphPath, sourceGraph); - File.WriteAllText(graphViewPath, sourceGraphView); + //File.WriteAllText(graphViewPath, sourceGraphView); //Refresh the AssetDatabase to import the new file AssetDatabase.Refresh(); diff --git a/TNode/TNodeCore/Runtime/Attributes/ModelColor.cs b/TNode/TNodeCore/Runtime/Attributes/ModelColor.cs deleted file mode 100644 index ae7106c..0000000 --- a/TNode/TNodeCore/Runtime/Attributes/ModelColor.cs +++ /dev/null @@ -1,5 +0,0 @@ -namespace TNodeCore.Runtime.Attributes{ - public class ModelColor{ - - } -} \ No newline at end of file diff --git a/TNode/TNodeCore/Runtime/Attributes/PortColor.cs b/TNode/TNodeCore/Runtime/Attributes/PortColor.cs new file mode 100644 index 0000000..998f75b --- /dev/null +++ b/TNode/TNodeCore/Runtime/Attributes/PortColor.cs @@ -0,0 +1,17 @@ +using System; +using UnityEngine; + +namespace TNodeCore.Runtime.Attributes{ + /// + /// this attribute only works on implemented types + /// + public class PortColorAttribute : Attribute{ + public Color Color; + public PortColorAttribute(float r, float g, float b){ + Color = new Color(r, g, b); + } + public PortColorAttribute(int r, int g,int b){ + Color = new Color(r/255.0f, g/255.0f, b/255.0f); + } + } +} \ No newline at end of file diff --git a/TNode/TNodeCore/Runtime/Attributes/ModelColor.cs.meta b/TNode/TNodeCore/Runtime/Attributes/PortColor.cs.meta similarity index 100% rename from TNode/TNodeCore/Runtime/Attributes/ModelColor.cs.meta rename to TNode/TNodeCore/Runtime/Attributes/PortColor.cs.meta diff --git a/TNode/TNodeCore/Runtime/Logger.meta b/TNode/TNodeCore/Runtime/Logger.meta new file mode 100644 index 0000000..841905b --- /dev/null +++ b/TNode/TNodeCore/Runtime/Logger.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: f70fd0a222b9459093dff6c2b0679c3c +timeCreated: 1659682655 \ No newline at end of file diff --git a/TNode/TNodeCore/Runtime/NodeLogger.cs b/TNode/TNodeCore/Runtime/Logger/NodeLogger.cs similarity index 100% rename from TNode/TNodeCore/Runtime/NodeLogger.cs rename to TNode/TNodeCore/Runtime/Logger/NodeLogger.cs diff --git a/TNode/TNodeCore/Runtime/NodeLogger.cs.meta b/TNode/TNodeCore/Runtime/Logger/NodeLogger.cs.meta similarity index 100% rename from TNode/TNodeCore/Runtime/NodeLogger.cs.meta rename to TNode/TNodeCore/Runtime/Logger/NodeLogger.cs.meta diff --git a/TNode/TNodeGraphViewImpl/Editor/Cache/NodeEditorExtensions.cs b/TNode/TNodeGraphViewImpl/Editor/Cache/NodeEditorExtensions.cs index 598fe9d..738cd85 100644 --- a/TNode/TNodeGraphViewImpl/Editor/Cache/NodeEditorExtensions.cs +++ b/TNode/TNodeGraphViewImpl/Editor/Cache/NodeEditorExtensions.cs @@ -84,6 +84,10 @@ namespace TNode.TNodeGraphViewImpl.Editor.Cache{ private IBaseDataGraphView GraphViewImplCreator(Type arg){ var genericType = typeof(BaseDataGraphView<>).MakeGenericType(arg); var instance = CreateViewComponentFromBaseType(genericType) as IBaseDataGraphView; + if (instance == null){ + //fallback to default graph view + instance = (IBaseDataGraphView) Activator.CreateInstance(genericType); + } return instance; } private void SetGraphUsageAttribute(Type type){ diff --git a/TNode/TNodeGraphViewImpl/Editor/GraphBlackboard/BlackboardDataEntry.cs b/TNode/TNodeGraphViewImpl/Editor/GraphBlackboard/BlackboardDataEntry.cs index b94a32f..3097e50 100644 --- a/TNode/TNodeGraphViewImpl/Editor/GraphBlackboard/BlackboardDataEntry.cs +++ b/TNode/TNodeGraphViewImpl/Editor/GraphBlackboard/BlackboardDataEntry.cs @@ -1,5 +1,6 @@ using System; -using System.Collections; +using System.Reflection; +using TNodeCore.Runtime.Attributes; using UnityEditor.Experimental.GraphView; using UnityEngine; using UnityEngine.UIElements; @@ -8,37 +9,34 @@ namespace TNode.TNodeGraphViewImpl.Editor.GraphBlackboard{ public class BlackboardDataEntry:GraphElement{ public Type propertyType; public string propertyPath; + private Color _convertedColor; public BlackboardDataEntry(Type type){ propertyType = type; if (typeof(Component).IsAssignableFrom(propertyType)){ this.AddToClassList("typeComponent"); - } - if (typeof(GameObject).IsAssignableFrom(propertyType)){ + }else if (typeof(GameObject).IsAssignableFrom(propertyType)){ this.AddToClassList("gameObject"); + }else{ + this.AddToClassList(propertyType.Name); } - if (typeof(Vector2).IsAssignableFrom(propertyType)){ - this.AddToClassList("vector"); - } - if (typeof(Vector2Int).IsAssignableFrom(propertyType)){ - this.AddToClassList("vector"); - } - if (typeof(IList).IsAssignableFrom(propertyType)){ - this.AddToClassList("list"); - } + + this.capabilities |= Capabilities.Selectable | Capabilities.Deletable | Capabilities.Droppable | Capabilities.Renamable; this.AddManipulator(new SelectionDropper()); var styleSheet = Resources.Load("BlackboardDataEntry"); this.styleSheets.Add(styleSheet); + if (type.GetCustomAttribute() is {} portColorAttribute){ + _convertedColor = portColorAttribute.Color; + } this.RegisterCallback((evt) => { style.borderBottomColor=style.borderRightColor=style.borderLeftColor=style.borderTopColor=new Color(1,1,1,1); }); this.RegisterCallback((evt) => { style.borderBottomColor = style.borderRightColor = - style.borderLeftColor = style.borderTopColor = StyleKeyword.Null; + style.borderLeftColor = style.borderTopColor = _convertedColor==default?StyleKeyword.Null:_convertedColor; }); - } } } \ No newline at end of file diff --git a/TNode/TNodeGraphViewImpl/Editor/NodeViews/NodeView.cs b/TNode/TNodeGraphViewImpl/Editor/NodeViews/NodeView.cs index a94b9cf..ccca056 100644 --- a/TNode/TNodeGraphViewImpl/Editor/NodeViews/NodeView.cs +++ b/TNode/TNodeGraphViewImpl/Editor/NodeViews/NodeView.cs @@ -6,6 +6,7 @@ using TNode.TNodeGraphViewImpl.Editor.Ports; using TNodeCore.Editor.NodeGraphView; using TNodeCore.Editor.Serialization; using TNodeCore.Runtime; +using TNodeCore.Runtime.Attributes; using TNodeCore.Runtime.Attributes.Ports; using TNodeCore.Runtime.Models; using UnityEditor; @@ -141,27 +142,31 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeViews{ Port port = new CustomPort(Orientation.Horizontal, Direction.Output, attribute.Multiple ? Port.Capacity.Multi : Port.Capacity.Single, BuildPortType(attribute, propertyInfo)); - - this.outputContainer.Add(port); - var portName = ObjectNames.NicifyVariableName(BuildPortName(attribute,propertyInfo)); - port.portName = portName; - port.name = propertyInfo.Name; + BuildPort(port, attribute, propertyInfo,outputContainer); } } 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; - + Port port = new CustomPort + (Orientation.Horizontal, + Direction.Input,attribute.Multiple?Port.Capacity.Multi: Port.Capacity.Single,BuildPortType(attribute,propertyInfo)); + BuildPort(port,attribute,propertyInfo,inputContainer); } } } + private void BuildPort(Port port, PortAttribute attribute, PropertyInfo propertyInfo,VisualElement portContainer){ + portContainer.Add(port); + var portName = ObjectNames.NicifyVariableName(BuildPortName(attribute, propertyInfo)); + port.portName = portName; + port.name = propertyInfo.Name; + var colorAtt = propertyInfo.PropertyType.GetCustomAttribute(); + if (colorAtt != null){ + var color = colorAtt.Color; + port.portColor = color; + } + } + public void StartARenameTitleTextField(){ var textField = new TextField{ value = title, @@ -220,8 +225,7 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeViews{ 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; + _data.positionInView.position = newPos.position; base.SetPosition(newPos); } diff --git a/TNode/TNodeGraphViewImpl/Editor/Resources/BlackboardDataEntry.uss b/TNode/TNodeGraphViewImpl/Editor/Resources/BlackboardDataEntry.uss index e0ad638..b51fec5 100644 --- a/TNode/TNodeGraphViewImpl/Editor/Resources/BlackboardDataEntry.uss +++ b/TNode/TNodeGraphViewImpl/Editor/Resources/BlackboardDataEntry.uss @@ -6,7 +6,19 @@ border-width: 1px; border-color: rgba(201, 249, 116, 255); } -.vector{ +.Int32{ border-width: 1px; - border-color: rgba(0.788, 0.969, 0.455, 1.000); + border-color: rgba(148,130,230,255); +} +.Float{ + border-width: 1px; + border-color: aquamarine; +} +.System32{ + border-width: 1px; + border-color: aquamarine; +} +.String{ + border-width: 1px; + border-color: crimson; } \ No newline at end of file From 8bdc6afbb3a3332be63a8b6c2f74577a2bf9b6aa Mon Sep 17 00:00:00 2001 From: taoria <445625470@qq.com> Date: Fri, 5 Aug 2022 21:18:08 +0800 Subject: [PATCH 3/4] feature:Implicit conversion now supported --- README.md | 33 +++--- TNode/Samples.meta | 8 ++ TNode/Samples/Editor.meta | 8 ++ TNode/Samples/Editor/HelloEditor.asset | 17 +++ TNode/Samples/Editor/HelloEditor.asset.meta | 8 ++ TNode/Samples/Editor/HelloEditor.cs | 25 +++++ TNode/Samples/Editor/HelloEditor.cs.meta | 14 +++ TNode/Samples/HelloGraph.cs | 8 ++ TNode/Samples/HelloGraph.cs.meta | 11 ++ TNode/Samples/New HelloGraph.asset | 24 +++++ TNode/Samples/New HelloGraph.asset.meta | 8 ++ .../Runtime/Interfaces/IPortTypeConversion.cs | 5 + .../Runtime/RuntimeCache/RuntimeCache.cs | 101 ++++++++++++++++-- TNode/TNodeCore/Runtime/RuntimeNode.cs | 7 +- TNode/TNodeGtfImpl.meta | 8 ++ 15 files changed, 253 insertions(+), 32 deletions(-) create mode 100644 TNode/Samples.meta create mode 100644 TNode/Samples/Editor.meta create mode 100644 TNode/Samples/Editor/HelloEditor.asset create mode 100644 TNode/Samples/Editor/HelloEditor.asset.meta create mode 100644 TNode/Samples/Editor/HelloEditor.cs create mode 100644 TNode/Samples/Editor/HelloEditor.cs.meta create mode 100644 TNode/Samples/HelloGraph.cs create mode 100644 TNode/Samples/HelloGraph.cs.meta create mode 100644 TNode/Samples/New HelloGraph.asset create mode 100644 TNode/Samples/New HelloGraph.asset.meta create mode 100644 TNode/TNodeGtfImpl.meta diff --git a/README.md b/README.md index 20868e5..4f7ac3f 100644 --- a/README.md +++ b/README.md @@ -3,34 +3,29 @@ Node graph creation tool based on unity experimental graphview and if possible l 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 . - -The tool separate its graph editor implementation and the graph creation logic. - -# Install - -currently under development - # Some Features -* Create graph script a the creator tool -* Node creation based on specified type of graph +* creator tool create graph easily * 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 +* Scene object nodes hold scene objects like blackboard + +# Some to-dos +* Port connectivity of two types have implicit conversion +* Node placement +* Vertical node +* A universal merger handle multiple input +* Support static graph data traversal + +# Install & Usage +Right now this lib is still under development. + + -# Some To-dos -* Function as port -* Circular dependency support for some situations such as FSM -* Edge colors customization -# Usage -Not yet documented -### Convention diff --git a/TNode/Samples.meta b/TNode/Samples.meta new file mode 100644 index 0000000..102f2aa --- /dev/null +++ b/TNode/Samples.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: dc7f08d6196fcc24c97cf3b03543b697 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/TNode/Samples/Editor.meta b/TNode/Samples/Editor.meta new file mode 100644 index 0000000..5e4d0b6 --- /dev/null +++ b/TNode/Samples/Editor.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 15edfa2efedd3854c95e45fefd5caf48 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/TNode/Samples/Editor/HelloEditor.asset b/TNode/Samples/Editor/HelloEditor.asset new file mode 100644 index 0000000..d60be1a --- /dev/null +++ b/TNode/Samples/Editor/HelloEditor.asset @@ -0,0 +1,17 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 99ad0af56b40495cb6bd6165e652266c, type: 3} + m_Name: HelloEditor + m_EditorClassIdentifier: + graphElementsData: [] + graphImplType: 0 + autoUpdate: 0 diff --git a/TNode/Samples/Editor/HelloEditor.asset.meta b/TNode/Samples/Editor/HelloEditor.asset.meta new file mode 100644 index 0000000..0fd1ea2 --- /dev/null +++ b/TNode/Samples/Editor/HelloEditor.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 060ae44fcac9b534f9bdca3c3e5f1484 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/TNode/Samples/Editor/HelloEditor.cs b/TNode/Samples/Editor/HelloEditor.cs new file mode 100644 index 0000000..f7e4219 --- /dev/null +++ b/TNode/Samples/Editor/HelloEditor.cs @@ -0,0 +1,25 @@ +using UnityEditor; +using UnityEditor.Callbacks; +using UnityEngine; +using TNodeCore.Editor; +public class HelloEditor : GraphEditor{ + [OnOpenAsset] + public static bool OnOpenAsset(int instanceID, int line){ + var graph = EditorUtility.InstanceIDToObject(instanceID) as HelloGraph; + if (graph != null) { + var wnd = GetWindow(); + wnd.titleContent = new GUIContent("EasyGraph Editor"); + wnd.Show(); + wnd.SetupNonRuntime(graph); + return true; + } + return false; + } + [MenuItem("Window/HelloEditor")] + public static void ShowWindow(){ + var res = GetWindow(); + res.titleContent = new GUIContent("EasyGraph Editor"); + res.Show(); + } + +} \ No newline at end of file diff --git a/TNode/Samples/Editor/HelloEditor.cs.meta b/TNode/Samples/Editor/HelloEditor.cs.meta new file mode 100644 index 0000000..ec0600b --- /dev/null +++ b/TNode/Samples/Editor/HelloEditor.cs.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 7bffb928791aff340912bba71fc356e9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: + - m_ViewDataDictionary: {instanceID: 0} + - mVisualTreeAsset: {fileID: 9197481963319205126, guid: b67f6dcbe2361b649ad2b7845207321b, type: 3} + - graphEditorData: {fileID: 11400000, guid: 060ae44fcac9b534f9bdca3c3e5f1484, type: 2} + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/TNode/Samples/HelloGraph.cs b/TNode/Samples/HelloGraph.cs new file mode 100644 index 0000000..9c4dd64 --- /dev/null +++ b/TNode/Samples/HelloGraph.cs @@ -0,0 +1,8 @@ +using UnityEngine; +using System; +using TNodeCore.Runtime.Models; +[CreateAssetMenu(fileName = "New HelloGraph", menuName = "TNode/HelloGraph")] +[Serializable] +public class HelloGraph : GraphData{ + +} \ No newline at end of file diff --git a/TNode/Samples/HelloGraph.cs.meta b/TNode/Samples/HelloGraph.cs.meta new file mode 100644 index 0000000..3baf052 --- /dev/null +++ b/TNode/Samples/HelloGraph.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2051a0adbd1ba974084a535dd06ab7d7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/TNode/Samples/New HelloGraph.asset b/TNode/Samples/New HelloGraph.asset new file mode 100644 index 0000000..58a1457 --- /dev/null +++ b/TNode/Samples/New HelloGraph.asset @@ -0,0 +1,24 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 2051a0adbd1ba974084a535dd06ab7d7, type: 3} + m_Name: New HelloGraph + m_EditorClassIdentifier: + nodeList: [] + nodeLinks: [] + blackboardData: + rid: -2 + sceneReference: + references: + version: 2 + RefIds: + - rid: -2 + type: {class: , ns: , asm: } diff --git a/TNode/Samples/New HelloGraph.asset.meta b/TNode/Samples/New HelloGraph.asset.meta new file mode 100644 index 0000000..e631b0a --- /dev/null +++ b/TNode/Samples/New HelloGraph.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 490933fc590be444780d73cd9f777ed4 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/TNode/TNodeCore/Runtime/Interfaces/IPortTypeConversion.cs b/TNode/TNodeCore/Runtime/Interfaces/IPortTypeConversion.cs index 4633e26..092dc61 100644 --- a/TNode/TNodeCore/Runtime/Interfaces/IPortTypeConversion.cs +++ b/TNode/TNodeCore/Runtime/Interfaces/IPortTypeConversion.cs @@ -3,5 +3,10 @@ public abstract class PortTypeConversion{ public abstract TTo Convert(TFrom tFrom); } + public abstract class TwoWayPortTypeConversion : PortTypeConversion{ + + public abstract TFrom ConvertBack(TTo tTo); + + } } \ No newline at end of file diff --git a/TNode/TNodeCore/Runtime/RuntimeCache/RuntimeCache.cs b/TNode/TNodeCore/Runtime/RuntimeCache/RuntimeCache.cs index c2db650..bb5046e 100644 --- a/TNode/TNodeCore/Runtime/RuntimeCache/RuntimeCache.cs +++ b/TNode/TNodeCore/Runtime/RuntimeCache/RuntimeCache.cs @@ -45,11 +45,23 @@ namespace TNodeCore.Runtime.RuntimeCache{ public object Convert(object value){ return _converter.Convert((T1)value); } - + + } + //Store a t1 to t2 conversion but use two way converter's convert back method + internal class PortConverterHelperReverse : IPortConverterHelper{ + private readonly TwoWayPortTypeConversion _converter; + public object Convert(object value){ + return _converter.ConvertBack((T1)value); + } + public PortConverterHelperReverse(Type type){ + _converter = Activator.CreateInstance(type) as TwoWayPortTypeConversion; + } + } internal interface IPortConverterHelper{ public object Convert(object value); + } public class PropertyNotFoundException : Exception{ @@ -126,18 +138,17 @@ namespace TNodeCore.Runtime.RuntimeCache{ else{ } } - + private void CacheRuntimePortTypeConversion(Type type){ + if (type.BaseType == null) return; if (type.BaseType != null){ var genericType = type.BaseType.GetGenericTypeDefinition(); - if (genericType != typeof(PortTypeConversion<,>)){ + if (genericType != typeof(PortTypeConversion<,>)|| genericType != typeof(TwoWayPortTypeConversion<,>)){ return; } } - else{ - return; - } - + + //Forward direction var type1 = type.BaseType.GetGenericArguments()[0]; var type2 = type.BaseType.GetGenericArguments()[1]; var specificType = typeof(PortConverterHelper<,>).MakeGenericType(type1, type2); @@ -149,17 +160,70 @@ namespace TNodeCore.Runtime.RuntimeCache{ CachedPortConverters.Add(type1,new Dictionary()); } CachedPortConverters[type1].Add(type2,instance); + + //Reverse direction + if(type.BaseType.GetGenericTypeDefinition()==typeof(TwoWayPortTypeConversion<,>)){ + var specificTypeReverse = typeof(PortConverterHelperReverse<,>).MakeGenericType(type2, type1); + var instanceReverse = Activator.CreateInstance(specificTypeReverse, type) as IPortConverterHelper; + if (instanceReverse == null){ + return; + } + if (!CachedPortConverters.ContainsKey(type2)){ + CachedPortConverters.Add(type2,new Dictionary()); + } + CachedPortConverters[type2].Add(type1,instanceReverse); + } + } + private readonly Dictionary,bool> _possibleImplicitConversions = new (); + private bool HasImplicitConversion(Type baseType, Type targetType){ + var tuple = new Tuple(baseType, targetType); + if (_possibleImplicitConversions.ContainsKey(tuple)){ + return _possibleImplicitConversions[tuple]; + } + var res =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; + }); + return _possibleImplicitConversions[tuple] = res; + } + + private void CachingImplicitConversion(Type baseType, Type targetType){ + if (HasImplicitConversion(baseType, targetType)) return; + + //Create Implicit Conversion Helper that caches the implicit cast function + var typeConverter = Activator.CreateInstance(typeof(ImplicitConversionHelper<,>).MakeGenericType(baseType, targetType)) as IPortConverterHelper; + + if (!CachedPortConverters.ContainsKey(baseType)){ + CachedPortConverters.Add(baseType,new Dictionary()); + } + CachedPortConverters[baseType].Add(targetType,typeConverter); + } - public object GetConvertedValue(Type from,Type to,object value){ + if(!CachedPortConverters.ContainsKey(from)){ - throw new ConversionFailedException("No converter found for type "+from); + //Find the cached port failed ,check if there is an implicit conversion + //This inner cache method would only run once,so add a guard to prevent it run again,even though the function itself has a guard statement. + if(HasImplicitConversion(from,to)){ + CachingImplicitConversion(from,to); + } } if(!CachedPortConverters[from].ContainsKey(to)){ + //Just like above, this function should be checked in here too + if(HasImplicitConversion(from,to)){ + CachingImplicitConversion(from,to); + } return value; } return CachedPortConverters[from][to].Convert(value); } + + private bool GetImplcitConvertedValue(Type from, Type to){ + throw new NotImplementedException(); + } + public List GetSupportedTypes(Type type){ if(!CachedPortConverters.ContainsKey(type)){ return null; @@ -248,6 +312,25 @@ namespace TNodeCore.Runtime.RuntimeCache{ } + public class ImplicitConversionHelper : IPortConverterHelper{ + public Func ConvertFunc; + public ImplicitConversionHelper(){ + //Caching the implicit method that converts t1 to t2 + var method = typeof(T2).GetMethod("op_Implicit", BindingFlags.Public | BindingFlags.Static, null, new[] { typeof(T1) }, null); + if (method == null){ + //Search it in T1 + method = typeof(T1).GetMethod("op_Implicit", BindingFlags.Public | BindingFlags.Static, null, new[] { typeof(T2) }, null); + } + //Create the delegate + if (method != null) + ConvertFunc = (Func) Delegate.CreateDelegate(typeof(Func), method); + } + + public object Convert(object value){ + return ConvertFunc((T1) value); + } + } + public class ConversionFailedException : Exception{ public ConversionFailedException(string noConverterFoundForType):base(noConverterFoundForType){ diff --git a/TNode/TNodeCore/Runtime/RuntimeNode.cs b/TNode/TNodeCore/Runtime/RuntimeNode.cs index 172d0e8..2bf09f7 100644 --- a/TNode/TNodeCore/Runtime/RuntimeNode.cs +++ b/TNode/TNodeCore/Runtime/RuntimeNode.cs @@ -23,16 +23,15 @@ namespace TNodeCore.Runtime{ var portType = _portAccessors[portName].Type; if(portType!=valueType && !portType.IsAssignableFrom(valueType)){ var res =RuntimeCache.RuntimeCache.Instance.GetConvertedValue(valueType, portType, value); - _portAccessors[portName].SetValue(this.NodeData, res); + _portAccessors[portName].SetValue(NodeData, res); } else{ - - _portAccessors[portName].SetValue(this.NodeData,value); + _portAccessors[portName].SetValue(NodeData,value); } } public object GetOutput(string portName){ - return _portAccessors[portName].GetValue(this.NodeData); + return _portAccessors[portName].GetValue(NodeData); } diff --git a/TNode/TNodeGtfImpl.meta b/TNode/TNodeGtfImpl.meta new file mode 100644 index 0000000..19f4b0e --- /dev/null +++ b/TNode/TNodeGtfImpl.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: fcfff7d02bd7fbb41a515c4c4359aab2 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: From 7fc1ebafdb41117c8d32b272e3725836e50deeb7 Mon Sep 17 00:00:00 2001 From: taoria <445625470@qq.com> Date: Fri, 5 Aug 2022 23:48:20 +0800 Subject: [PATCH 4/4] fix:fix a blackboard error --- TNode/Samples/AddNode.cs | 23 ++++ TNode/Samples/AddNode.cs.meta | 3 + TNode/Samples/Editor/HelloEditor.cs | 5 +- TNode/Samples/HelloBlackboard.cs | 17 +++ TNode/Samples/HelloBlackboard.cs.meta | 3 + TNode/Samples/HelloGraph.cs | 11 +- TNode/Samples/New HelloGraph.asset | 100 +++++++++++++++++- TNode/TNodeCore/Editor/GraphEditor.cs | 1 + .../Runtime/Models/BlackboardData.cs | 7 +- .../Runtime/RuntimeCache/RuntimeCache.cs | 7 +- .../Editor/Cache/NodeEditorExtensions.cs | 26 ++++- .../DefaultGraphBlackboardView.cs | 13 +-- .../Editor/NodeGraphView/DataGraphView.cs | 73 ++++++++++--- .../Editor/NodeViews/DragNodeView.cs | 1 + .../Search/BlackboardSearchWindowProvider.cs | 10 +- 15 files changed, 254 insertions(+), 46 deletions(-) create mode 100644 TNode/Samples/AddNode.cs create mode 100644 TNode/Samples/AddNode.cs.meta create mode 100644 TNode/Samples/HelloBlackboard.cs create mode 100644 TNode/Samples/HelloBlackboard.cs.meta diff --git a/TNode/Samples/AddNode.cs b/TNode/Samples/AddNode.cs new file mode 100644 index 0000000..2c22e58 --- /dev/null +++ b/TNode/Samples/AddNode.cs @@ -0,0 +1,23 @@ + +using TNodeCore.Runtime; +using TNodeCore.Runtime.Attributes; +using TNodeCore.Runtime.Attributes.Ports; +using TNodeCore.Runtime.Models; +using UnityEngine; + +namespace Samples{ + [GraphUsage(typeof(HelloGraph),"Math")] + public class AddNode:NodeData{ + [Input] + public Vector3 A{ get; set; } + [Input] + public Vector2 B{ get; set; } + [Output] + public Vector3 Res{ get; set; } + + public override void Process(){ + Res = A + (Vector3)B; + this.Log(Res.ToString()); + } + } +} \ No newline at end of file diff --git a/TNode/Samples/AddNode.cs.meta b/TNode/Samples/AddNode.cs.meta new file mode 100644 index 0000000..89b3d0d --- /dev/null +++ b/TNode/Samples/AddNode.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: f9814ff421124feda824b77793cf24f2 +timeCreated: 1659705932 \ No newline at end of file diff --git a/TNode/Samples/Editor/HelloEditor.cs b/TNode/Samples/Editor/HelloEditor.cs index f7e4219..055890b 100644 --- a/TNode/Samples/Editor/HelloEditor.cs +++ b/TNode/Samples/Editor/HelloEditor.cs @@ -1,3 +1,4 @@ +using Samples; using UnityEditor; using UnityEditor.Callbacks; using UnityEngine; @@ -8,7 +9,7 @@ public class HelloEditor : GraphEditor{ var graph = EditorUtility.InstanceIDToObject(instanceID) as HelloGraph; if (graph != null) { var wnd = GetWindow(); - wnd.titleContent = new GUIContent("EasyGraph Editor"); + wnd.titleContent = new GUIContent("HelloGraph Editor"); wnd.Show(); wnd.SetupNonRuntime(graph); return true; @@ -18,7 +19,7 @@ public class HelloEditor : GraphEditor{ [MenuItem("Window/HelloEditor")] public static void ShowWindow(){ var res = GetWindow(); - res.titleContent = new GUIContent("EasyGraph Editor"); + res.titleContent = new GUIContent("HelloGraph Editor"); res.Show(); } diff --git a/TNode/Samples/HelloBlackboard.cs b/TNode/Samples/HelloBlackboard.cs new file mode 100644 index 0000000..0b1f787 --- /dev/null +++ b/TNode/Samples/HelloBlackboard.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using Samples; +using TNodeCore.Runtime.Attributes; +using TNodeCore.Runtime.Models; +using UnityEngine; + +namespace TNode.Samples{ + [GraphUsage(typeof(HelloGraph))] + public class HelloBlackboard:BlackboardData{ + public string HelloString = "Hello World"; + + public List V3S; + public List V2S; + + } +} \ No newline at end of file diff --git a/TNode/Samples/HelloBlackboard.cs.meta b/TNode/Samples/HelloBlackboard.cs.meta new file mode 100644 index 0000000..81c6994 --- /dev/null +++ b/TNode/Samples/HelloBlackboard.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: edaf56bfb57443eb85ecadd142c4ce7d +timeCreated: 1659706002 \ No newline at end of file diff --git a/TNode/Samples/HelloGraph.cs b/TNode/Samples/HelloGraph.cs index 9c4dd64..779c75d 100644 --- a/TNode/Samples/HelloGraph.cs +++ b/TNode/Samples/HelloGraph.cs @@ -1,8 +1,11 @@ -using UnityEngine; using System; using TNodeCore.Runtime.Models; -[CreateAssetMenu(fileName = "New HelloGraph", menuName = "TNode/HelloGraph")] -[Serializable] -public class HelloGraph : GraphData{ +using UnityEngine; + +namespace Samples{ + [CreateAssetMenu(fileName = "New HelloGraph", menuName = "TNode/HelloGraph")] + [Serializable] + public class HelloGraph : GraphData{ + } } \ No newline at end of file diff --git a/TNode/Samples/New HelloGraph.asset b/TNode/Samples/New HelloGraph.asset index 58a1457..687fdaa 100644 --- a/TNode/Samples/New HelloGraph.asset +++ b/TNode/Samples/New HelloGraph.asset @@ -12,13 +12,103 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 2051a0adbd1ba974084a535dd06ab7d7, type: 3} m_Name: New HelloGraph m_EditorClassIdentifier: - nodeList: [] - nodeLinks: [] + nodeList: + - rid: 4804121563801583862 + - rid: 4804121563801583898 + - rid: 4804121563801583870 + - rid: 4804121563801583866 + nodeLinks: + - inPort: + portEntryName: A + nodeDataId: 6ceba867-fe0d-40c3-9d30-2d5d12803b52 + outPort: + portEntryName: Value + nodeDataId: ac84573e-638d-45fa-b4e2-1a81c31fa9e7 + - inPort: + portEntryName: B + nodeDataId: 6ceba867-fe0d-40c3-9d30-2d5d12803b52 + outPort: + portEntryName: Value + nodeDataId: b2ab4a52-e65d-4104-8891-dc316af217d9 blackboardData: - rid: -2 + rid: 4804121563801583854 sceneReference: references: version: 2 RefIds: - - rid: -2 - type: {class: , ns: , asm: } + - rid: 4804121563801583854 + type: {class: HelloBlackboard, ns: TNode.Samples, asm: Assembly-CSharp} + data: + positionInView: + serializedVersion: 2 + x: 0 + y: 0 + width: 0 + height: 0 + HelloString: Hello World + V3S: + - {x: 0, y: 0, z: 0} + - {x: 0, y: 0, z: 0} + - {x: 0, y: 0, z: 0} + V2S: + - {x: 0, y: 0} + - {x: 0, y: 0} + - {x: 0, y: 0} + - rid: 4804121563801583862 + type: {class: BlackboardDragNodeData, ns: TNodeCore.Runtime.Models, asm: NewAssembly} + data: + positionInView: + serializedVersion: 2 + x: 256 + y: 264 + width: 0 + height: 0 + id: bae506a7-58ec-4b79-9c21-747fa2b6a7ba + nodeName: + entryPoint: 0 + isTest: 0 + blackDragData: HelloString + isListElement: 0 + - rid: 4804121563801583866 + type: {class: AddNode, ns: Samples, asm: Assembly-CSharp} + data: + positionInView: + serializedVersion: 2 + x: 620 + y: 234 + width: 0 + height: 0 + id: 6ceba867-fe0d-40c3-9d30-2d5d12803b52 + nodeName: AddNode + entryPoint: 0 + isTest: 0 + - rid: 4804121563801583870 + type: {class: BlackboardDragNodeData, ns: TNodeCore.Runtime.Models, asm: NewAssembly} + data: + positionInView: + serializedVersion: 2 + x: 469.00006 + y: 336 + width: 0 + height: 0 + id: b2ab4a52-e65d-4104-8891-dc316af217d9 + nodeName: + entryPoint: 0 + isTest: 0 + blackDragData: V2S.0 + isListElement: 1 + - rid: 4804121563801583898 + type: {class: BlackboardDragNodeData, ns: TNodeCore.Runtime.Models, asm: NewAssembly} + data: + positionInView: + serializedVersion: 2 + x: 469 + y: 213 + width: 0 + height: 0 + id: ac84573e-638d-45fa-b4e2-1a81c31fa9e7 + nodeName: + entryPoint: 0 + isTest: 0 + blackDragData: V3S.0 + isListElement: 1 diff --git a/TNode/TNodeCore/Editor/GraphEditor.cs b/TNode/TNodeCore/Editor/GraphEditor.cs index d035c65..b4c339b 100644 --- a/TNode/TNodeCore/Editor/GraphEditor.cs +++ b/TNode/TNodeCore/Editor/GraphEditor.cs @@ -80,6 +80,7 @@ namespace TNodeCore.Editor{ GraphView.IsRuntimeGraph = false; } private void BuildGraphView(){ + GraphView = graphEditorData.GetGraphView(); GraphView.Owner = this; diff --git a/TNode/TNodeCore/Runtime/Models/BlackboardData.cs b/TNode/TNodeCore/Runtime/Models/BlackboardData.cs index 4d67b50..4ca2528 100644 --- a/TNode/TNodeCore/Runtime/Models/BlackboardData.cs +++ b/TNode/TNodeCore/Runtime/Models/BlackboardData.cs @@ -7,10 +7,7 @@ namespace TNodeCore.Runtime.Models{ /// [Serializable] - public class BlackboardData:Model,ICloneable{ - - - - + public abstract class BlackboardData:Model{ + } } \ No newline at end of file diff --git a/TNode/TNodeCore/Runtime/RuntimeCache/RuntimeCache.cs b/TNode/TNodeCore/Runtime/RuntimeCache/RuntimeCache.cs index bb5046e..a3d0f69 100644 --- a/TNode/TNodeCore/Runtime/RuntimeCache/RuntimeCache.cs +++ b/TNode/TNodeCore/Runtime/RuntimeCache/RuntimeCache.cs @@ -175,7 +175,7 @@ namespace TNodeCore.Runtime.RuntimeCache{ } } private readonly Dictionary,bool> _possibleImplicitConversions = new (); - private bool HasImplicitConversion(Type baseType, Type targetType){ + public bool HasImplicitConversion(Type baseType, Type targetType){ var tuple = new Tuple(baseType, targetType); if (_possibleImplicitConversions.ContainsKey(tuple)){ return _possibleImplicitConversions[tuple]; @@ -188,6 +188,7 @@ namespace TNodeCore.Runtime.RuntimeCache{ }); return _possibleImplicitConversions[tuple] = res; } + private void CachingImplicitConversion(Type baseType, Type targetType){ if (HasImplicitConversion(baseType, targetType)) return; @@ -201,8 +202,8 @@ namespace TNodeCore.Runtime.RuntimeCache{ CachedPortConverters[baseType].Add(targetType,typeConverter); } + public object GetConvertedValue(Type from,Type to,object value){ - if(!CachedPortConverters.ContainsKey(from)){ //Find the cached port failed ,check if there is an implicit conversion //This inner cache method would only run once,so add a guard to prevent it run again,even though the function itself has a guard statement. @@ -226,7 +227,7 @@ namespace TNodeCore.Runtime.RuntimeCache{ public List GetSupportedTypes(Type type){ if(!CachedPortConverters.ContainsKey(type)){ - return null; + return new List(); } return CachedPortConverters[type].Keys.ToList(); } diff --git a/TNode/TNodeGraphViewImpl/Editor/Cache/NodeEditorExtensions.cs b/TNode/TNodeGraphViewImpl/Editor/Cache/NodeEditorExtensions.cs index 738cd85..4c996ec 100644 --- a/TNode/TNodeGraphViewImpl/Editor/Cache/NodeEditorExtensions.cs +++ b/TNode/TNodeGraphViewImpl/Editor/Cache/NodeEditorExtensions.cs @@ -10,7 +10,9 @@ using TNodeCore.Editor.EditorPersistence; using TNodeCore.Editor.NodeGraphView; using TNodeCore.Runtime.Attributes; using TNodeCore.Runtime.Models; +using Unity.VisualScripting; using UnityEditor; +using UnityEngine; namespace TNode.TNodeGraphViewImpl.Editor.Cache{ /// @@ -40,7 +42,12 @@ namespace TNode.TNodeGraphViewImpl.Editor.Cache{ get{ return _instance ??= new NodeEditorSingleton(); } } - private static readonly string[] ExcludedAssemblies = new string[]{"Microsoft", "UnityEngine","UnityEditor","mscorlib","System"}; + + private static readonly string[] ExcludedAssemblies = new[]{ + "Microsoft", "UnityEngine","UnityEditor","mscorlib", + "System","Mono","PlasticPipe","unityplastic","ExCSS", + "Unity","PlayerBuildProgramLibrary","netstandard","log4net","Newtonsoft","Bee","nunit","PsdPlugin" + }; public static T CreateViewComponentFromBaseType(){ var implementedType = NodeEditorSingleton.Instance.FromGenericToSpecific[typeof(T)]; var instance = (T)Activator.CreateInstance(implementedType); @@ -63,10 +70,12 @@ namespace TNode.TNodeGraphViewImpl.Editor.Cache{ private NodeEditorSingleton(){ //exclude unity ,system ,and microsoft types - var assemblies = AppDomain. - CurrentDomain.GetAssemblies() - .Where(x=>ExcludedAssemblies.All(y=>!x.GetName().Name.Split(".")[0].Equals(y))); - + var assemblies = AppDomain.CurrentDomain.GetAssemblies(); + + + assemblies = assemblies.Where(x => !ExcludedAssemblies.Contains(x.FullName.Split('.',',',' ')[0])).ToArray(); + foreach (var ass in assemblies){ + } foreach(var assembly in assemblies){ foreach(var type in assembly.GetTypes()){ if(type.IsClass && !type.IsAbstract){ @@ -91,6 +100,7 @@ namespace TNode.TNodeGraphViewImpl.Editor.Cache{ return instance; } private void SetGraphUsageAttribute(Type type){ + foreach (var attribute in type.GetCustomAttributes(typeof(GraphUsageAttribute), true)){ var parent = type.BaseType; if (typeof(Model).IsAssignableFrom(type.BaseType)){ @@ -205,11 +215,15 @@ namespace TNode.TNodeGraphViewImpl.Editor.Cache{ } public static List GetGraphCategories(Type t){ + if(!NodeEditorSingleton.Instance.GraphDataUsage.ContainsKey(t)){ + return new List(); + } var list = NodeEditorSingleton.Instance.GraphDataUsage[t]; //Merge same category var res = list.Select(x=>x.GetCustomAttribute().Category).Distinct().ToList(); return res; } + //TODO Move this method to runtime place public static BlackboardData GetAppropriateBlackboardData(Type t){ if (NodeEditorSingleton.Instance.GraphBlackboard.ContainsKey(t)){ return (BlackboardData)Activator.CreateInstance(NodeEditorSingleton.Instance.GraphBlackboard[t]); @@ -261,8 +275,10 @@ namespace TNode.TNodeGraphViewImpl.Editor.Cache{ } } [InitializeOnLoad] + public class Launcher{ static Launcher(){ + Debug.Log("NES Launched"); NodeEditorSingleton.Instance.Initialize(); } } diff --git a/TNode/TNodeGraphViewImpl/Editor/GraphBlackboard/DefaultGraphBlackboardView.cs b/TNode/TNodeGraphViewImpl/Editor/GraphBlackboard/DefaultGraphBlackboardView.cs index ac89773..649d74d 100644 --- a/TNode/TNodeGraphViewImpl/Editor/GraphBlackboard/DefaultGraphBlackboardView.cs +++ b/TNode/TNodeGraphViewImpl/Editor/GraphBlackboard/DefaultGraphBlackboardView.cs @@ -50,24 +50,24 @@ namespace TNode.TNodeGraphViewImpl.Editor.GraphBlackboard{ blackboardList.Add(foldout); Add(blackboardList); + if(field.GetValue(data)==null) continue; if (field.GetValue(data) is IList list){ for (var i = 0; i < list.Count; i++){ CreateBlackboardDataEntryForListItem(field, serializedObject, isRuntimeGraph, blackboardList, i); } } - if (field.GetValue(data).GetType().IsArray){ var array = (Array)field.GetValue(data); + if(array==null) continue; for (var i = 0; i < array.Length; i++){ CreateBlackboardDataEntryForListItem(field, serializedObject, isRuntimeGraph, blackboardList, i); } } } } - addItemRequested += (sender) => { + addItemRequested = (sender) => { var res = ScriptableObject.CreateInstance(); - - + Debug.Log(res); //Get right top corner of the blackboard var blackboardPos = GetPosition().position+OwnerWindow.position.position; @@ -79,7 +79,6 @@ namespace TNode.TNodeGraphViewImpl.Editor.GraphBlackboard{ res.Setup(Owner.GetGraphData().GetType(),Owner,OwnerWindow,this); SearchWindow.Open(searchWindowContext, res); - }; } @@ -87,7 +86,8 @@ namespace TNode.TNodeGraphViewImpl.Editor.GraphBlackboard{ private static void CreateBlackboardDataEntryForListItem(FieldInfo field, SerializedObject serializedObject, bool isRuntimeGraph, BlackboardSection blackboardSection, int index){ - var property =serializedObject.FindProperty("data").FindPropertyRelative(field.Name).GetArrayElementAtIndex(index); + var property = serializedObject.FindProperty("data"); + property = property.FindPropertyRelative(field.Name).GetArrayElementAtIndex(index); BlackboardDataEntry entry = new BlackboardDataEntry(field.FieldType){ propertyPath = field.Name+"."+index, @@ -102,6 +102,7 @@ namespace TNode.TNodeGraphViewImpl.Editor.GraphBlackboard{ } + private static void CreateBlackboardDataEntry(FieldInfo field, SerializedObject serializedObject, bool isRuntimeGraph, BlackboardSection blackboardSection){ BlackboardDataEntry entry = new BlackboardDataEntry(field.FieldType){ diff --git a/TNode/TNodeGraphViewImpl/Editor/NodeGraphView/DataGraphView.cs b/TNode/TNodeGraphViewImpl/Editor/NodeGraphView/DataGraphView.cs index 8a1459d..4eef460 100644 --- a/TNode/TNodeGraphViewImpl/Editor/NodeGraphView/DataGraphView.cs +++ b/TNode/TNodeGraphViewImpl/Editor/NodeGraphView/DataGraphView.cs @@ -145,6 +145,7 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeGraphView{ if (Data != null){ visualElement.RemoveFromHierarchy(); } + CreateMenu(); }; } @@ -218,8 +219,7 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeGraphView{ _loaded = true; SetDetachedFromPanel(); - - + } private void SetDetachedFromPanel(){ @@ -241,6 +241,7 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeGraphView{ } protected void CreateMenu(){ + if (this.Q("TopMenu") != null) return; var visualElement = new VisualElement{ name = "TopMenu" }; @@ -278,6 +279,16 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeGraphView{ } }); visualElement.Add(runButton); + + var blackboardButton = new Button{ + name = "blackboardButton", + text = "Blackboard" + }; + blackboardButton.RegisterCallback(evt => { + if(_blackboard==null) + CreateBlackboard(); + }); + visualElement.Add(blackboardButton); } public void RegisterDragEvent(){ @@ -399,12 +410,14 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeGraphView{ } - private void BlackboardUpdate(){ + private void UpdateBlackboardData(){ + if (_data == null) return; + if (_data.blackboardData == null || _data.blackboardData.GetType()==(typeof(BlackboardData))){ + _data.blackboardData = NodeEditorExtensions.GetAppropriateBlackboardData(_data.GetType()); - + Debug.Log(_data.blackboardData); if (_data.blackboardData == null) return; - } _blackboard.SetBlackboardData(GetBlackboardData()); } @@ -506,15 +519,45 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeGraphView{ }); } public override List GetCompatiblePorts(Port startPort, NodeAdapter nodeAdapter){ - var supportedTypes = RuntimeCache.Instance.GetSupportedTypes(startPort.portType); - + + var compatiblePorts = ports.Where(x => startPort != x && - (x.portType == startPort.portType || - x.portType.IsAssignableFrom(startPort.portType) - )).ToList(); - if (supportedTypes != null){ - compatiblePorts.AddRange(ports.Where(x => supportedTypes.Contains(x.portType)).ToList()); + (x.portType == startPort.portType || + x.portType.IsAssignableFrom(startPort.portType) + )).ToList(); + if(startPort.direction==Direction.Input){ + //Search output to find ports with type that have implicit conversion or define converter that convert to type of the startPort + var outputPorts = ports.Where(x => x.direction == Direction.Output).ToList(); + foreach (var outputPort in outputPorts){ + //Want a port type that can convert to to the type of the startPort + if (HasImplicitConversion(outputPort.portType,startPort.portType)){ + compatiblePorts.Add(outputPort); + } + if (RuntimeCache.Instance.GetSupportedTypes(outputPort.portType).Contains(startPort.portType)){ + compatiblePorts.Add(outputPort); + } + } + } + else{ + var inputPorts = ports.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)){ + compatiblePorts.Add(inputPort); + } + //Check if input port type is supported by output port type + if (RuntimeCache.Instance.GetSupportedTypes(startPort.portType).Contains(inputPort.portType)){ + compatiblePorts.Add(inputPort); + } + } } + + + + + + return compatiblePorts; @@ -607,6 +650,7 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeGraphView{ get=>Owner.graphEditorData.autoUpdate; set=>Owner.graphEditorData.autoUpdate = value; } + public override EventPropagation DeleteSelection(){ Undo.RegisterCompleteObjectUndo(_data,"Delete Selection"); var res = base.DeleteSelection(); @@ -616,13 +660,14 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeGraphView{ } public void CreateBlackboard(){ - _blackboard = NodeEditorExtensions.CreateBlackboardWithGraphData(typeof(T)); + _blackboard = NodeEditorExtensions.CreateBlackboardWithGraphData(typeof(T)) ; _blackboard.Setup(this,Owner); var castedBlackboard = _blackboard as Blackboard; Add(castedBlackboard); Rect blackboardPos = new Rect(0,0,300,700); castedBlackboard?.SetPosition(blackboardPos); - OnDataChanged+= (sender, e) => { BlackboardUpdate(); }; + UpdateBlackboardData(); + OnDataChanged+= (sender, e) => { UpdateBlackboardData(); }; } public GraphData GetGraphData(){ diff --git a/TNode/TNodeGraphViewImpl/Editor/NodeViews/DragNodeView.cs b/TNode/TNodeGraphViewImpl/Editor/NodeViews/DragNodeView.cs index f95f424..4f417f8 100644 --- a/TNode/TNodeGraphViewImpl/Editor/NodeViews/DragNodeView.cs +++ b/TNode/TNodeGraphViewImpl/Editor/NodeViews/DragNodeView.cs @@ -33,6 +33,7 @@ namespace TNode.TNodeGraphViewImpl.Editor.NodeViews{ label.text = ObjectNames.NicifyVariableName(obj.BlackDragData); //Get serialized property's icon Texture2D icon = null; + if (serializedProperty == null) return; if (serializedProperty.boxedValue is Object value){ icon = AssetPreview.GetMiniThumbnail(value); } diff --git a/TNode/TNodeGraphViewImpl/Editor/Search/BlackboardSearchWindowProvider.cs b/TNode/TNodeGraphViewImpl/Editor/Search/BlackboardSearchWindowProvider.cs index fe01ff4..be8e56d 100644 --- a/TNode/TNodeGraphViewImpl/Editor/Search/BlackboardSearchWindowProvider.cs +++ b/TNode/TNodeGraphViewImpl/Editor/Search/BlackboardSearchWindowProvider.cs @@ -31,17 +31,21 @@ namespace TNode.TNodeGraphViewImpl.Editor.Search{ if (list == null) throw new ArgumentNullException(nameof(list)); //search fields with List type Texture2D icon = new Texture2D(2,2); - foreach (var field in type.GetFields()){ if (field.FieldType.IsGenericType){ var genericType = field.FieldType.GetGenericTypeDefinition(); if (genericType == typeof(List<>)){ + var castedList = field.GetValue(blackboardData) as IList; + if (castedList == null){ + field.SetValue(blackboardData, Activator.CreateInstance(field.FieldType)); + } list.Add(new SearchTreeEntry(new GUIContent(field.Name,icon)){ level = 1, userData = new InternalSearchTreeUserData(){ List = field.GetValue(blackboardData) as IList, Type = field.FieldType.GetGenericArguments()[0] } + }); } } @@ -64,7 +68,9 @@ namespace TNode.TNodeGraphViewImpl.Editor.Search{ if (userData is InternalSearchTreeUserData){ var list = ((InternalSearchTreeUserData) userData).List; - Debug.Log(list); + if (list == null){ + + } var type = ((InternalSearchTreeUserData) userData).Type; if (!typeof(Object).IsAssignableFrom(type)){ var newItem = Activator.CreateInstance(type);