diff --git a/Scripts/Editor/NodeEditor.cs b/Scripts/Editor/NodeEditor.cs index 7e450e2..838cdc6 100644 --- a/Scripts/Editor/NodeEditor.cs +++ b/Scripts/Editor/NodeEditor.cs @@ -7,7 +7,9 @@ using XNode; namespace XNodeEditor { /// Base class to derive custom Node editors from. Use this to create your own custom inspectors and editors for your nodes. - public class NodeEditor { + [CustomNodeEditor(typeof(Node))] + public class NodeEditor : XNodeInternal.NodeEditorBase { + /// Fires every whenever a node was modified through the editor public static Action onUpdateNode; public Node target; @@ -45,17 +47,21 @@ namespace XNodeEditor { public virtual int GetWidth() { return 200; } - } - [AttributeUsage(AttributeTargets.Class)] - public class CustomNodeEditorAttribute : Attribute { - public Type inspectedType { get { return _inspectedType; } } - private Type _inspectedType; - /// Tells a NodeEditor which Node type it is an editor for - /// Type that this editor can edit - /// Path to the node - public CustomNodeEditorAttribute(Type inspectedType) { - _inspectedType = inspectedType; + [AttributeUsage(AttributeTargets.Class)] + public class CustomNodeEditorAttribute : Attribute, + INodeEditorAttrib { + private Type inspectedType; + /// Tells a NodeEditor which Node type it is an editor for + /// Type that this editor can edit + /// Path to the node + public CustomNodeEditorAttribute(Type inspectedType) { + this.inspectedType = inspectedType; + } + + public Type GetInspectedType() { + return inspectedType; + } } } } \ No newline at end of file diff --git a/Scripts/Editor/NodeEditorBase.cs b/Scripts/Editor/NodeEditorBase.cs new file mode 100644 index 0000000..3c31777 --- /dev/null +++ b/Scripts/Editor/NodeEditorBase.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Reflection; +using UnityEngine; +using XNode; +using XNodeEditor; + +namespace XNodeInternal { + /// Handles caching of custom editor classes and their target types. Accessible with GetEditor(Type type) + public class NodeEditorBase where A : Attribute, NodeEditorBase.INodeEditorAttrib where T : class { + /// Custom editors defined with [CustomNodeEditor] + private static Dictionary editors; + + public static T GetEditor(Type type) { + if (type == null) return null; + if (editors == null) CacheCustomEditors(); + if (editors.ContainsKey(type)) return editors[type]; + //If type isn't found, try base type + return GetEditor(type.BaseType); + } + + private static void CacheCustomEditors() { + editors = new Dictionary(); + + //Get all classes deriving from NodeEditor via reflection + Type[] nodeEditors = NodeEditorWindow.GetDerivedTypes(typeof(T)); + for (int i = 0; i < nodeEditors.Length; i++) { + var attribs = nodeEditors[i].GetCustomAttributes(typeof(A), false); + if (attribs == null || attribs.Length == 0) continue; + if (nodeEditors[i].IsAbstract) continue; + A attrib = attribs[0] as A; + editors.Add(attrib.GetInspectedType(), Activator.CreateInstance(nodeEditors[i]) as T); + } + } + + public interface INodeEditorAttrib { + Type GetInspectedType(); + } + } +} \ No newline at end of file diff --git a/Scripts/Editor/NodeEditorBase.cs.meta b/Scripts/Editor/NodeEditorBase.cs.meta new file mode 100644 index 0000000..4ded02a --- /dev/null +++ b/Scripts/Editor/NodeEditorBase.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: e85122ded59aceb4eb4b1bd9d9202642 +timeCreated: 1511353946 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Editor/NodeEditorGUI.cs b/Scripts/Editor/NodeEditorGUI.cs index e3da60a..f7625c8 100644 --- a/Scripts/Editor/NodeEditorGUI.cs +++ b/Scripts/Editor/NodeEditorGUI.cs @@ -193,7 +193,7 @@ namespace XNodeEditor { Node node = graph.nodes[n]; Type nodeType = node.GetType(); - NodeEditor nodeEditor = GetNodeEditor(nodeType); + NodeEditor nodeEditor = NodeEditor.GetEditor(nodeType); nodeEditor.target = node; nodeEditor.serializedObject = new SerializedObject(node); NodeEditor.portPositions = new Dictionary(); diff --git a/Scripts/Editor/NodeEditorReflection.cs b/Scripts/Editor/NodeEditorReflection.cs index d1eba68..319bfe5 100644 --- a/Scripts/Editor/NodeEditorReflection.cs +++ b/Scripts/Editor/NodeEditorReflection.cs @@ -10,40 +10,18 @@ using XNode; namespace XNodeEditor { /// Contains reflection-related info public partial class NodeEditorWindow { - /// Custom node editors defined with [CustomNodeInspector] - [NonSerialized] private static Dictionary customNodeEditor; /// Custom node tint colors defined with [NodeColor(r, g, b)] public static Dictionary nodeTint { get { return _nodeTint != null ? _nodeTint : _nodeTint = GetNodeTint(); } } - [NonSerialized] private static Dictionary _nodeTint; + [NonSerialized] private static Dictionary _nodeTint; /// All available node types public static Type[] nodeTypes { get { return _nodeTypes != null ? _nodeTypes : _nodeTypes = GetNodeTypes(); } } - [NonSerialized] private static Type[] _nodeTypes = null; - - public static NodeEditor GetNodeEditor(Type node) { - if (customNodeEditor == null) CacheCustomNodeEditors(); - if (customNodeEditor.ContainsKey(node)) return customNodeEditor[node]; - return customNodeEditor[typeof(Node)]; - } + [NonSerialized] private static Type[] _nodeTypes = null; public static Type[] GetNodeTypes() { //Get all classes deriving from Node via reflection return GetDerivedTypes(typeof(Node)); } - public static void CacheCustomNodeEditors() { - customNodeEditor = new Dictionary(); - customNodeEditor.Add(typeof(Node), new NodeEditor()); - //Get all classes deriving from NodeEditor via reflection - Type[] nodeEditors = GetDerivedTypes(typeof(NodeEditor)); - for (int i = 0; i < nodeEditors.Length; i++) { - var attribs = nodeEditors[i].GetCustomAttributes(typeof(CustomNodeEditorAttribute), false); - if (attribs == null || attribs.Length == 0) continue; - if (nodeEditors[i].IsAbstract) continue; - CustomNodeEditorAttribute attrib = attribs[0] as CustomNodeEditorAttribute; - customNodeEditor.Add(attrib.inspectedType, Activator.CreateInstance(nodeEditors[i]) as NodeEditor); - } - } - public static Dictionary GetNodeTint() { Dictionary tints = new Dictionary(); for (int i = 0; i < nodeTypes.Length; i++) { @@ -121,7 +99,6 @@ namespace XNodeEditor { FieldInfo sectionsField = type.GetField("m_Sections", BindingFlags.Instance | BindingFlags.NonPublic); IList sections = sectionsField.GetValue(window) as IList; - //Iterate through sections and check contents Type sectionType = sectionsField.FieldType.GetGenericArguments() [0]; FieldInfo sectionContentField = sectionType.GetField("content", BindingFlags.Instance | BindingFlags.Public); diff --git a/Scripts/Editor/NodeGraphEditor.cs b/Scripts/Editor/NodeGraphEditor.cs new file mode 100644 index 0000000..ffb938c --- /dev/null +++ b/Scripts/Editor/NodeGraphEditor.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using UnityEditor; +using UnityEngine; +using XNode; + +namespace XNodeEditor { + /// Base class to derive custom Node Graph editors from. Use this to override how graphs are drawn in the editor. + [CustomNodeGraphEditor(typeof(NodeGraph))] + public class NodeGraphEditor : XNodeInternal.NodeEditorBase { + /// Custom node editors defined with [CustomNodeGraphEditor] + [NonSerialized] private static Dictionary editors; + + public NodeGraph target; + public SerializedObject serializedObject; + + public virtual Texture2D GetGridTexture() { + return NodeEditorPreferences.gridTexture; + } + + [AttributeUsage(AttributeTargets.Class)] + public class CustomNodeGraphEditorAttribute : Attribute, + INodeEditorAttrib { + private Type inspectedType; + /// Tells a NodeEditor which Node type it is an editor for + /// Type that this editor can edit + /// Path to the node + public CustomNodeGraphEditorAttribute(Type inspectedType) { + this.inspectedType = inspectedType; + } + + public Type GetInspectedType() { + return inspectedType; + } + } + } +} \ No newline at end of file diff --git a/Scripts/Editor/NodeGraphEditor.cs.meta b/Scripts/Editor/NodeGraphEditor.cs.meta new file mode 100644 index 0000000..bc1c153 --- /dev/null +++ b/Scripts/Editor/NodeGraphEditor.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: ddcbb5432255d3247a0718b15a9c193c +timeCreated: 1505462176 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: