diff --git a/Sample/Editor/HelloGraphView.cs b/Sample/Editor/HelloGraphView.cs index 819917f..9d2de3e 100644 --- a/Sample/Editor/HelloGraphView.cs +++ b/Sample/Editor/HelloGraphView.cs @@ -1,9 +1,13 @@ using TNode.Attribute; using TNode.Editor.BaseViews; +using TNode.Editor.Inspector; namespace Sample.Editor{ [NodeComponent] public class HelloGraphView : DataGraphView{ - + public override void OnGraphViewCreate(){ + NodeInspector inspector = new NodeInspector(); + this.Add(inspector); + } } } \ No newline at end of file diff --git a/Sample/Editor/HelloGraph.cs b/Sample/HelloGraph.cs similarity index 100% rename from Sample/Editor/HelloGraph.cs rename to Sample/HelloGraph.cs diff --git a/Sample/Editor/HelloGraph.cs.meta b/Sample/HelloGraph.cs.meta similarity index 100% rename from Sample/Editor/HelloGraph.cs.meta rename to Sample/HelloGraph.cs.meta diff --git a/Sample/HelloNode.cs b/Sample/HelloNode.cs new file mode 100644 index 0000000..b8dd3d0 --- /dev/null +++ b/Sample/HelloNode.cs @@ -0,0 +1,10 @@ +using Sample.Editor; +using TNode.Attribute; +using TNode.Models; + +namespace Sample{ + [GraphUsage(typeof(HelloGraph))] + public class HelloNode:NodeData{ + + } +} \ No newline at end of file diff --git a/Sample/HelloNode.cs.meta b/Sample/HelloNode.cs.meta new file mode 100644 index 0000000..0b740d3 --- /dev/null +++ b/Sample/HelloNode.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 928bb3292c464ae0b811455e9f4e8667 +timeCreated: 1656391464 \ No newline at end of file diff --git a/Scenes/SampleScene.unity b/Scenes/SampleScene.unity index 9421266..2be4338 100644 --- a/Scenes/SampleScene.unity +++ b/Scenes/SampleScene.unity @@ -123,6 +123,107 @@ NavMeshSettings: debug: m_Flags: 0 m_NavMeshData: {fileID: 0} +--- !u!1 &507038906 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 507038910} + - component: {fileID: 507038909} + - component: {fileID: 507038908} + - component: {fileID: 507038907} + m_Layer: 5 + m_Name: Canvas + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &507038907 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 507038906} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3} + m_Name: + m_EditorClassIdentifier: + m_IgnoreReversedGraphics: 1 + m_BlockingObjects: 0 + m_BlockingMask: + serializedVersion: 2 + m_Bits: 4294967295 +--- !u!114 &507038908 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 507038906} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3} + m_Name: + m_EditorClassIdentifier: + m_UiScaleMode: 0 + m_ReferencePixelsPerUnit: 100 + m_ScaleFactor: 1 + m_ReferenceResolution: {x: 800, y: 600} + m_ScreenMatchMode: 0 + m_MatchWidthOrHeight: 0 + m_PhysicalUnit: 3 + m_FallbackScreenDPI: 96 + m_DefaultSpriteDPI: 96 + m_DynamicPixelsPerUnit: 1 + m_PresetInfoIsWorld: 0 +--- !u!223 &507038909 +Canvas: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 507038906} + m_Enabled: 1 + serializedVersion: 3 + m_RenderMode: 0 + m_Camera: {fileID: 0} + m_PlaneDistance: 100 + m_PixelPerfect: 0 + m_ReceivesEvents: 1 + m_OverrideSorting: 0 + m_OverridePixelPerfect: 0 + m_SortingBucketNormalizedSize: 0 + m_AdditionalShaderChannelsFlag: 0 + m_UpdateRectTransformForStandalone: 0 + m_SortingLayerID: 0 + m_SortingOrder: 0 + m_TargetDisplay: 0 +--- !u!224 &507038910 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 507038906} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 0, y: 0, z: 0} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0, y: 0} --- !u!1 &519420028 GameObject: m_ObjectHideFlags: 0 @@ -202,7 +303,243 @@ Transform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: -10} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 0} m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &691266389 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 691266390} + - component: {fileID: 691266391} + m_Layer: 0 + m_Name: Circle + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &691266390 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 691266389} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 0.79506373, y: 0.7908081, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1608359614} + m_RootOrder: -1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!331 &691266391 +SpriteMask: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 691266389} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 10758, guid: 0000000000000000f000000000000000, type: 0} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -2413806693520163455, guid: a86470a33a6bf42c4b3595704624658b, type: 3} + m_MaskAlphaCutoff: 0.2 + m_FrontSortingLayerID: 0 + m_BackSortingLayerID: 0 + m_FrontSortingLayer: 0 + m_BackSortingLayer: 0 + m_FrontSortingOrder: 0 + m_BackSortingOrder: 0 + m_IsCustomRangeActive: 0 + m_SpriteSortPoint: 0 +--- !u!1 &1608359612 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1608359614} + - component: {fileID: 1608359613} + m_Layer: 0 + m_Name: Circle + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!212 &1608359613 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1608359612} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 10754, guid: 0000000000000000f000000000000000, type: 0} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: -2413806693520163455, guid: a86470a33a6bf42c4b3595704624658b, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 0 + m_Size: {x: 1, y: 1} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 2 + m_SpriteSortPoint: 0 +--- !u!4 &1608359614 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1608359612} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 16.183, y: 14.154, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 691266390} + m_Father: {fileID: 0} + m_RootOrder: 3 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1701140682 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1701140685} + - component: {fileID: 1701140684} + - component: {fileID: 1701140683} + m_Layer: 0 + m_Name: EventSystem + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1701140683 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1701140682} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4f231c4fb786f3946a6b90b886c48677, type: 3} + m_Name: + m_EditorClassIdentifier: + m_HorizontalAxis: Horizontal + m_VerticalAxis: Vertical + m_SubmitButton: Submit + m_CancelButton: Cancel + m_InputActionsPerSecond: 10 + m_RepeatDelay: 0.5 + m_ForceModuleActive: 0 +--- !u!114 &1701140684 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1701140682} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 76c392e42b5098c458856cdf6ecaaaa1, type: 3} + m_Name: + m_EditorClassIdentifier: + m_FirstSelected: {fileID: 0} + m_sendNavigationEvents: 1 + m_DragThreshold: 10 +--- !u!4 &1701140685 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1701140682} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} diff --git a/TNode/Attribute/AssetMenuCreateAsGraphEditor.cs b/TNode/Attribute/AssetMenuCreateAsGraphEditor.cs deleted file mode 100644 index 38af2b1..0000000 --- a/TNode/Attribute/AssetMenuCreateAsGraphEditor.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; -using JetBrains.Annotations; -using UnityEngine; - -namespace TNode.Attribute{ - [MeansImplicitUse] - [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] - [BaseTypeRequired(typeof(ScriptableObject))] - public class AssetMenuCreateAsGraphEditorAttribute:System.Attribute{ - - } -} \ No newline at end of file diff --git a/TNode/Attribute/AssetMenuCreateAsGraphEditor.cs.meta b/TNode/Attribute/AssetMenuCreateAsGraphEditor.cs.meta deleted file mode 100644 index e908835..0000000 --- a/TNode/Attribute/AssetMenuCreateAsGraphEditor.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 536eae3bd21b49609d88e3bd24b4d7d0 -timeCreated: 1656038984 \ No newline at end of file diff --git a/TNode/Attribute/GraphUsageAttribute.cs b/TNode/Attribute/GraphUsageAttribute.cs new file mode 100644 index 0000000..4cc6b1f --- /dev/null +++ b/TNode/Attribute/GraphUsageAttribute.cs @@ -0,0 +1,26 @@ +using System; +using JetBrains.Annotations; +using TNode.Models; +using Unity.VisualScripting; + +namespace TNode.Attribute{ + /// + /// Use this attribute to claim the usage of a type of node on the derived NodeData class. + /// it can be applied to the same node multiple times. + /// + /// [GraphUsage(DialogueGraph)] + /// + /// + [AttributeUsage(AttributeTargets.Class)] + [BaseTypeRequired(typeof(NodeData))] + public class GraphUsageAttribute:System.Attribute{ + public Type GraphDataType; + public GraphUsageAttribute(Type t){ + //check if the type t is graph + if(!typeof(GraphData).IsAssignableFrom(t)){ + throw new Exception("The type must be a graph"); + } + GraphDataType = t; + } + } +} \ No newline at end of file diff --git a/TNode/Attribute/GraphUsageAttribute.cs.meta b/TNode/Attribute/GraphUsageAttribute.cs.meta new file mode 100644 index 0000000..bc8dab3 --- /dev/null +++ b/TNode/Attribute/GraphUsageAttribute.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 25593dbfe27b42809a2a38eae3458521 +timeCreated: 1656389642 \ No newline at end of file diff --git a/TNode/Editor/BaseViews/SimpleGraphSubWindow.cs b/TNode/Editor/BaseViews/SimpleGraphSubWindow.cs index b81282b..26be881 100644 --- a/TNode/Editor/BaseViews/SimpleGraphSubWindow.cs +++ b/TNode/Editor/BaseViews/SimpleGraphSubWindow.cs @@ -7,6 +7,7 @@ namespace TNode.BaseViews{ private readonly Dragger _dragger = new Dragger(); protected void ConstructWindowBasicSetting(){ + style.position = new StyleEnum(Position.Absolute); RegisterCallback(evt => { evt.StopPropagation(); }); focusable = false; capabilities |= Capabilities.Movable | Capabilities.Resizable; diff --git a/TNode/Editor/Cache/NodeEditorExtensions.cs b/TNode/Editor/Cache/NodeEditorExtensions.cs index 4d8f57b..22909e1 100644 --- a/TNode/Editor/Cache/NodeEditorExtensions.cs +++ b/TNode/Editor/Cache/NodeEditorExtensions.cs @@ -1,38 +1,80 @@ using System; using System.Collections.Generic; +using System.Linq; using TNode.Attribute; using TNode.BaseViews; +using TNode.Editor; using TNode.Editor.BaseViews; +using TNode.Models; +using UnityEditor.Experimental.GraphView; using UnityEngine; namespace TNode.Cache{ + /// + /// Internal singleton class for caching TNode reflection Data. + /// internal class NodeEditorSingleton{ private static NodeEditorSingleton _instance; public readonly Dictionary FromGenericToSpecific = new Dictionary(); + public readonly Dictionary> GraphDataUsage = new Dictionary>(); public static NodeEditorSingleton Instance{ get{ return _instance ??= new NodeEditorSingleton(); } } + + private static readonly string[] ExcludedAssemblies = new string[]{"Microsoft", "UnityEngine","UnityEditor","mscorlib","System"}; + private NodeEditorSingleton(){ - foreach(var assembly in AppDomain.CurrentDomain.GetAssemblies()){ + //exclude unity ,system ,and microsoft types + var assemblies = AppDomain. + CurrentDomain.GetAssemblies() + .Where(x=>ExcludedAssemblies.All(y=>!x.GetName().Name.Split(".")[0].Equals(y))); + + foreach(var assembly in assemblies){ foreach(var type in assembly.GetTypes()){ if(type.IsClass && !type.IsAbstract){ - 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} && (parent.GetGenericTypeDefinition() == typeof(NodeView<>) || parent.GetGenericTypeDefinition() == typeof(DataGraphView<>))){ - //Get the generic type of this type - //Add this type to the dictionary - Debug.Log($"Find a component named {type} and its parent is {parent}" ); - FromGenericToSpecific.Add(parent, type); - } - + //Register Node View And Graph View via its parent class + SetNodeComponentAttribute(type); + //Register Node Data by GraphUsageAttribute. + SetGraphUsageAttribute(type); + } + } + } + } + + private void SetGraphUsageAttribute(Type type){ + foreach (var attribute in type.GetCustomAttributes(typeof(GraphUsageAttribute), true)){ + var parent = type.BaseType; + if (typeof(NodeData).IsAssignableFrom(type.BaseType)){ + //Check if GraphDataUsage dictionary has GraphDataType of attribute + if (attribute is GraphUsageAttribute attributeCasted){ + if (GraphDataUsage.ContainsKey(attributeCasted.GraphDataType)){ + GraphDataUsage[attributeCasted.GraphDataType].Add(type); + } + else{ + GraphDataUsage.Add(attributeCasted.GraphDataType, new List{type}); } } } } } + + 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} && (parent.GetGenericTypeDefinition() == typeof(NodeView<>) || + parent.GetGenericTypeDefinition() == typeof(DataGraphView<>))){ + //Get the generic type of this type + //Add this type to the dictionary + Debug.Log($"Find a component named {type} and its parent is {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. + } + } } + //Outer wrapper for the singleton class public static class NodeEditorExtensions{ public static T CreateInstance(){ Debug.Log($"Create A instance of {typeof(T)}"); @@ -50,5 +92,37 @@ namespace TNode.Cache{ var implementedType = NodeEditorSingleton.Instance.FromGenericToSpecific[typeof(T)] as T; return (T)implementedType!=null; } + public static List GetGraphDataUsage(Type t){ + if (NodeEditorSingleton.Instance.GraphDataUsage.ContainsKey(t)){ + return NodeEditorSingleton.Instance.GraphDataUsage[t]; + } + return new List(); + } + public static object CreateNodeViewFromNodeType() where T:NodeData,new(){ + //Check specific derived type exists or not. + var type = typeof(NodeView); + if (NodeEditorSingleton.Instance.FromGenericToSpecific.ContainsKey(type)){ + var implementedType = NodeEditorSingleton.Instance.FromGenericToSpecific[type]; + var instance = (NodeView)Activator.CreateInstance(implementedType); + return instance; + } + else{ + return new DefaultNodeView(); + } + + } + public static object CreateNodeViewFromNodeType(Type t){ + //Check the generic type of NodeView by t + 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(); + } + + } } } \ No newline at end of file diff --git a/TNode/Editor/DefaultNodeView.cs b/TNode/Editor/DefaultNodeView.cs new file mode 100644 index 0000000..999938a --- /dev/null +++ b/TNode/Editor/DefaultNodeView.cs @@ -0,0 +1,8 @@ +using TNode.BaseViews; +using TNode.Models; + +namespace TNode.Editor{ + public class DefaultNodeView:NodeView{ + + } +} \ No newline at end of file diff --git a/TNode/Editor/DefaultNodeView.cs.meta b/TNode/Editor/DefaultNodeView.cs.meta new file mode 100644 index 0000000..6de0d0a --- /dev/null +++ b/TNode/Editor/DefaultNodeView.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 30bf0ad9c92f4bebae1a838bafd71c06 +timeCreated: 1656401737 \ No newline at end of file diff --git a/TNode/Editor/GraphEditor.cs b/TNode/Editor/GraphEditor.cs index 24b0f55..645bab9 100644 --- a/TNode/Editor/GraphEditor.cs +++ b/TNode/Editor/GraphEditor.cs @@ -52,7 +52,10 @@ namespace TNode.Editor{ evt.menu.AppendAction("Create Node", dma => { var dmaPos = dma.eventInfo.mousePosition+editorPosition; SearchWindowContext searchWindowContext = new SearchWindowContext(dmaPos,200,200); - SearchWindow.Open(searchWindowContext, ScriptableObject.CreateInstance()); + var searchWindow = CreateInstance(); + searchWindow.Setup(typeof(T),_graphView); + Debug.Log(searchWindow); + SearchWindow.Open(searchWindowContext, searchWindow); }); }); } @@ -78,7 +81,7 @@ namespace TNode.Editor{ { string path = EditorUtility.SaveFilePanel("Save Graph", "", "", "asset"); if (path.Length != 0){ - //Create a new asset file with type of T + //Create a new asset file with type of GraphDataType T asset = ScriptableObject.CreateInstance(); AssetDatabase.CreateAsset(asset, path); } diff --git a/TNode/Editor/Inspector/DefaultInspectorItemFactory.cs b/TNode/Editor/Inspector/DefaultInspectorItemFactory.cs index 0bc873e..0f90d97 100644 --- a/TNode/Editor/Inspector/DefaultInspectorItemFactory.cs +++ b/TNode/Editor/Inspector/DefaultInspectorItemFactory.cs @@ -8,7 +8,7 @@ namespace TNode.Editor.Inspector{ public class DefaultInspectorItemFactory{ public InspectorItem Create(){ - //Check type of T + //Check type of GraphDataType var hasSpecificType = NodeEditorExtensions.HasSpecificType>(); if (hasSpecificType){ return NodeEditorExtensions.CreateInstance>(); diff --git a/TNode/Editor/Inspector/NodeInspector.cs b/TNode/Editor/Inspector/NodeInspector.cs index a15dabb..48accc7 100644 --- a/TNode/Editor/Inspector/NodeInspector.cs +++ b/TNode/Editor/Inspector/NodeInspector.cs @@ -23,6 +23,8 @@ namespace TNode.Editor.Inspector{ } public NodeInspector(){ var visualTreeAsset = Resources.Load("NodeInspector"); + + Debug.Log(visualTreeAsset); ConstructWindowBasicSetting(); BuildWindow(visualTreeAsset); } diff --git a/TNode/Editor/Resources/NodeInsepctor.uxml b/TNode/Editor/Resources/NodeInspector.uxml similarity index 100% rename from TNode/Editor/Resources/NodeInsepctor.uxml rename to TNode/Editor/Resources/NodeInspector.uxml diff --git a/TNode/Editor/Resources/NodeInsepctor.uxml.meta b/TNode/Editor/Resources/NodeInspector.uxml.meta similarity index 100% rename from TNode/Editor/Resources/NodeInsepctor.uxml.meta rename to TNode/Editor/Resources/NodeInspector.uxml.meta diff --git a/TNode/Editor/SearchWindowProvider.cs b/TNode/Editor/SearchWindowProvider.cs index 3073585..c0bf4c8 100644 --- a/TNode/Editor/SearchWindowProvider.cs +++ b/TNode/Editor/SearchWindowProvider.cs @@ -1,18 +1,50 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; +using TNode.BaseViews; +using TNode.Cache; +using TNode.Models; using UnityEditor.Experimental.GraphView; using UnityEngine; +using UnityEngine.UIElements; namespace TNode.Editor{ public class SearchWindowProvider:ScriptableObject,ISearchWindowProvider{ + private Type _graphType; + private GraphView _graphView; + public void Setup(Type graph,GraphView graphView){ + _graphType = graph; + _graphView = graphView; + } public List CreateSearchTree(SearchWindowContext context){ - var list = new List(); - list.Add(new SearchTreeGroupEntry(new GUIContent("Add New Node"), 0)); - list.Add(new SearchTreeGroupEntry(new GUIContent("Add Placemat"), 0)); + var nodeDataTypes = NodeEditorExtensions.GetGraphDataUsage(_graphType); + + var list = new List{ + new SearchTreeGroupEntry(new GUIContent("Add New Node"), 0), + }; + //TODO a node icon shall be given by some way + 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, + }); + } return list; } - public bool OnSelectEntry(SearchTreeEntry SearchTreeEntry, SearchWindowContext context){ + var userData = SearchTreeEntry.userData; + if (userData is Type type){ + var nodeView = NodeEditorExtensions.CreateNodeViewFromNodeType(type) as GraphElement; + _graphView.AddElement(nodeView); + return true; + } return false; } + + public SearchWindowProvider(){ + } } } \ No newline at end of file diff --git a/TNode/TNodeSample.meta b/TNode/TNodeSample.meta deleted file mode 100644 index 8fedb61..0000000 --- a/TNode/TNodeSample.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: ab3bb3578bf34dafad6ff9fb71f040e1 -timeCreated: 1655794910 \ No newline at end of file diff --git a/TNode/TNodeSample/GraphViewTest.cs b/TNode/TNodeSample/GraphViewTest.cs deleted file mode 100644 index ce772a5..0000000 --- a/TNode/TNodeSample/GraphViewTest.cs +++ /dev/null @@ -1,8 +0,0 @@ -using Dialogue; -using TNode.Attribute; - - -namespace TNode.TNodeSample{ - - -} \ No newline at end of file diff --git a/TNode/TNodeSample/GraphViewTest.cs.meta b/TNode/TNodeSample/GraphViewTest.cs.meta deleted file mode 100644 index 8769352..0000000 --- a/TNode/TNodeSample/GraphViewTest.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: a7d4101454c84539b936140f3b54a3a6 -timeCreated: 1655794926 \ No newline at end of file diff --git a/TNode/TNodeSample/NodeDataTest.cs b/TNode/TNodeSample/NodeDataTest.cs deleted file mode 100644 index 9e10c6c..0000000 --- a/TNode/TNodeSample/NodeDataTest.cs +++ /dev/null @@ -1,15 +0,0 @@ -using Dialogue; -using TNode.Attribute; -using TNode.Models; -using UnityEditor.Experimental.GraphView; - -namespace TNode.TNodeSample{ - public class NodeDataTest:NodeData{ - [InputPort(typeof(NodeLink),Port.Capacity.Multi)] - private float _floatInput; - public NodeDataTest(string name):base(){ - - } - - } -} \ No newline at end of file diff --git a/TNode/TNodeSample/NodeDataTest.cs.meta b/TNode/TNodeSample/NodeDataTest.cs.meta deleted file mode 100644 index 7fc5fff..0000000 --- a/TNode/TNodeSample/NodeDataTest.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 2d66df6e04694c51818042134869583f -timeCreated: 1655794954 \ No newline at end of file