diff --git a/TNodeCore/Attribute/GraphUsageAttribute.cs b/TNodeCore/Attribute/GraphUsageAttribute.cs index af08872..4eb9151 100644 --- a/TNodeCore/Attribute/GraphUsageAttribute.cs +++ b/TNodeCore/Attribute/GraphUsageAttribute.cs @@ -16,15 +16,14 @@ namespace TNodeCore.Attribute{ public class GraphUsageAttribute:System.Attribute{ public readonly Type GraphDataType; public string Category; - public GraphUsageAttribute(Type t,string category = null){ + public GraphUsageAttribute(Type t,string category = "default"){ //check if the type t is graph if(!typeof(GraphData).IsAssignableFrom(t)){ throw new Exception("The type used on Graph Usage must be a graph"); } GraphDataType = t; - if (category != null){ - Category = category; - } + Category = category; + } } diff --git a/TNodeGraphViewImpl/Editor/Cache/NodeEditorExtensions.cs b/TNodeGraphViewImpl/Editor/Cache/NodeEditorExtensions.cs index 5d55934..fcdcb48 100644 --- a/TNodeGraphViewImpl/Editor/Cache/NodeEditorExtensions.cs +++ b/TNodeGraphViewImpl/Editor/Cache/NodeEditorExtensions.cs @@ -18,8 +18,7 @@ namespace TNodeGraphViewImpl.Editor.Cache{ /// Internal singleton class for caching TNode reflection Data. /// internal class NodeEditorTypeDictionary:Dictionary{ - private class NodeEditorTypeDictionaryComparer : IEqualityComparer - { + private class NodeEditorTypeDictionaryComparer : IEqualityComparer{ public bool Equals(Type x, Type y){ return x?.ToString() == y?.ToString(); } @@ -28,11 +27,9 @@ namespace TNodeGraphViewImpl.Editor.Cache{ return obj.ToString().GetHashCode(); } } - public NodeEditorTypeDictionary():base(new NodeEditorTypeDictionaryComparer()){ } - } internal class NodeEditorSingleton{ @@ -132,6 +129,10 @@ namespace TNodeGraphViewImpl.Editor.Cache{ var instance = (T)Activator.CreateInstance(implementedType); return instance; } + public static string GetTypeCategory(Type type){ + var category = type.GetCustomAttribute(); + return category?.Category ?? ""; + } /// /// by given a generic type t,return the implementation instance of the generic type @@ -190,6 +191,13 @@ namespace TNodeGraphViewImpl.Editor.Cache{ } return new List(); } + + public static List GetGraphCategories(Type t){ + var list = NodeEditorSingleton.Instance.GraphDataUsage[t]; + //Merge same category + var res = list.Select(x=>x.GetCustomAttribute().Category).Distinct().ToList(); + return res; + } public static BlackboardData GetAppropriateBlackboardData(Type t){ if (NodeEditorSingleton.Instance.GraphBlackboard.ContainsKey(t)){ return (BlackboardData)Activator.CreateInstance(NodeEditorSingleton.Instance.GraphBlackboard[t]); diff --git a/TNodeGraphViewImpl/Editor/NodeGraphView/DataGraphView.cs b/TNodeGraphViewImpl/Editor/NodeGraphView/DataGraphView.cs index c5c515b..fcab94f 100644 --- a/TNodeGraphViewImpl/Editor/NodeGraphView/DataGraphView.cs +++ b/TNodeGraphViewImpl/Editor/NodeGraphView/DataGraphView.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Reflection; using TNode.Editor.Inspector; using TNode.Editor.Search; using TNodeCore.Editor.Blackboard; @@ -12,6 +13,7 @@ using TNodeCore.Runtime; using TNodeGraphViewImpl.Editor.Cache; using TNodeGraphViewImpl.Editor.GraphBlackboard; using TNodeGraphViewImpl.Editor.NodeViews; +using TNodeGraphViewImpl.Editor.Search; using UnityEditor; using UnityEditor.Experimental.GraphView; using UnityEngine; @@ -397,10 +399,20 @@ namespace TNodeGraphViewImpl.Editor.NodeGraphView{ _data.blackboardData = NodeEditorExtensions.GetAppropriateBlackboardData(_data.GetType()); } } - - + //TODO:Handling implicit conversion when two port types are different but compatible + private static bool HasImplicitConversion(Type baseType, Type targetType) + { + return baseType.GetMethods(BindingFlags.Public | BindingFlags.Static) + .Where(mi => mi.Name == "op_Implicit" && mi.ReturnType == targetType) + .Any(mi => { + ParameterInfo pi = mi.GetParameters().FirstOrDefault(); + return pi != null && pi.ParameterType == baseType; + }); + } public override List GetCompatiblePorts(Port startPort, NodeAdapter nodeAdapter){ - return ports.Where(x => x.portType == startPort.portType || x.portType.IsAssignableFrom(startPort.portType)).ToList(); + + return ports.Where(x => startPort!=x && (x.portType == startPort.portType || x.portType.IsAssignableFrom(startPort.portType))).ToList(); + } public virtual void OnGraphViewCreate(){ diff --git a/TNodeGraphViewImpl/Editor/Search/NodeSearchWindowProvider.cs b/TNodeGraphViewImpl/Editor/Search/NodeSearchWindowProvider.cs index d7deafd..d2f2af7 100644 --- a/TNodeGraphViewImpl/Editor/Search/NodeSearchWindowProvider.cs +++ b/TNodeGraphViewImpl/Editor/Search/NodeSearchWindowProvider.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using TNodeCore.Editor.NodeGraphView; using TNodeCore.Editor.Tools.NodeCreator; using TNodeCore.Models; @@ -9,7 +10,7 @@ using UnityEditor.Experimental.GraphView; using UnityEngine; using UnityEngine.UIElements; -namespace TNode.Editor.Search{ +namespace TNodeGraphViewImpl.Editor.Search{ public class NodeSearchWindowProvider:ScriptableObject,ISearchWindowProvider{ private Type _graphType; private GraphView _graphView; @@ -21,20 +22,26 @@ namespace TNode.Editor.Search{ } public List CreateSearchTree(SearchWindowContext context){ var nodeDataTypes = NodeEditorExtensions.GetGraphDataUsage(_graphType); + var categories = NodeEditorExtensions.GetGraphCategories(_graphType); var list = new List{ - new SearchTreeGroupEntry(new GUIContent("Add New Node"), 0), + }; - //TODO a node icon shall be given by some way + var root = new SearchTreeGroupEntry(new GUIContent("Create"),0); + list.Add(root); Texture2D icon = new Texture2D(2,2); - foreach (var nodeDataType in nodeDataTypes){ - Debug.Log(nodeDataType.Name); - - - list.Add(new SearchTreeEntry(new GUIContent($" {nodeDataType.Name} ",icon)){ - level = 1, - userData = nodeDataType, + foreach (var category in categories){ + var categoryEntry = new SearchTreeGroupEntry(new GUIContent(category),1); + list.Add(categoryEntry); + nodeDataTypes.Where(x => NodeEditorExtensions.GetTypeCategory(x).Equals(category)).ToList().ForEach(x => { + var nodeDataType = x; + var nodeDataTypeEntry = new SearchTreeEntry(new GUIContent($" {nodeDataType.Name} ",icon)){ + level = 2, + userData = nodeDataType + }; + list.Add(nodeDataTypeEntry); }); + } return list; } @@ -55,8 +62,5 @@ namespace TNode.Editor.Search{ } return false; } - - public NodeSearchWindowProvider(){ - } } } \ No newline at end of file