diff --git a/Scripts/Editor/NodeEditorGUILayout.cs b/Scripts/Editor/NodeEditorGUILayout.cs index b17fea3..30f6426 100644 --- a/Scripts/Editor/NodeEditorGUILayout.cs +++ b/Scripts/Editor/NodeEditorGUILayout.cs @@ -45,7 +45,7 @@ namespace XNodeEditor { float spacePadding = 0; SpaceAttribute spaceAttribute; - if(NodeEditorUtilities.GetAttrib(port.node.GetType(), property.name, out spaceAttribute)) spacePadding = spaceAttribute.height; + if (NodeEditorUtilities.GetCachedAttrib(port.node.GetType(), property.name, out spaceAttribute)) spacePadding = spaceAttribute.height; // If property is an input, display a regular property field and put a port handle on the left side if (port.direction == XNode.NodePort.IO.Input) { @@ -53,15 +53,15 @@ namespace XNodeEditor { XNode.Node.ShowBackingValue showBacking = XNode.Node.ShowBackingValue.Unconnected; XNode.Node.InputAttribute inputAttribute; bool instancePortList = false; - if (NodeEditorUtilities.GetAttrib(port.node.GetType(), property.name, out inputAttribute)) { + if (NodeEditorUtilities.GetCachedAttrib(port.node.GetType(), property.name, out inputAttribute)) { instancePortList = inputAttribute.instancePortList; showBacking = inputAttribute.backingValue; } //Call GUILayout.Space if Space attribute is set and we are NOT drawing a PropertyField - bool useLayoutSpace = instancePortList - || showBacking == XNode.Node.ShowBackingValue.Never - || (showBacking == XNode.Node.ShowBackingValue.Unconnected && port.IsConnected); + bool useLayoutSpace = instancePortList || + showBacking == XNode.Node.ShowBackingValue.Never || + (showBacking == XNode.Node.ShowBackingValue.Unconnected && port.IsConnected); if (spacePadding > 0 && useLayoutSpace) { GUILayout.Space(spacePadding); spacePadding = 0; @@ -98,17 +98,16 @@ namespace XNodeEditor { XNode.Node.ShowBackingValue showBacking = XNode.Node.ShowBackingValue.Unconnected; XNode.Node.OutputAttribute outputAttribute; bool instancePortList = false; - if (NodeEditorUtilities.GetAttrib(port.node.GetType(), property.name, out outputAttribute)) { + if (NodeEditorUtilities.GetCachedAttrib(port.node.GetType(), property.name, out outputAttribute)) { instancePortList = outputAttribute.instancePortList; showBacking = outputAttribute.backingValue; } //Call GUILayout.Space if Space attribute is set and we are NOT drawing a PropertyField - bool useLayoutSpace = instancePortList - || showBacking == XNode.Node.ShowBackingValue.Never - || (showBacking == XNode.Node.ShowBackingValue.Unconnected && port.IsConnected); - if (spacePadding > 0 && useLayoutSpace) - { + bool useLayoutSpace = instancePortList || + showBacking == XNode.Node.ShowBackingValue.Never || + (showBacking == XNode.Node.ShowBackingValue.Unconnected && port.IsConnected); + if (spacePadding > 0 && useLayoutSpace) { GUILayout.Space(spacePadding); spacePadding = 0; } diff --git a/Scripts/Editor/NodeEditorUtilities.cs b/Scripts/Editor/NodeEditorUtilities.cs index 0d98420..ebc7bd4 100644 --- a/Scripts/Editor/NodeEditorUtilities.cs +++ b/Scripts/Editor/NodeEditorUtilities.cs @@ -15,6 +15,9 @@ namespace XNodeEditor { /// C#'s Script Icon [The one MonoBhevaiour Scripts have]. private static Texture2D scriptIcon = (EditorGUIUtility.IconContent("cs Script Icon").image as Texture2D); + /// Saves Attribute from Type+Field for faster lookup. Resets on recompiles. + private static Dictionary>> typeAttributes = new Dictionary>>(); + public static bool GetAttrib(Type classType, out T attribOut) where T : Attribute { object[] attribs = classType.GetCustomAttributes(typeof(T), false); return GetAttrib(attribs, out attribOut); @@ -45,6 +48,34 @@ namespace XNodeEditor { return false; } + public static bool GetCachedAttrib(Type classType, string fieldName, out T attribOut) where T : Attribute { + Dictionary> typeFields; + if (!typeAttributes.TryGetValue(classType, out typeFields)) { + typeFields = new Dictionary>(); + typeAttributes.Add(classType, typeFields); + } + + Dictionary typeTypes; + if (!typeFields.TryGetValue(fieldName, out typeTypes)) { + typeTypes = new Dictionary(); + typeFields.Add(fieldName, typeTypes); + } + + Attribute attr; + if (!typeTypes.TryGetValue(typeof(T), out attr)) { + if (GetAttrib(classType, fieldName, out attribOut)) typeTypes.Add(typeof(T), attribOut); + else typeTypes.Add(typeof(T), null); + } + + if (attr == null) { + attribOut = null; + return false; + } + + attribOut = attr as T; + return true; + } + /// Returns true if this can be casted to public static bool IsCastableTo(this Type from, Type to) { if (to.IsAssignableFrom(from)) return true;