From 28f87fd0f2dbc604585fcf4e443c6ec4eb684cc5 Mon Sep 17 00:00:00 2001 From: taoria <445625470@qq.com> Date: Tue, 5 Jul 2022 02:53:46 +0800 Subject: [PATCH 1/5] 1.blackboard data --- TNode/Editor/BaseViews/DataGraphView.cs | 83 ++++++++++++++++--------- TNode/Models/BlackDragNodeData.cs | 10 +-- TNode/Models/BlackboardData.cs | 4 +- TNode/Runtime/Runtimeblackboard.cs | 10 +++ TNode/Runtime/Runtimeblackboard.cs.meta | 3 + TNode/RuntimeCache/RuntimeCache.cs | 58 ++++++++--------- 6 files changed, 102 insertions(+), 66 deletions(-) create mode 100644 TNode/Runtime/Runtimeblackboard.cs create mode 100644 TNode/Runtime/Runtimeblackboard.cs.meta diff --git a/TNode/Editor/BaseViews/DataGraphView.cs b/TNode/Editor/BaseViews/DataGraphView.cs index 408bfed..6312cf7 100644 --- a/TNode/Editor/BaseViews/DataGraphView.cs +++ b/TNode/Editor/BaseViews/DataGraphView.cs @@ -116,7 +116,8 @@ namespace TNode.Editor.BaseViews{ private NodeInspector _nodeInspector; public GraphEditor Owner; private Dictionary _nodeDict = new(); - + private Blackboard _blackboard; + public T Data{ get{ return _data; } set{ @@ -234,7 +235,7 @@ namespace TNode.Editor.BaseViews{ } public void CreateBlackboard(){ - var blackboard = new Blackboard(); + _blackboard = new Blackboard(); //Blackboard add "Add Node" button // blackboard.Add(new BlackboardSection(){ // title = "Hello World", @@ -245,40 +246,60 @@ namespace TNode.Editor.BaseViews{ // }; // //Set black board to left side of the view - blackboard.SetPosition(new Rect(0,0,200,600)); - Add(blackboard); + _blackboard.SetPosition(new Rect(0,0,200,600)); + Add(_blackboard); //Check the type of the blackboard - OnDataChanged+= (sender, e) => { - - if (_data.blackboardData==null||_data.blackboardData.GetType()==typeof(BlackboardData)){ - _data.blackboardData = NodeEditorExtensions.GetAppropriateBlackboardData(_data.GetType()); - - if(_data.blackboardData==null) return; - - } - Debug.Log(_data.blackboardData); - //Iterate field of the blackboard and add a button for each field - foreach (var field in _data.blackboardData.GetType() - .GetFields(BindingFlags.Public|BindingFlags.NonPublic | BindingFlags.Instance)){ - Debug.Log(field); - //if the field is MonoBehaviour,add a property field for blackboard - if(typeof(UnityEngine.Object).IsAssignableFrom(field.FieldType)){ - var propertyField = new BlackboardField(null,field.Name,null){ - - }; - blackboard.Add(propertyField); - } - if(typeof(string).IsAssignableFrom(field.FieldType)){ - var propertyField = new BlackboardField(null,field.Name,null){ - - }; - blackboard.Add(propertyField); - } + OnDataChanged+= (sender, e) => { BlackboardUpdate(); }; + + } + + private void BlackboardUpdate(){ + if (_data.blackboardData == null || _data.blackboardData.GetType() == typeof(BlackboardData)){ + _data.blackboardData = NodeEditorExtensions.GetAppropriateBlackboardData(_data.GetType()); + + if (_data.blackboardData == null) return; + } + + Debug.Log(_data.blackboardData); + //Iterate field of the blackboard and add a button for each field + foreach (var field in _data.blackboardData.GetType() + .GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)){ + Debug.Log(field); + //if the field is MonoBehaviour,add a property field for blackboard + if (typeof(UnityEngine.Object).IsAssignableFrom(field.FieldType)){ + var propertyField = new BlackboardField(null, field.Name, null){ + }; + _blackboard.Add(propertyField); + //register a drag event for the property field to drag the object from blackboard to the graph + + propertyField.RegisterCallback(evt => { + if (evt.target is GraphView graphView){ + var type = field.FieldType; + //Get Generic Constructor of the BlackDragNodeData<> + var genericConstructor = typeof(BlackDragNodeData<>).MakeGenericType(type).GetConstructor( + BindingFlags.Instance | BindingFlags.NonPublic, + null, + new Type[]{typeof(string), typeof(object)}, + null); + if (genericConstructor != null){ + NodeData nodeData = null; + nodeData = + genericConstructor.Invoke(null, new object[]{field.Name, _data.blackboardData}) as NodeData; + this.AddTNode(nodeData, new Rect(evt.localMousePosition, new Vector2(200, 200))); + } + } + }); } - }; + if (typeof(string).IsAssignableFrom(field.FieldType)){ + var propertyField = new BlackboardField(null, field.Name, null){ + }; + _blackboard.Add(propertyField); + } + } } + public virtual void DestroyInspector(){ if(_nodeInspector!=null){ this.Remove(_nodeInspector); diff --git a/TNode/Models/BlackDragNodeData.cs b/TNode/Models/BlackDragNodeData.cs index 19eb282..4876f25 100644 --- a/TNode/Models/BlackDragNodeData.cs +++ b/TNode/Models/BlackDragNodeData.cs @@ -1,16 +1,18 @@ using System.Runtime.InteropServices; using Newtonsoft.Json; using TNode.Attribute.Ports; +using TNode.RuntimeCache; namespace TNode.Models{ - public class BlackDragNodeData:NodeData{ + public class BlackDragNodeData:NodeData where T:BlackboardData{ [JsonIgnore] private string _blackDragData; [JsonIgnore] - private BlackboardData _blackboardData; + private T _blackboardData; - [Output] public T value => _blackboardData.GetValue(_blackDragData); - public BlackDragNodeData(string blackDragData,BlackboardData blackboardData){ + [Output] + public T Value => _blackboardData.GetValue(_blackDragData); + public BlackDragNodeData(string blackDragData,T blackboardData){ _blackDragData = blackDragData; _blackboardData = blackboardData; } diff --git a/TNode/Models/BlackboardData.cs b/TNode/Models/BlackboardData.cs index 4b2c2e7..fc0b66a 100644 --- a/TNode/Models/BlackboardData.cs +++ b/TNode/Models/BlackboardData.cs @@ -1,8 +1,6 @@ namespace TNode.Models{ public class BlackboardData:IModel{ - public T GetValue(string key){ - return default(T); - } + } } \ No newline at end of file diff --git a/TNode/Runtime/Runtimeblackboard.cs b/TNode/Runtime/Runtimeblackboard.cs new file mode 100644 index 0000000..1a91406 --- /dev/null +++ b/TNode/Runtime/Runtimeblackboard.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; +using TNode.Models; + +namespace TNode.Runtime{ + public class RuntimeBlackboard where T:BlackboardData{ + + public T Data { get; set; } + + } +} \ No newline at end of file diff --git a/TNode/Runtime/Runtimeblackboard.cs.meta b/TNode/Runtime/Runtimeblackboard.cs.meta new file mode 100644 index 0000000..02868cd --- /dev/null +++ b/TNode/Runtime/Runtimeblackboard.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 6b69b2dedba24e35bf04bc9112da6b12 +timeCreated: 1656958407 \ No newline at end of file diff --git a/TNode/RuntimeCache/RuntimeCache.cs b/TNode/RuntimeCache/RuntimeCache.cs index 13e82e4..11bc35b 100644 --- a/TNode/RuntimeCache/RuntimeCache.cs +++ b/TNode/RuntimeCache/RuntimeCache.cs @@ -16,38 +16,13 @@ namespace TNode.RuntimeCache{ //delegate return a value from a nodedata public delegate object GetValueDelegate(IModel nodeData); - public readonly Dictionary> CachedDelegatesForGettingValue = + public readonly Dictionary> CachedDelegatesForGettingValue = new (); - public void ExecuteOutput(T nodeData) where T:NodeData{ - var type = typeof(T); - if(!CachedDelegatesForGettingValue.ContainsKey(type)){ - return; - } - var delegates = CachedDelegatesForGettingValue[type]; - foreach(var delegateInstance in delegates){ - var value = delegateInstance(nodeData); - } - } private static readonly string[] ExcludedAssemblies = new string[]{"Microsoft", "UnityEngine","UnityEditor","mscorlib","System"}; - public void RegisterRuntimeNode() where T:NodeData{ - var type = typeof(T); - if(!CachedDelegatesForGettingValue.ContainsKey(type)){ - CachedDelegatesForGettingValue.Add(type, new List()); - var properties = type.GetProperties(); - foreach(var property in properties){ - var getValueDelegate = GetValueDelegateForProperty(property); - CachedDelegatesForGettingValue[type].Add(getValueDelegate); - } - } - else{ - //Cache already exists for this type - - } - } public void RegisterRuntimeBlackboard(Type type){ if(!CachedDelegatesForGettingValue.ContainsKey(type)){ - CachedDelegatesForGettingValue.Add(type, new List()); + CachedDelegatesForGettingValue.Add(type, new Dictionary()); var properties = type.GetProperties(); foreach(var property in properties){ //if the property only has a setter ,skip @@ -55,14 +30,41 @@ namespace TNode.RuntimeCache{ continue; } var getValueDelegate = GetValueDelegateForProperty(property); - CachedDelegatesForGettingValue[type].Add(getValueDelegate); + CachedDelegatesForGettingValue[type].Add(property.Name,getValueDelegate); + } + //register the fields + var fields = type.GetFields(); + foreach(var field in fields){ + var getValueDelegate = GetValueDelegateForField(field); + CachedDelegatesForGettingValue[type].Add(field.Name,getValueDelegate); } } } + private GetValueDelegate GetValueDelegateForField(FieldInfo field){ + return field.GetValue; + } + + private GetValueDelegate GetValueDelegateForProperty(PropertyInfo property){ var getValueDelegate = (GetValueDelegate)Delegate.CreateDelegate(typeof(GetValueDelegate), property.GetGetMethod()); return getValueDelegate; } + + + + } + public static class RuntimeExtension{ + + //todo latter on i will try some way caching reflection more efficiently + public static T GetValue(this BlackboardData blackboardData,string path){ + var method = RuntimeCache.Instance.CachedDelegatesForGettingValue[blackboardData.GetType()][path]; + return (T) method.Invoke(blackboardData); + } + public static RuntimeCache.GetValueDelegate GetValueDelegate(this BlackboardData blackboardData,string path){ + var method = RuntimeCache.Instance.CachedDelegatesForGettingValue[blackboardData.GetType()][path]; + return method; + } + } } \ No newline at end of file From de0d55d07aac8e0dad05312aacd5a50cdb0b2113 Mon Sep 17 00:00:00 2001 From: taoria <445625470@qq.com> Date: Wed, 6 Jul 2022 02:38:50 +0800 Subject: [PATCH 2/5] 1.continue working on blackboard data --- TNode/Editor/BaseViews/DataGraphView.cs | 98 ++++++++++++------- .../Editor/GraphBlackboard/BlackboardField.cs | 12 +++ .../GraphBlackboard/BlackboardField.cs.meta | 3 + .../GraphBlackboard/BlackboardProperty.meta | 3 + .../BlackboardProperty/BlackboardProperty.cs | 14 +++ .../BlackboardProperty.cs.meta | 3 + ...gNodeData.cs => BlackboardDragNodeData.cs} | 4 +- ...cs.meta => BlackboardDragNodeData.cs.meta} | 0 TNode/RuntimeCache/RuntimeCache.cs | 3 +- 9 files changed, 100 insertions(+), 40 deletions(-) create mode 100644 TNode/Editor/GraphBlackboard/BlackboardField.cs create mode 100644 TNode/Editor/GraphBlackboard/BlackboardField.cs.meta create mode 100644 TNode/Editor/GraphBlackboard/BlackboardProperty.meta create mode 100644 TNode/Editor/GraphBlackboard/BlackboardProperty/BlackboardProperty.cs create mode 100644 TNode/Editor/GraphBlackboard/BlackboardProperty/BlackboardProperty.cs.meta rename TNode/Models/{BlackDragNodeData.cs => BlackboardDragNodeData.cs} (75%) rename TNode/Models/{BlackDragNodeData.cs.meta => BlackboardDragNodeData.cs.meta} (100%) diff --git a/TNode/Editor/BaseViews/DataGraphView.cs b/TNode/Editor/BaseViews/DataGraphView.cs index 6312cf7..baa2227 100644 --- a/TNode/Editor/BaseViews/DataGraphView.cs +++ b/TNode/Editor/BaseViews/DataGraphView.cs @@ -4,8 +4,10 @@ using System.Linq; using System.Reflection; using TNode.BaseViews; using TNode.Cache; +using TNode.Editor.GraphBlackboard; using TNode.Editor.Inspector; using TNode.Editor.Model; + using TNode.Models; using Unity.VisualScripting; using UnityEditor; @@ -109,6 +111,11 @@ namespace TNode.Editor.BaseViews{ } */ public abstract class DataGraphView:GraphView,IDataGraphView where T:GraphData{ + #region variablesandproperties + + + + private T _data; private bool _isInspectorOn; @@ -117,6 +124,7 @@ namespace TNode.Editor.BaseViews{ public GraphEditor Owner; private Dictionary _nodeDict = new(); private Blackboard _blackboard; + public T Data{ get{ return _data; } @@ -129,11 +137,14 @@ namespace TNode.Editor.BaseViews{ } } public event DataChangedEventHandler OnDataChanged; + #endregion public delegate void DataChangedEventHandler(object sender, DataChangedEventArgs e); //A Constructor for the DataGraphView ,never to override it + + + #region construct default behaviour public DataGraphView(){ - styleSheets.Add(Resources.Load("GraphViewBackground")); var grid = new GridBackground(); Insert(0,grid); @@ -142,6 +153,7 @@ namespace TNode.Editor.BaseViews{ this.AddManipulator(new SelectionDragger()); this.AddManipulator(new RectangleSelector()); SetupZoom(ContentZoomer.DefaultMinScale, ContentZoomer.DefaultMaxScale); + RegisterDragEvent(); OnInit(); } private void ConstructDefaultBehaviour(){ @@ -150,10 +162,7 @@ namespace TNode.Editor.BaseViews{ } public void ConstructViewContextualMenu(){ - - //Rebuild the contextual menu - - this.RegisterCallback(evt => { + RegisterCallback(evt => { Vector2 editorPosition = Owner==null?Vector2.zero:Owner.position.position; //Remove all the previous menu items evt.menu.MenuItems().Clear(); @@ -164,11 +173,50 @@ namespace TNode.Editor.BaseViews{ searchWindow.Setup(typeof(T),this,Owner); SearchWindow.Open(searchWindowContext, searchWindow); }); - }); - } + public void RegisterDragEvent(){ + RegisterCallback(OnDragUpdated); + RegisterCallback(OnDragPerform); + } + #endregion + + private void OnDragPerform(DragPerformEvent evt){ + + if (DragAndDrop.GetGenericData("DragSelection") is List{Count: > 0} data){ + var blackboardFields = data.OfType(); + foreach (var selectable in blackboardFields){ + if(selectable is { } field) { + //Make a constructor of BlackboardDragNodeData by reflection + var specifiedType = + typeof(BlackboardDragNodeData<>).MakeGenericType(field.BlackboardProperty.PropertyType); + //get specific constructor of specified type with two parameters, one is a string ,another is a blackboarddata + var constructor = specifiedType.GetConstructor(new[] {typeof(string),typeof(BlackboardData)}); + //create a new instance of the specified type with the constructor and the two parameters + if (constructor != null){ + var dragNodeData = constructor.Invoke(new object[] + {field.BlackboardProperty.PropertyName, _data.blackboardData}) as NodeData; + this.AddTNode(dragNodeData,new Rect(Owner.position.position+evt.mousePosition,new Vector2(100,100))); + } + + } + } + } + } + + private void OnDragUpdated(DragUpdatedEvent evt){ + Debug.Log(evt); + + //check if the drag data is BlackboardField + + if (DragAndDrop.GetGenericData("DragSelection") is List{Count: > 0} data){ + DragAndDrop.visualMode = DragAndDropVisualMode.Move; + + } + + + } private void OnInit(){ ConstructDefaultBehaviour(); OnGraphViewCreate(); @@ -267,36 +315,8 @@ namespace TNode.Editor.BaseViews{ .GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)){ Debug.Log(field); //if the field is MonoBehaviour,add a property field for blackboard - if (typeof(UnityEngine.Object).IsAssignableFrom(field.FieldType)){ - var propertyField = new BlackboardField(null, field.Name, null){ - }; - _blackboard.Add(propertyField); - //register a drag event for the property field to drag the object from blackboard to the graph - - propertyField.RegisterCallback(evt => { - if (evt.target is GraphView graphView){ - var type = field.FieldType; - //Get Generic Constructor of the BlackDragNodeData<> - var genericConstructor = typeof(BlackDragNodeData<>).MakeGenericType(type).GetConstructor( - BindingFlags.Instance | BindingFlags.NonPublic, - null, - new Type[]{typeof(string), typeof(object)}, - null); - if (genericConstructor != null){ - NodeData nodeData = null; - nodeData = - genericConstructor.Invoke(null, new object[]{field.Name, _data.blackboardData}) as NodeData; - this.AddTNode(nodeData, new Rect(evt.localMousePosition, new Vector2(200, 200))); - } - } - }); - } - - if (typeof(string).IsAssignableFrom(field.FieldType)){ - var propertyField = new BlackboardField(null, field.Name, null){ - }; - _blackboard.Add(propertyField); - } + var propertyField = new BlackboardPropertyField(new BlackboardProperty(field.Name,field.FieldType)); + _blackboard.Add(propertyField); } } @@ -398,6 +418,10 @@ namespace TNode.Editor.BaseViews{ OnGraphViewDestroy(); } + public bool IsDroppable(){ + return true; + } + public void AddTNode(NodeData nodeData, Rect rect){ if (NodeEditorExtensions.CreateNodeViewFromNodeType(nodeData.GetType()) is Node nodeView){ nodeView.SetPosition(rect); diff --git a/TNode/Editor/GraphBlackboard/BlackboardField.cs b/TNode/Editor/GraphBlackboard/BlackboardField.cs new file mode 100644 index 0000000..87f5d9d --- /dev/null +++ b/TNode/Editor/GraphBlackboard/BlackboardField.cs @@ -0,0 +1,12 @@ +using UnityEditor.Experimental.GraphView; + +namespace TNode.Editor.GraphBlackboard{ + public class BlackboardPropertyField:BlackboardField{ + public BlackboardProperty BlackboardProperty; + public BlackboardPropertyField(BlackboardProperty blackboardProperty):base(null,blackboardProperty.PropertyName,null){ + BlackboardProperty = blackboardProperty; + } + + + } +} \ No newline at end of file diff --git a/TNode/Editor/GraphBlackboard/BlackboardField.cs.meta b/TNode/Editor/GraphBlackboard/BlackboardField.cs.meta new file mode 100644 index 0000000..e30c407 --- /dev/null +++ b/TNode/Editor/GraphBlackboard/BlackboardField.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 5603912d8c2b4d71878f76a7eb5915a7 +timeCreated: 1657033185 \ No newline at end of file diff --git a/TNode/Editor/GraphBlackboard/BlackboardProperty.meta b/TNode/Editor/GraphBlackboard/BlackboardProperty.meta new file mode 100644 index 0000000..85b9875 --- /dev/null +++ b/TNode/Editor/GraphBlackboard/BlackboardProperty.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 35fceca3e7c849279ed5bee0a5ee3225 +timeCreated: 1657041797 \ No newline at end of file diff --git a/TNode/Editor/GraphBlackboard/BlackboardProperty/BlackboardProperty.cs b/TNode/Editor/GraphBlackboard/BlackboardProperty/BlackboardProperty.cs new file mode 100644 index 0000000..d7dff1a --- /dev/null +++ b/TNode/Editor/GraphBlackboard/BlackboardProperty/BlackboardProperty.cs @@ -0,0 +1,14 @@ +using System; + +namespace TNode.Editor.GraphBlackboard{ + public class BlackboardProperty{ + public string PropertyName; + public Type PropertyType; + // public RuntimeCache.RuntimeCache.GetValueDelegate GetValue; + // public RuntimeCache.RuntimeCache.SetValueDelegate SetValue; + public BlackboardProperty(string propertyName, Type propertyType){ + PropertyName = propertyName; + PropertyType = propertyType; + } + } +} \ No newline at end of file diff --git a/TNode/Editor/GraphBlackboard/BlackboardProperty/BlackboardProperty.cs.meta b/TNode/Editor/GraphBlackboard/BlackboardProperty/BlackboardProperty.cs.meta new file mode 100644 index 0000000..c0b848a --- /dev/null +++ b/TNode/Editor/GraphBlackboard/BlackboardProperty/BlackboardProperty.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: b022203e15244da5bcfbf7932e7dd30c +timeCreated: 1657034160 \ No newline at end of file diff --git a/TNode/Models/BlackDragNodeData.cs b/TNode/Models/BlackboardDragNodeData.cs similarity index 75% rename from TNode/Models/BlackDragNodeData.cs rename to TNode/Models/BlackboardDragNodeData.cs index 4876f25..3b75c22 100644 --- a/TNode/Models/BlackDragNodeData.cs +++ b/TNode/Models/BlackboardDragNodeData.cs @@ -4,7 +4,7 @@ using TNode.Attribute.Ports; using TNode.RuntimeCache; namespace TNode.Models{ - public class BlackDragNodeData:NodeData where T:BlackboardData{ + public class BlackboardDragNodeData:NodeData where T:BlackboardData{ [JsonIgnore] private string _blackDragData; [JsonIgnore] @@ -12,7 +12,7 @@ namespace TNode.Models{ [Output] public T Value => _blackboardData.GetValue(_blackDragData); - public BlackDragNodeData(string blackDragData,T blackboardData){ + public BlackboardDragNodeData(string blackDragData,T blackboardData){ _blackDragData = blackDragData; _blackboardData = blackboardData; } diff --git a/TNode/Models/BlackDragNodeData.cs.meta b/TNode/Models/BlackboardDragNodeData.cs.meta similarity index 100% rename from TNode/Models/BlackDragNodeData.cs.meta rename to TNode/Models/BlackboardDragNodeData.cs.meta diff --git a/TNode/RuntimeCache/RuntimeCache.cs b/TNode/RuntimeCache/RuntimeCache.cs index 11bc35b..c63aea1 100644 --- a/TNode/RuntimeCache/RuntimeCache.cs +++ b/TNode/RuntimeCache/RuntimeCache.cs @@ -15,6 +15,7 @@ namespace TNode.RuntimeCache{ } //delegate return a value from a nodedata public delegate object GetValueDelegate(IModel nodeData); + public delegate object SetValueDelegate(IModel nodeData,object value); public readonly Dictionary> CachedDelegatesForGettingValue = new (); @@ -52,7 +53,7 @@ namespace TNode.RuntimeCache{ } - + } public static class RuntimeExtension{ From 1e16ddda5ccf823c4e29ffb4ef1cc1b21d16132a Mon Sep 17 00:00:00 2001 From: taoria <445625470@qq.com> Date: Wed, 6 Jul 2022 20:55:49 +0800 Subject: [PATCH 3/5] chore: minor work around 1.dragging a property from blackboard now create a node with an output port 2.add a rename text field to modify node's title fast --- TNode/Editor/BaseViews/DataGraphView.cs | 80 +++++++++---------- TNode/Editor/BaseViews/NodeView.cs | 46 +++++++++++ TNode/Editor/Cache/NodeEditorExtensions.cs | 3 + TNode/Editor/Manipulators.meta | 3 + .../Editor/Search/NodeSearchWindowProvider.cs | 4 +- .../{NodeHelper.cs => NodeCreator.cs} | 2 +- ...NodeHelper.cs.meta => NodeCreator.cs.meta} | 0 TNode/JsonSerialize/JsonSerializeTool.cs | 4 +- TNode/Models/BlackboardDragNodeData.cs | 10 +-- 9 files changed, 103 insertions(+), 49 deletions(-) create mode 100644 TNode/Editor/Manipulators.meta rename TNode/Editor/Tools/NodeCreator/{NodeHelper.cs => NodeCreator.cs} (94%) rename TNode/Editor/Tools/NodeCreator/{NodeHelper.cs.meta => NodeCreator.cs.meta} (100%) diff --git a/TNode/Editor/BaseViews/DataGraphView.cs b/TNode/Editor/BaseViews/DataGraphView.cs index baa2227..456cb21 100644 --- a/TNode/Editor/BaseViews/DataGraphView.cs +++ b/TNode/Editor/BaseViews/DataGraphView.cs @@ -7,7 +7,7 @@ using TNode.Cache; using TNode.Editor.GraphBlackboard; using TNode.Editor.Inspector; using TNode.Editor.Model; - +using TNode.Editor.Tools.NodeCreator; using TNode.Models; using Unity.VisualScripting; using UnityEditor; @@ -111,7 +111,7 @@ namespace TNode.Editor.BaseViews{ } */ public abstract class DataGraphView:GraphView,IDataGraphView where T:GraphData{ - #region variablesandproperties + #region variables and properties @@ -138,7 +138,10 @@ namespace TNode.Editor.BaseViews{ } public event DataChangedEventHandler OnDataChanged; #endregion + #region event declarations public delegate void DataChangedEventHandler(object sender, DataChangedEventArgs e); + + #endregion //A Constructor for the DataGraphView ,never to override it @@ -176,12 +179,19 @@ namespace TNode.Editor.BaseViews{ }); } + private void OnInit(){ + ConstructDefaultBehaviour(); + OnGraphViewCreate(); + } public void RegisterDragEvent(){ RegisterCallback(OnDragUpdated); RegisterCallback(OnDragPerform); } + #endregion + #region event callbakc + private void OnDragPerform(DragPerformEvent evt){ if (DragAndDrop.GetGenericData("DragSelection") is List{Count: > 0} data){ @@ -191,17 +201,12 @@ namespace TNode.Editor.BaseViews{ //Make a constructor of BlackboardDragNodeData by reflection var specifiedType = typeof(BlackboardDragNodeData<>).MakeGenericType(field.BlackboardProperty.PropertyType); - //get specific constructor of specified type with two parameters, one is a string ,another is a blackboarddata - var constructor = specifiedType.GetConstructor(new[] {typeof(string),typeof(BlackboardData)}); - //create a new instance of the specified type with the constructor and the two parameters - if (constructor != null){ - var dragNodeData = constructor.Invoke(new object[] - {field.BlackboardProperty.PropertyName, _data.blackboardData}) as NodeData; - this.AddTNode(dragNodeData,new Rect(Owner.position.position+evt.mousePosition,new Vector2(100,100))); - } - + //Create a new instance of specified type + var dragNodeData = NodeCreator.InstantiateNodeData(specifiedType); + this.AddTNode(dragNodeData,new Rect(evt.mousePosition,new Vector2(200,200))); } } + } } @@ -217,10 +222,11 @@ namespace TNode.Editor.BaseViews{ } - private void OnInit(){ - ConstructDefaultBehaviour(); - OnGraphViewCreate(); - } + + #endregion + + + public void ResetGraphView(){ //Clear all nodes foreach (var node in nodes){ @@ -268,7 +274,7 @@ namespace TNode.Editor.BaseViews{ - + public virtual void CreateInspector(){ NodeInspector nodeInspector = new NodeInspector(); this.Add(nodeInspector); @@ -276,13 +282,13 @@ namespace TNode.Editor.BaseViews{ _isInspectorOn = true; } - public void CreateMiniMap(Rect rect){ + public virtual void CreateMiniMap(Rect rect){ var miniMap = new MiniMap(); this.Add(miniMap); miniMap.SetPosition(rect); } - public void CreateBlackboard(){ + public virtual void CreateBlackboard(){ _blackboard = new Blackboard(); //Blackboard add "Add Node" button // blackboard.Add(new BlackboardSection(){ @@ -370,11 +376,10 @@ namespace TNode.Editor.BaseViews{ } } private void SaveEdge(){ + var links = new List(); foreach (var edge in edges){ var inputNode = edge.input.node as INodeView; var outputNode = edge.output.node as INodeView; - var links = new List(); - Debug.Log($"Edge{inputNode},{outputNode}"); if (inputNode != null && outputNode != null){ var inputNodeData = inputNode.GetNodeData(); var outputNodeData = outputNode.GetNodeData(); @@ -388,17 +393,16 @@ namespace TNode.Editor.BaseViews{ }); links.Add(newNodeLink); } - - _data.nodeLinks = links; } + + _data.nodeLinks = links; } private void SaveGraphData(){ _data.NodeDictionary.Clear(); - + _data.nodeLinks.Clear(); SaveNode(); SaveEdge(); - EditorUtility.SetDirty(_data); } @@ -436,7 +440,6 @@ namespace TNode.Editor.BaseViews{ } } }); - if(nodeView is INodeView nodeViewInterface){ nodeViewInterface.SetNodeData(nodeData); } @@ -448,30 +451,27 @@ namespace TNode.Editor.BaseViews{ menu.AddItem(new GUIContent("Delete"), false, () => { RemoveElement(nodeView); if (nodeView is INodeView tNodeView){ - var nodeData1 = tNodeView.GetNodeData(); - _data.NodeDictionary.Remove(nodeData1.id); - _nodeDict.Remove(nodeData1.id); - //Break all edges connected to this node - foreach (var edge in edges){ - if (edge.input.node == nodeView || edge.output.node == nodeView){ - RemoveElement(edge); - } - } - Owner.graphEditorData.graphElementsData.RemoveAll(x => x.guid == nodeData1.id); + RemoveTNode(tNodeView.GetNodeData()); } }); menu.ShowAsContext(); }); - - - - } } public void RemoveTNode(NodeData nodeData){ - throw new NotImplementedException(); + + _data.NodeDictionary.Remove(nodeData.id); + var nodeView = _nodeDict[nodeData.id]; + _nodeDict.Remove(nodeData.id); + //Break all edges connected to this node + foreach (var edge in edges){ + if (edge.input.node == nodeView || edge.output.node == nodeView){ + RemoveElement(edge); + } + } + Owner.graphEditorData.graphElementsData.RemoveAll(x => x.guid == nodeData.id); } } diff --git a/TNode/Editor/BaseViews/NodeView.cs b/TNode/Editor/BaseViews/NodeView.cs index 15c6636..b7caa5d 100644 --- a/TNode/Editor/BaseViews/NodeView.cs +++ b/TNode/Editor/BaseViews/NodeView.cs @@ -7,6 +7,7 @@ using UnityEditor; using UnityEditor.Experimental.GraphView; using UnityEditor.UIElements; using UnityEngine; +using UnityEngine.UIElements; namespace TNode.Editor.BaseViews{ @@ -41,10 +42,13 @@ namespace TNode.Editor.BaseViews{ protected NodeView(){ OnDataChanged+=OnDataChangedHandler; + _nodeInspectorInNode = new NodeInspectorInNode(){ name = "nodeInspectorInNode" }; this.extensionContainer.Add(_nodeInspectorInNode); + + BuildDoubleClickRename(); } private void OnDataChangedHandler(T obj){ this.title = _data.nodeName; @@ -83,6 +87,48 @@ namespace TNode.Editor.BaseViews{ } } + public void StartARenameTitleTextField(){ + var textField = new TextField{ + value = title, + style ={ + //Make the text filed overlap the title container + position = Position.Absolute, + left = 0, + top = 0, + width = titleContainer.layout.width, + height = titleContainer.layout.height + } + }; + textField.StretchToParentSize(); + textField.RegisterValueChangedCallback(evt2 => { + title = evt2.newValue; + }); + textField.RegisterCallback(evt2 => { + title = textField.text; + ((NodeDataWrapper)_data).SetValue("nodeName",textField.text); + textField.RemoveFromHierarchy(); + }); + //if enter is pressed ,set the title and remove the text field + textField.RegisterCallback(evt2 => { + if (evt2.keyCode == KeyCode.Return){ + title = textField.text; + ((NodeDataWrapper)_data).SetValue("nodeName",textField.text); + textField.RemoveFromHierarchy(); + } + }); + + titleContainer.Add(textField); + textField.Focus(); + } + private void BuildDoubleClickRename(){ + //when double click titleContainer ,create a textfield to rename the node + titleContainer.RegisterCallback(evt => { + if (evt.clickCount == 2){ + StartARenameTitleTextField(); + } + }); + } + public void SetNodeData(NodeData nodeData){ Data = (T)nodeData; diff --git a/TNode/Editor/Cache/NodeEditorExtensions.cs b/TNode/Editor/Cache/NodeEditorExtensions.cs index 6338d97..80cf405 100644 --- a/TNode/Editor/Cache/NodeEditorExtensions.cs +++ b/TNode/Editor/Cache/NodeEditorExtensions.cs @@ -145,6 +145,9 @@ namespace TNode.Cache{ } public static object CreateNodeViewFromNodeType(Type t){ //Check the generic type of NodeView by t + Debug.Log(t); + Debug.Log(t.ToString()); + Debug.Log(typeof(NodeData).IsAssignableFrom(t)); var type = typeof(NodeView<>).MakeGenericType(t); if (NodeEditorSingleton.Instance.FromGenericToSpecific.ContainsKey(type)){ var implementedType = NodeEditorSingleton.Instance.FromGenericToSpecific[type]; diff --git a/TNode/Editor/Manipulators.meta b/TNode/Editor/Manipulators.meta new file mode 100644 index 0000000..f9c9614 --- /dev/null +++ b/TNode/Editor/Manipulators.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 400542f3cec140e2b55e2bcf637b2d9b +timeCreated: 1657009018 \ No newline at end of file diff --git a/TNode/Editor/Search/NodeSearchWindowProvider.cs b/TNode/Editor/Search/NodeSearchWindowProvider.cs index 58a3c1d..e694f4a 100644 --- a/TNode/Editor/Search/NodeSearchWindowProvider.cs +++ b/TNode/Editor/Search/NodeSearchWindowProvider.cs @@ -48,8 +48,8 @@ namespace TNode.Editor{ //Check if type is derived from NodeData if (typeof(NodeData).IsAssignableFrom(type)){ //Make an instance of the type - if (NodeHelper.InstantiateNodeData(type) is { } nodeData){ - nodeData.nodeName = "New Node"; + if (NodeCreator.InstantiateNodeData(type) is { } nodeData){ + nodeData.nodeName = $"New {type.Name}"; ((IDataGraphView) _graphView).AddTNode(nodeData, new Rect(localPos.x, localPos.y, 100, 100)); } } diff --git a/TNode/Editor/Tools/NodeCreator/NodeHelper.cs b/TNode/Editor/Tools/NodeCreator/NodeCreator.cs similarity index 94% rename from TNode/Editor/Tools/NodeCreator/NodeHelper.cs rename to TNode/Editor/Tools/NodeCreator/NodeCreator.cs index adf3b15..416e8a1 100644 --- a/TNode/Editor/Tools/NodeCreator/NodeHelper.cs +++ b/TNode/Editor/Tools/NodeCreator/NodeCreator.cs @@ -2,7 +2,7 @@ using TNode.Models; namespace TNode.Editor.Tools.NodeCreator{ - public static class NodeHelper{ + public static class NodeCreator{ /// /// always use this to create a new node. diff --git a/TNode/Editor/Tools/NodeCreator/NodeHelper.cs.meta b/TNode/Editor/Tools/NodeCreator/NodeCreator.cs.meta similarity index 100% rename from TNode/Editor/Tools/NodeCreator/NodeHelper.cs.meta rename to TNode/Editor/Tools/NodeCreator/NodeCreator.cs.meta diff --git a/TNode/JsonSerialize/JsonSerializeTool.cs b/TNode/JsonSerialize/JsonSerializeTool.cs index e886ccf..58888ba 100644 --- a/TNode/JsonSerialize/JsonSerializeTool.cs +++ b/TNode/JsonSerialize/JsonSerializeTool.cs @@ -21,7 +21,9 @@ namespace TNode.JsonSerialize{ DateFormatString = "yyyy-MM-dd HH:mm:ss", Converters = new List { new Vector3Converter() }, TypeNameHandling = TypeNameHandling.Auto, - ContractResolver = new WritablePropertiesOnlyResolver() + ContractResolver = new WritablePropertiesOnlyResolver(), + Formatting = Formatting.Indented + }; diff --git a/TNode/Models/BlackboardDragNodeData.cs b/TNode/Models/BlackboardDragNodeData.cs index 3b75c22..5119283 100644 --- a/TNode/Models/BlackboardDragNodeData.cs +++ b/TNode/Models/BlackboardDragNodeData.cs @@ -4,17 +4,17 @@ using TNode.Attribute.Ports; using TNode.RuntimeCache; namespace TNode.Models{ - public class BlackboardDragNodeData:NodeData where T:BlackboardData{ + public class BlackboardDragNodeData:NodeData{ [JsonIgnore] private string _blackDragData; [JsonIgnore] - private T _blackboardData; + private BlackboardData _blackboardData; [Output] public T Value => _blackboardData.GetValue(_blackDragData); - public BlackboardDragNodeData(string blackDragData,T blackboardData){ - _blackDragData = blackDragData; - _blackboardData = blackboardData; + + public BlackboardDragNodeData(){ + } } From f6d5632a0bf02b514d1a0462a27ad587b94eb9e4 Mon Sep 17 00:00:00 2001 From: taoria <445625470@qq.com> Date: Thu, 7 Jul 2022 20:22:48 +0800 Subject: [PATCH 4/5] 1.Add an new property drawer for graph --- TNode/Attribute/Ports/BatchInputAttribute.cs | 5 ++++ .../Ports/BatchInputAttribute.cs.meta | 3 ++ TNode/Attribute/Ports/BatchOutputAttribute.cs | 12 ++++++++ .../Ports/BatchOutputAttribute.cs.meta | 3 ++ TNode/Attribute/Ports/InputAttribute.cs | 7 +---- TNode/Attribute/Ports/PortAttribute.cs | 18 +----------- TNode/Attribute/ShowInNodeViewAttribute.cs | 1 + TNode/Editor/BaseViews/DataGraphView.cs | 8 ++---- TNode/Editor/BaseViews/NodeView.cs | 1 - TNode/Editor/Cache/NodeEditorExtensions.cs | 28 +++++++++---------- TNode/Editor/GraphEditor.cs | 2 +- .../InspectorImplementation/EnumFieldItem.cs | 20 +++++++++++++ .../EnumFieldItem.cs.meta | 3 ++ TNode/Editor/Inspector/InspectorItem.cs | 21 ++++++++------ .../Editor/Inspector/InspectorItemFactory.cs | 25 +++++++++++++++-- TNode/Editor/Inspector/NodeInspectorInNode.cs | 23 +++++++++------ TNode/Editor/Inspector/TinyInspectorItem.cs | 13 --------- .../Inspector/TinyInspectorItem.cs.meta | 3 -- .../Search/BlackboardSearchWindowProvider.cs | 17 +++++++++-- TNode/Models/GraphData.cs | 1 - 20 files changed, 129 insertions(+), 85 deletions(-) create mode 100644 TNode/Attribute/Ports/BatchInputAttribute.cs create mode 100644 TNode/Attribute/Ports/BatchInputAttribute.cs.meta create mode 100644 TNode/Attribute/Ports/BatchOutputAttribute.cs create mode 100644 TNode/Attribute/Ports/BatchOutputAttribute.cs.meta create mode 100644 TNode/Editor/Inspector/InspectorImplementation/EnumFieldItem.cs create mode 100644 TNode/Editor/Inspector/InspectorImplementation/EnumFieldItem.cs.meta delete mode 100644 TNode/Editor/Inspector/TinyInspectorItem.cs delete mode 100644 TNode/Editor/Inspector/TinyInspectorItem.cs.meta diff --git a/TNode/Attribute/Ports/BatchInputAttribute.cs b/TNode/Attribute/Ports/BatchInputAttribute.cs new file mode 100644 index 0000000..4786d55 --- /dev/null +++ b/TNode/Attribute/Ports/BatchInputAttribute.cs @@ -0,0 +1,5 @@ +namespace TNode.Attribute.Ports{ + public class BatchInputAttribute{ + + } +} \ No newline at end of file diff --git a/TNode/Attribute/Ports/BatchInputAttribute.cs.meta b/TNode/Attribute/Ports/BatchInputAttribute.cs.meta new file mode 100644 index 0000000..2847ec0 --- /dev/null +++ b/TNode/Attribute/Ports/BatchInputAttribute.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 8745aaf35940443693af378c8214060e +timeCreated: 1657190813 \ No newline at end of file diff --git a/TNode/Attribute/Ports/BatchOutputAttribute.cs b/TNode/Attribute/Ports/BatchOutputAttribute.cs new file mode 100644 index 0000000..9e96754 --- /dev/null +++ b/TNode/Attribute/Ports/BatchOutputAttribute.cs @@ -0,0 +1,12 @@ +using System; +using UnityEditor.Experimental.GraphView; + +namespace TNode.Attribute.Ports{ + /// + /// Batch out port attribute could specify a batch out port,allowing large scale calculation. + /// + [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)] + public class BatchOutputAttribute:PortAttribute{ + + } +} \ No newline at end of file diff --git a/TNode/Attribute/Ports/BatchOutputAttribute.cs.meta b/TNode/Attribute/Ports/BatchOutputAttribute.cs.meta new file mode 100644 index 0000000..e5a345e --- /dev/null +++ b/TNode/Attribute/Ports/BatchOutputAttribute.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 0a6ca9cc801d4db3b73ee59cf0aef38e +timeCreated: 1657190648 \ No newline at end of file diff --git a/TNode/Attribute/Ports/InputAttribute.cs b/TNode/Attribute/Ports/InputAttribute.cs index 0ac3ed1..1312c34 100644 --- a/TNode/Attribute/Ports/InputAttribute.cs +++ b/TNode/Attribute/Ports/InputAttribute.cs @@ -7,11 +7,6 @@ namespace TNode.Attribute{ [MeansImplicitUse] [AttributeUsage(AttributeTargets.Property, AllowMultiple = true)] public class InputAttribute : PortAttribute{ - public InputAttribute(string portName, Type nodeLinkType, Port.Capacity capacity, string portAccepted = "*") : base(portName, nodeLinkType, capacity, portAccepted){ - } - public InputAttribute(Type nodeLinkType, Port.Capacity capacity, string portAccepted="*") : base(nodeLinkType, capacity, portAccepted){ - } - public InputAttribute(string portName="*",string portAccepted = "*") :base(portName, typeof(NodeLink),Port.Capacity.Multi,portAccepted){ - } + } } \ No newline at end of file diff --git a/TNode/Attribute/Ports/PortAttribute.cs b/TNode/Attribute/Ports/PortAttribute.cs index 1b983eb..72fb46e 100644 --- a/TNode/Attribute/Ports/PortAttribute.cs +++ b/TNode/Attribute/Ports/PortAttribute.cs @@ -7,22 +7,6 @@ namespace TNode.Attribute{ [AttributeUsage(AttributeTargets.Property, AllowMultiple = true)] public class PortAttribute:System.Attribute{ - public string PortName; - public string PortAccepted; - public Type NodeLinkType; - public Port.Capacity Capacity; - - public PortAttribute(string portName, Type nodeLinkType, Port.Capacity capacity,string portAccepted="*"){ - PortName = portName; - PortAccepted = portAccepted; - NodeLinkType = nodeLinkType; - Capacity = capacity; - } - //Auto generate port name via variable use this attribute - public PortAttribute(Type nodeLinkType, Port.Capacity capacity, string portAccepted = "*"){ - PortAccepted = portAccepted; - NodeLinkType = nodeLinkType; - Capacity = capacity; - } + } } \ No newline at end of file diff --git a/TNode/Attribute/ShowInNodeViewAttribute.cs b/TNode/Attribute/ShowInNodeViewAttribute.cs index f2ffde9..d516534 100644 --- a/TNode/Attribute/ShowInNodeViewAttribute.cs +++ b/TNode/Attribute/ShowInNodeViewAttribute.cs @@ -2,6 +2,7 @@ namespace TNode.Attribute{ [AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = false)] + public class ShowInNodeViewAttribute:System.Attribute{ } diff --git a/TNode/Editor/BaseViews/DataGraphView.cs b/TNode/Editor/BaseViews/DataGraphView.cs index 456cb21..dac2122 100644 --- a/TNode/Editor/BaseViews/DataGraphView.cs +++ b/TNode/Editor/BaseViews/DataGraphView.cs @@ -261,8 +261,7 @@ namespace TNode.Editor.BaseViews{ input = inputNodeView.inputContainer.Q(edge.inPort.portName), output = outputNodeView.outputContainer.Q(edge.outPort.portName) }; - Debug.Log(edge.inPort.portName); - Debug.Log(edge.outPort.portName); + newEdge.input?.Connect(newEdge); newEdge.output?.Connect(newEdge); AddElement(newEdge); @@ -296,7 +295,7 @@ namespace TNode.Editor.BaseViews{ // }); // blackboard.addItemRequested = (item) => { // //Create a sub window for the blackboard to show the selection - // var subWindow = ScriptableObject.CreateInstance(); + // var subWindow = ScriptableObject.CreateNodeComponentFromGenericType(); // }; // //Set black board to left side of the view @@ -315,11 +314,9 @@ namespace TNode.Editor.BaseViews{ if (_data.blackboardData == null) return; } - Debug.Log(_data.blackboardData); //Iterate field of the blackboard and add a button for each field foreach (var field in _data.blackboardData.GetType() .GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)){ - Debug.Log(field); //if the field is MonoBehaviour,add a property field for blackboard var propertyField = new BlackboardPropertyField(new BlackboardProperty(field.Name,field.FieldType)); _blackboard.Add(propertyField); @@ -432,7 +429,6 @@ namespace TNode.Editor.BaseViews{ AddElement(nodeView); //Add a select callback to the nodeView nodeView.RegisterCallback(evt => { - Debug.Log("NodeView Selected"); if (evt.clickCount == 1){ if (_isInspectorOn){ _nodeInspector.Data = nodeData; diff --git a/TNode/Editor/BaseViews/NodeView.cs b/TNode/Editor/BaseViews/NodeView.cs index b7caa5d..bcf74b8 100644 --- a/TNode/Editor/BaseViews/NodeView.cs +++ b/TNode/Editor/BaseViews/NodeView.cs @@ -76,7 +76,6 @@ namespace TNode.Editor.BaseViews{ } } foreach (var propertyInfo in propertyInfos){ - Debug.Log(propertyInfos); var attribute = propertyInfo.GetCustomAttributes(typeof(InputAttribute),true); if (attribute.Length > 0){ Port port = InstantiatePort(Orientation.Horizontal, Direction.Input,Port.Capacity.Multi,propertyInfo.PropertyType); diff --git a/TNode/Editor/Cache/NodeEditorExtensions.cs b/TNode/Editor/Cache/NodeEditorExtensions.cs index 80cf405..f238eb8 100644 --- a/TNode/Editor/Cache/NodeEditorExtensions.cs +++ b/TNode/Editor/Cache/NodeEditorExtensions.cs @@ -92,32 +92,33 @@ namespace TNode.Cache{ } //Outer wrapper for the singleton class public static class NodeEditorExtensions{ - public static T CreateInstance(){ + public static T CreateNodeComponentFromGenericType(){ var implementedType = NodeEditorSingleton.Instance.FromGenericToSpecific[typeof(T)]; var instance = (T)Activator.CreateInstance(implementedType); return instance; } - public static object CreateInstance(Type t){ + public static object CreateNodeComponentFromGenericType(Type t){ if (NodeEditorSingleton.Instance.FromGenericToSpecific.ContainsKey(t)){ var implementedType = NodeEditorSingleton.Instance.FromGenericToSpecific[t]; var instance = Activator.CreateInstance(implementedType); return instance; } - else{ - Debug.Log($"No given type found {t}"); - //check if t is a generic type node view - if (t is{IsGenericType: true} && t.GetGenericTypeDefinition() == typeof(NodeView<>)){ - var instance = Activator.CreateInstance(typeof(NodeView)); - return instance; - } - - return null; + Debug.Log($"No given type found {t}"); + //check if t is a generic type node view + if (t is{IsGenericType: true} && t.GetGenericTypeDefinition() == typeof(NodeView<>)){ + var instance = Activator.CreateInstance(typeof(NodeView)); + return instance; } + return null; } - public static bool HasSpecificType() where T : class{ + public static bool HasSpecificTypeComponent() where T : class{ return NodeEditorSingleton.Instance.FromGenericToSpecific.ContainsKey(typeof(T)); } + public static bool HasSpecificTypeComponent(Type t) { + + return NodeEditorSingleton.Instance.FromGenericToSpecific.ContainsKey(t); + } public static List GetGraphDataUsage(Type t){ if (NodeEditorSingleton.Instance.GraphDataUsage.ContainsKey(t)){ return NodeEditorSingleton.Instance.GraphDataUsage[t]; @@ -145,9 +146,6 @@ namespace TNode.Cache{ } public static object CreateNodeViewFromNodeType(Type t){ //Check the generic type of NodeView by t - Debug.Log(t); - Debug.Log(t.ToString()); - Debug.Log(typeof(NodeData).IsAssignableFrom(t)); var type = typeof(NodeView<>).MakeGenericType(t); if (NodeEditorSingleton.Instance.FromGenericToSpecific.ContainsKey(type)){ var implementedType = NodeEditorSingleton.Instance.FromGenericToSpecific[type]; diff --git a/TNode/Editor/GraphEditor.cs b/TNode/Editor/GraphEditor.cs index 7619b74..e045f39 100644 --- a/TNode/Editor/GraphEditor.cs +++ b/TNode/Editor/GraphEditor.cs @@ -36,7 +36,7 @@ namespace TNode.Editor{ } private void BuildGraphView(){ - _graphView = NodeEditorExtensions.CreateInstance>(); + _graphView = NodeEditorExtensions.CreateNodeComponentFromGenericType>(); rootVisualElement.Add(_graphView); _graphView.StretchToParentSize(); } diff --git a/TNode/Editor/Inspector/InspectorImplementation/EnumFieldItem.cs b/TNode/Editor/Inspector/InspectorImplementation/EnumFieldItem.cs new file mode 100644 index 0000000..148f9d7 --- /dev/null +++ b/TNode/Editor/Inspector/InspectorImplementation/EnumFieldItem.cs @@ -0,0 +1,20 @@ +using System; +using TNode.Attribute; +using UnityEngine; +using UnityEngine.UIElements; + +namespace TNode.Editor.Inspector.InspectorImplementation{ + [NodeComponent] + public class EnumFieldItem:InspectorItem{ + public EnumFieldItem() : base(){ + var field = new EnumField(); + Debug.Log("An Enum Field is created"); + CreateBindable(field); + OnDataChanged += () => { + + field.Init(Value); + Debug.Log(Value.GetType()); + }; + } + } +} \ No newline at end of file diff --git a/TNode/Editor/Inspector/InspectorImplementation/EnumFieldItem.cs.meta b/TNode/Editor/Inspector/InspectorImplementation/EnumFieldItem.cs.meta new file mode 100644 index 0000000..1a83a95 --- /dev/null +++ b/TNode/Editor/Inspector/InspectorImplementation/EnumFieldItem.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 6eb83a1255d545e5998c7b3efd1b0d69 +timeCreated: 1657193097 \ No newline at end of file diff --git a/TNode/Editor/Inspector/InspectorItem.cs b/TNode/Editor/Inspector/InspectorItem.cs index 829ac4b..278e215 100644 --- a/TNode/Editor/Inspector/InspectorItem.cs +++ b/TNode/Editor/Inspector/InspectorItem.cs @@ -6,8 +6,8 @@ using UnityEngine.UIElements; namespace TNode.Editor.Inspector{ public abstract class InspectorItem:VisualElement,INodeDataBinding { - private NodeData _bindingNodeData; - private string _bindingFieldName; + protected NodeData _bindingNodeData; + protected string _bindingFieldName; protected BaseField Bindable; protected event System.Action OnDataChanged; @@ -38,15 +38,19 @@ namespace TNode.Editor.Inspector{ } private T GetValue(){ - + var fieldInfo = _bindingNodeData.GetType().GetField(BindingPath, System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance); - //check field type - if (fieldInfo != null && fieldInfo.FieldType == typeof(T)){ + if (fieldInfo == null){ + throw new Exception("Null field info"); + } + if (fieldInfo.FieldType == typeof(T)){ return (T)fieldInfo.GetValue(BindingNodeData); } - else{ - Debug.LogError("Wrong Type for current node data"); + + if (fieldInfo.FieldType.IsEnum){ + return (T)fieldInfo.GetValue(BindingNodeData); } + Debug.LogError("Wrong Type for current node data"); return default; } @@ -75,7 +79,7 @@ namespace TNode.Editor.Inspector{ Bindable.UnregisterValueChangedCallback(OnInspectorItemValueChanged); } Bindable = bindable; - this.Add(Bindable); + Add(Bindable); Bindable?.RegisterValueChangedCallback(OnInspectorItemValueChanged); } private void OnDataChangedHandler(){ @@ -84,6 +88,7 @@ namespace TNode.Editor.Inspector{ Bindable.value = Value; Bindable.label = BindingPath; } + Debug.Log(Value.GetType()); } private void OnNodeDataValueChanged(NodeDataWrapper wrapper){ diff --git a/TNode/Editor/Inspector/InspectorItemFactory.cs b/TNode/Editor/Inspector/InspectorItemFactory.cs index be99391..9e5f9a7 100644 --- a/TNode/Editor/Inspector/InspectorItemFactory.cs +++ b/TNode/Editor/Inspector/InspectorItemFactory.cs @@ -11,9 +11,30 @@ namespace TNode.Editor.Inspector{ public InspectorItem Create(){ //Check type of GraphDataType - var hasSpecificType = NodeEditorExtensions.HasSpecificType>(); + var hasSpecificType = NodeEditorExtensions.HasSpecificTypeComponent>(); + if (hasSpecificType){ - return NodeEditorExtensions.CreateInstance>(); + return NodeEditorExtensions.CreateNodeComponentFromGenericType>(); + } + + if (typeof(T).IsEnum){ + + return NodeEditorExtensions.CreateNodeComponentFromGenericType(typeof(InspectorItem)) as InspectorItem; + } + return null; + } + + public INodeDataBindingBase Create(Type t){ + var genericType = typeof(InspectorItem<>).MakeGenericType(t); + var hasSpecificType = NodeEditorExtensions.HasSpecificTypeComponent(genericType); + + if (hasSpecificType){ + return NodeEditorExtensions.CreateNodeComponentFromGenericType(genericType) as INodeDataBindingBase; + } + + if (t.IsEnum){ + + return NodeEditorExtensions.CreateNodeComponentFromGenericType(typeof(InspectorItem)) as INodeDataBindingBase; } return null; } diff --git a/TNode/Editor/Inspector/NodeInspectorInNode.cs b/TNode/Editor/Inspector/NodeInspectorInNode.cs index 0268d98..e89603e 100644 --- a/TNode/Editor/Inspector/NodeInspectorInNode.cs +++ b/TNode/Editor/Inspector/NodeInspectorInNode.cs @@ -33,16 +33,21 @@ namespace TNode.Editor.Inspector{ if(!showInNodeViewAttribute) continue; //Invoke generic function Create<> of default inspector item factory to create an inspector item of appropriate type by reflection - MethodInfo methodInfo = inspectorItemFactory.GetType().GetMethod("Create", BindingFlags.Instance | BindingFlags.Public); - if (methodInfo != null){ - var genericMethod = methodInfo.MakeGenericMethod(type); - var createdItem = genericMethod.Invoke(inspectorItemFactory,null) as VisualElement; - Add(createdItem); - if (createdItem is INodeDataBindingBase castedItem){ - castedItem.BindingNodeData = _data; - castedItem.BindingPath = bindingPath; - } + var createdItem = inspectorItemFactory.Create(type); + if (createdItem is { } castedItem){ + castedItem.BindingNodeData = _data; + castedItem.BindingPath = bindingPath; } + Add((VisualElement)createdItem); + // MethodInfo methodInfo = inspectorItemFactory.GetType().GetMethod("Create", BindingFlags.Instance | BindingFlags.Public); + // if (methodInfo != null){ + // var genericMethod = methodInfo.MakeGenericMethod(type); + // Debug.Log(genericMethod); + // var createdItem = genericMethod.Invoke(inspectorItemFactory,null) as VisualElement; + // Add(createdItem); + // Debug.Log(createdItem?.GetType()); + // + // } } } } diff --git a/TNode/Editor/Inspector/TinyInspectorItem.cs b/TNode/Editor/Inspector/TinyInspectorItem.cs deleted file mode 100644 index 89186c9..0000000 --- a/TNode/Editor/Inspector/TinyInspectorItem.cs +++ /dev/null @@ -1,13 +0,0 @@ -using TNode.Models; -using UnityEngine.UIElements; - -namespace TNode.Editor.Inspector{ - /// - /// Tiny Inspector item is a simple inspector item inside a node view ,it monitor node data - /// - /// - public class TinyInspectorItem:VisualElement,INodeDataBinding{ - public string BindingPath{ get; set; } - public NodeData BindingNodeData{ get; set; } - } -} \ No newline at end of file diff --git a/TNode/Editor/Inspector/TinyInspectorItem.cs.meta b/TNode/Editor/Inspector/TinyInspectorItem.cs.meta deleted file mode 100644 index 5944c38..0000000 --- a/TNode/Editor/Inspector/TinyInspectorItem.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 7eeddeb28a5a475c85c85ceae3198778 -timeCreated: 1656142058 \ No newline at end of file diff --git a/TNode/Editor/Search/BlackboardSearchWindowProvider.cs b/TNode/Editor/Search/BlackboardSearchWindowProvider.cs index 53dfcbb..e0f5ed4 100644 --- a/TNode/Editor/Search/BlackboardSearchWindowProvider.cs +++ b/TNode/Editor/Search/BlackboardSearchWindowProvider.cs @@ -1,5 +1,16 @@ -namespace TNode.Editor{ - public class BlackboardSearchWindowProvider{ - +using System.Collections.Generic; +using UnityEditor.Experimental.GraphView; + +namespace TNode.Editor{ + public class BlackboardSearchWindowProvider:ISearchWindowProvider{ + + public List CreateSearchTree(SearchWindowContext context){ + throw new System.NotImplementedException(); + } + + public bool OnSelectEntry(SearchTreeEntry SearchTreeEntry, SearchWindowContext context){ + throw new System.NotImplementedException(); + } } + } \ No newline at end of file diff --git a/TNode/Models/GraphData.cs b/TNode/Models/GraphData.cs index 2d4d323..3937714 100644 --- a/TNode/Models/GraphData.cs +++ b/TNode/Models/GraphData.cs @@ -33,7 +33,6 @@ namespace TNode.Models{ var deserializedBlackboard = JsonConvert.DeserializeObject(jsonBlackboard,JsonSerializeTool.JsonSerializerSettings); blackboardData = deserializedBlackboard; - Debug.Log("hi"); } } } \ No newline at end of file From 6bacdb9eb45f94700637f32b316da97566080c04 Mon Sep 17 00:00:00 2001 From: taoria <445625470@qq.com> Date: Thu, 7 Jul 2022 23:45:01 +0800 Subject: [PATCH 5/5] chore: little work around on Blackboard drag node --- TNode/Attribute/Ports/BatchOutputAttribute.cs | 3 +- TNode/Attribute/Ports/InputAttribute.cs | 3 +- TNode/Attribute/Ports/OutputAttribute.cs | 5 +- TNode/Attribute/Ports/PortAttribute.cs | 18 ++++- TNode/Editor/Cache/NodeEditorExtensions.cs | 72 +++++++++++++++++-- TNode/Editor/Inspector/InspectorItem.cs | 1 - TNode/Editor/NodeViews.meta | 3 + .../Editor/{ => NodeViews}/DefaultNodeView.cs | 0 .../{ => NodeViews}/DefaultNodeView.cs.meta | 0 TNode/Editor/NodeViews/DragNodeView.cs | 15 ++++ TNode/Editor/NodeViews/DragNodeView.cs.meta | 3 + .../{BaseViews => NodeViews}/NodeView.cs | 43 ++++++++--- .../{BaseViews => NodeViews}/NodeView.cs.meta | 0 TNode/Models/BlackboardDragNodeData.cs | 4 +- TNode/RuntimeCache/RuntimeCache.cs | 5 ++ 15 files changed, 151 insertions(+), 24 deletions(-) create mode 100644 TNode/Editor/NodeViews.meta rename TNode/Editor/{ => NodeViews}/DefaultNodeView.cs (100%) rename TNode/Editor/{ => NodeViews}/DefaultNodeView.cs.meta (100%) create mode 100644 TNode/Editor/NodeViews/DragNodeView.cs create mode 100644 TNode/Editor/NodeViews/DragNodeView.cs.meta rename TNode/Editor/{BaseViews => NodeViews}/NodeView.cs (72%) rename TNode/Editor/{BaseViews => NodeViews}/NodeView.cs.meta (100%) diff --git a/TNode/Attribute/Ports/BatchOutputAttribute.cs b/TNode/Attribute/Ports/BatchOutputAttribute.cs index 9e96754..71a20c3 100644 --- a/TNode/Attribute/Ports/BatchOutputAttribute.cs +++ b/TNode/Attribute/Ports/BatchOutputAttribute.cs @@ -7,6 +7,7 @@ namespace TNode.Attribute.Ports{ /// [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)] public class BatchOutputAttribute:PortAttribute{ - + public BatchOutputAttribute(string name="") : base(name){ + } } } \ No newline at end of file diff --git a/TNode/Attribute/Ports/InputAttribute.cs b/TNode/Attribute/Ports/InputAttribute.cs index 1312c34..dd4b855 100644 --- a/TNode/Attribute/Ports/InputAttribute.cs +++ b/TNode/Attribute/Ports/InputAttribute.cs @@ -7,6 +7,7 @@ namespace TNode.Attribute{ [MeansImplicitUse] [AttributeUsage(AttributeTargets.Property, AllowMultiple = true)] public class InputAttribute : PortAttribute{ - + public InputAttribute(string name="", PortNameHandling nameHandling = PortNameHandling.Auto) : base(name, nameHandling){ + } } } \ No newline at end of file diff --git a/TNode/Attribute/Ports/OutputAttribute.cs b/TNode/Attribute/Ports/OutputAttribute.cs index 675d731..a0c3908 100644 --- a/TNode/Attribute/Ports/OutputAttribute.cs +++ b/TNode/Attribute/Ports/OutputAttribute.cs @@ -1,5 +1,6 @@ namespace TNode.Attribute.Ports{ - public class OutputAttribute:System.Attribute{ - + public class OutputAttribute:PortAttribute{ + public OutputAttribute(string name="", PortNameHandling nameHandling = PortNameHandling.Auto) : base(name, nameHandling){ + } } } \ No newline at end of file diff --git a/TNode/Attribute/Ports/PortAttribute.cs b/TNode/Attribute/Ports/PortAttribute.cs index 72fb46e..24feda5 100644 --- a/TNode/Attribute/Ports/PortAttribute.cs +++ b/TNode/Attribute/Ports/PortAttribute.cs @@ -3,10 +3,24 @@ using JetBrains.Annotations; using UnityEditor.Experimental.GraphView; namespace TNode.Attribute{ + + public enum PortNameHandling{ + Auto, + MemberName, + Manual, + Format, + MemberType + + } [MeansImplicitUse] [AttributeUsage(AttributeTargets.Property, AllowMultiple = true)] - public class PortAttribute:System.Attribute{ - + public readonly string Name; + public readonly PortNameHandling NameHandling; + + public PortAttribute(string name,PortNameHandling nameHandling=PortNameHandling.Auto){ + this.Name = name; + this.NameHandling = nameHandling; + } } } \ No newline at end of file diff --git a/TNode/Editor/Cache/NodeEditorExtensions.cs b/TNode/Editor/Cache/NodeEditorExtensions.cs index f238eb8..d21c96c 100644 --- a/TNode/Editor/Cache/NodeEditorExtensions.cs +++ b/TNode/Editor/Cache/NodeEditorExtensions.cs @@ -9,14 +9,37 @@ using TNode.Editor.Inspector; using TNode.Models; using UnityEditor.Experimental.GraphView; using UnityEngine; +using UnityEngine.TestTools.Utils; namespace TNode.Cache{ /// /// Internal singleton class for caching TNode reflection Data. /// + internal class NodeEditorTypeDictionary:Dictionary{ + //Custom camparator for sorting the dictionary by key. + + + + private class NodeEditorTypeDictionaryComparer : IEqualityComparer + { + public bool Equals(Type x, Type y){ + return x?.ToString() == y?.ToString(); + } + + public int GetHashCode(Type obj){ + return obj.ToString().GetHashCode(); + } + } + + public NodeEditorTypeDictionary():base(new NodeEditorTypeDictionaryComparer()){ + + } + + } + internal class NodeEditorSingleton{ private static NodeEditorSingleton _instance; - public readonly Dictionary FromGenericToSpecific = new Dictionary(); + public readonly Dictionary FromGenericToSpecific = new NodeEditorTypeDictionary(); public readonly Dictionary> GraphDataUsage = new Dictionary>(); public Dictionary GraphBlackboard = new(); public static NodeEditorSingleton Instance{ @@ -75,15 +98,22 @@ namespace TNode.Cache{ } } } - private readonly Type[] _acceptedTypesForGenericToSpecific = new Type[]{typeof(NodeView<>),typeof(DataGraphView<>),typeof(InspectorItem<>)}; + private readonly Type[] _acceptedTypesForGenericToSpecific = new Type[]{typeof(NodeView<>),typeof(DataGraphView<>),typeof(InspectorItem<>),typeof(NodeView<>)}; private void SetNodeComponentAttribute(Type type){ foreach (var attribute in type.GetCustomAttributes(typeof(NodeComponentAttribute), false)){ //fetch this type 's parent class var parent = type.BaseType; - //Check if this type is a generic type and is a generic type of NodeView or DataGraphView - if (parent is{IsGenericType: true} && _acceptedTypesForGenericToSpecific.Contains(parent.GetGenericTypeDefinition())){ + //Check if this type is a generic type and is a generic type of NodeView or DataGraphView, + //Two level generic definition is now supported by TNode + //Deeper nested generic definition is not supported by TNode + if (parent is{IsGenericType: true} && + (_acceptedTypesForGenericToSpecific.Contains(parent.GetGenericTypeDefinition()) || + (parent.GetGenericTypeDefinition().IsGenericType && _acceptedTypesForGenericToSpecific.Contains(parent.GetGenericTypeDefinition().GetGenericTypeDefinition())) + ) + ){ //Get the generic type of this type //Add this type to the dictionary + Debug.Log($"type {type} is a registered as node component for {parent}"); FromGenericToSpecific.Add(parent, type); } //TODO Note that a node component only applied to a specific type of editor,so ,same GraphView could behave differently in different editor.it's a todo feature. @@ -103,7 +133,6 @@ namespace TNode.Cache{ var instance = Activator.CreateInstance(implementedType); return instance; } - Debug.Log($"No given type found {t}"); //check if t is a generic type node view if (t is{IsGenericType: true} && t.GetGenericTypeDefinition() == typeof(NodeView<>)){ var instance = Activator.CreateInstance(typeof(NodeView)); @@ -146,13 +175,46 @@ namespace TNode.Cache{ } public static object CreateNodeViewFromNodeType(Type t){ //Check the generic type of NodeView by t + + if (t.IsGenericType){ + Debug.Log($"A generic type {t} is detected"); + //AKA if BlackboardDragNodeData is pulled + //Get BlackboardDragNodeData as generic type + + + var genericTypeDefinition = t.GetGenericTypeDefinition(); + + //What you want is a NodeView> to be created + var genericViewType = typeof(NodeView<>).MakeGenericType(genericTypeDefinition); + Debug.Log($"The generic view type is {genericViewType}"); + + //search for the specific type of genericViewType in the dictionary + if (NodeEditorSingleton.Instance.FromGenericToSpecific.ContainsKey(genericViewType)){ + + var implementedType = NodeEditorSingleton.Instance.FromGenericToSpecific[genericViewType]; + //The implementedType is still a generic type ,so we make it a specific type by using MakeGenericType + Debug.Log($"{implementedType}"); + //Get argument type of t + var argumentType = t.GetGenericArguments()[0]; + var instance = Activator.CreateInstance(implementedType.MakeGenericType(argumentType)); + + return instance; + + } + else{ + return new DefaultNodeView(); + } + + } var type = typeof(NodeView<>).MakeGenericType(t); if (NodeEditorSingleton.Instance.FromGenericToSpecific.ContainsKey(type)){ + var implementedType = NodeEditorSingleton.Instance.FromGenericToSpecific[type]; var instance = Activator.CreateInstance(implementedType); return instance; } else{ + return new DefaultNodeView(); } diff --git a/TNode/Editor/Inspector/InspectorItem.cs b/TNode/Editor/Inspector/InspectorItem.cs index 278e215..8802bb5 100644 --- a/TNode/Editor/Inspector/InspectorItem.cs +++ b/TNode/Editor/Inspector/InspectorItem.cs @@ -88,7 +88,6 @@ namespace TNode.Editor.Inspector{ Bindable.value = Value; Bindable.label = BindingPath; } - Debug.Log(Value.GetType()); } private void OnNodeDataValueChanged(NodeDataWrapper wrapper){ diff --git a/TNode/Editor/NodeViews.meta b/TNode/Editor/NodeViews.meta new file mode 100644 index 0000000..8da3bd3 --- /dev/null +++ b/TNode/Editor/NodeViews.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: ea202e63fe8e4d3b9b7759488419dde7 +timeCreated: 1657197080 \ No newline at end of file diff --git a/TNode/Editor/DefaultNodeView.cs b/TNode/Editor/NodeViews/DefaultNodeView.cs similarity index 100% rename from TNode/Editor/DefaultNodeView.cs rename to TNode/Editor/NodeViews/DefaultNodeView.cs diff --git a/TNode/Editor/DefaultNodeView.cs.meta b/TNode/Editor/NodeViews/DefaultNodeView.cs.meta similarity index 100% rename from TNode/Editor/DefaultNodeView.cs.meta rename to TNode/Editor/NodeViews/DefaultNodeView.cs.meta diff --git a/TNode/Editor/NodeViews/DragNodeView.cs b/TNode/Editor/NodeViews/DragNodeView.cs new file mode 100644 index 0000000..8ce31c7 --- /dev/null +++ b/TNode/Editor/NodeViews/DragNodeView.cs @@ -0,0 +1,15 @@ +using TNode.Attribute; +using TNode.Editor.BaseViews; +using TNode.Models; + +namespace TNode.Editor.NodeViews{ + [NodeComponent] + public class DragNodeView:NodeView>{ + public DragNodeView() : base(){ + //Make capsule like style + + this.titleContainer.visible = false; + this.titleContainer.RemoveFromHierarchy(); + } + } +} \ No newline at end of file diff --git a/TNode/Editor/NodeViews/DragNodeView.cs.meta b/TNode/Editor/NodeViews/DragNodeView.cs.meta new file mode 100644 index 0000000..97c8950 --- /dev/null +++ b/TNode/Editor/NodeViews/DragNodeView.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 899b964a5f674c2fbf1db20cf40ff5e7 +timeCreated: 1657197096 \ No newline at end of file diff --git a/TNode/Editor/BaseViews/NodeView.cs b/TNode/Editor/NodeViews/NodeView.cs similarity index 72% rename from TNode/Editor/BaseViews/NodeView.cs rename to TNode/Editor/NodeViews/NodeView.cs index bcf74b8..0079cb6 100644 --- a/TNode/Editor/BaseViews/NodeView.cs +++ b/TNode/Editor/NodeViews/NodeView.cs @@ -1,4 +1,6 @@ using System; +using System.Linq; +using System.Reflection; using TNode.Attribute; using TNode.Attribute.Ports; using TNode.Editor.Inspector; @@ -63,25 +65,46 @@ namespace TNode.Editor.BaseViews{ this.RefreshExpandedState(); } - private void BuildInputAndOutputPort(){ + protected virtual string BuildPortName(PortAttribute portAttribute,PropertyInfo propertyInfo,params object[] args){ + switch (portAttribute.NameHandling){ + case PortNameHandling.Auto: + return portAttribute.Name.Trim(' ').Length>0?portAttribute.Name:propertyInfo.Name; + break; + case PortNameHandling.Manual: + return portAttribute.Name; + break; + case PortNameHandling.MemberName: + return propertyInfo.Name; + case PortNameHandling.Format: + return String.Format(propertyInfo.Name, args); + case PortNameHandling.MemberType: + return propertyInfo.PropertyType.Name; + default: + throw new ArgumentOutOfRangeException(); + } + } + /// + /// of course you can override this method to build your own port builder + /// + protected virtual void BuildInputAndOutputPort(){ var propertyInfos = _data.GetType().GetProperties(); foreach (var propertyInfo in propertyInfos){ - var attribute = propertyInfo.GetCustomAttributes(typeof(OutputAttribute),true); - if (attribute.Length > 0){ + if (propertyInfo.GetCustomAttributes(typeof(OutputAttribute),true).FirstOrDefault() is OutputAttribute attribute){ Port port = InstantiatePort(Orientation.Horizontal, Direction.Output,Port.Capacity.Multi,propertyInfo.PropertyType); this.outputContainer.Add(port); - port.portName = propertyInfo.Name; - port.name = propertyInfo.Name; + var portName = BuildPortName(attribute,propertyInfo); + port.portName = portName; + port.name = portName; } } foreach (var propertyInfo in propertyInfos){ - var attribute = propertyInfo.GetCustomAttributes(typeof(InputAttribute),true); - if (attribute.Length > 0){ - Port port = InstantiatePort(Orientation.Horizontal, Direction.Input,Port.Capacity.Multi,propertyInfo.PropertyType); + if(propertyInfo.GetCustomAttributes(typeof(InputAttribute),true).FirstOrDefault() is InputAttribute attribute){ + Port port = InstantiatePort(Orientation.Horizontal, Direction.Input,Port.Capacity.Single,propertyInfo.PropertyType); this.inputContainer.Add(port); - port.portName = propertyInfo.Name; - port.name = propertyInfo.Name; + var portName = BuildPortName(attribute,propertyInfo); + port.portName = portName; + port.name = portName; } } } diff --git a/TNode/Editor/BaseViews/NodeView.cs.meta b/TNode/Editor/NodeViews/NodeView.cs.meta similarity index 100% rename from TNode/Editor/BaseViews/NodeView.cs.meta rename to TNode/Editor/NodeViews/NodeView.cs.meta diff --git a/TNode/Models/BlackboardDragNodeData.cs b/TNode/Models/BlackboardDragNodeData.cs index 5119283..dc587ad 100644 --- a/TNode/Models/BlackboardDragNodeData.cs +++ b/TNode/Models/BlackboardDragNodeData.cs @@ -1,16 +1,16 @@ using System.Runtime.InteropServices; using Newtonsoft.Json; +using TNode.Attribute; using TNode.Attribute.Ports; using TNode.RuntimeCache; namespace TNode.Models{ public class BlackboardDragNodeData:NodeData{ - [JsonIgnore] private string _blackDragData; [JsonIgnore] private BlackboardData _blackboardData; - [Output] + [Output("",PortNameHandling.MemberType)] public T Value => _blackboardData.GetValue(_blackDragData); public BlackboardDragNodeData(){ diff --git a/TNode/RuntimeCache/RuntimeCache.cs b/TNode/RuntimeCache/RuntimeCache.cs index c63aea1..4310a3e 100644 --- a/TNode/RuntimeCache/RuntimeCache.cs +++ b/TNode/RuntimeCache/RuntimeCache.cs @@ -62,6 +62,11 @@ namespace TNode.RuntimeCache{ var method = RuntimeCache.Instance.CachedDelegatesForGettingValue[blackboardData.GetType()][path]; return (T) method.Invoke(blackboardData); } + + public static object GetValue(this BlackboardData blackboardData, string path){ + var method = RuntimeCache.Instance.CachedDelegatesForGettingValue[blackboardData.GetType()][path]; + return method.Invoke(blackboardData); + } public static RuntimeCache.GetValueDelegate GetValueDelegate(this BlackboardData blackboardData,string path){ var method = RuntimeCache.Instance.CachedDelegatesForGettingValue[blackboardData.GetType()][path]; return method;