From aa58c0b1ff53d6953adb135b98a4e77e37858563 Mon Sep 17 00:00:00 2001 From: Simon Rodriguez Date: Mon, 28 Nov 2022 21:40:48 +0100 Subject: [PATCH 1/6] this does not need to be serialized --- Scripts/NodeDataCache.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/Scripts/NodeDataCache.cs b/Scripts/NodeDataCache.cs index 4f4937d..f381845 100644 --- a/Scripts/NodeDataCache.cs +++ b/Scripts/NodeDataCache.cs @@ -220,7 +220,6 @@ namespace XNode { } } - [System.Serializable] private class PortDataCache : Dictionary> { } } } From 6684d8336c1812a396b827fa6a3c430e6b719dcc Mon Sep 17 00:00:00 2001 From: Simon Rodriguez Date: Mon, 28 Nov 2022 21:43:09 +0100 Subject: [PATCH 2/6] clean whitespace --- Scripts/NodeDataCache.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Scripts/NodeDataCache.cs b/Scripts/NodeDataCache.cs index f381845..c559fe9 100644 --- a/Scripts/NodeDataCache.cs +++ b/Scripts/NodeDataCache.cs @@ -36,8 +36,8 @@ namespace XNode { Dictionary staticPorts; if (!portDataCache.TryGetValue(nodeType, out staticPorts)) { - staticPorts = new Dictionary(); - } + staticPorts = new Dictionary(); + } // Cleanup port dict - Remove nonexisting static ports - update static port types // AND update dynamic ports (albeit only those in lists) too, in order to enforce proper serialisation. @@ -69,6 +69,7 @@ namespace XNode { dynamicListPorts.Add(port); } } + // Add missing ports foreach (NodePort staticPort in staticPorts.Values) { if (!ports.ContainsKey(staticPort.fieldName)) { @@ -206,8 +207,8 @@ namespace XNode { if (inputAttrib != null && outputAttrib != null) Debug.LogError("Field " + fieldInfo[i].Name + " of type " + nodeType.FullName + " cannot be both input and output."); else { if (!portDataCache.ContainsKey(nodeType)) portDataCache.Add(nodeType, new Dictionary()); - NodePort port = new NodePort(fieldInfo[i]); - portDataCache[nodeType].Add(port.fieldName, port); + NodePort port = new NodePort(fieldInfo[i]); + portDataCache[nodeType].Add(port.fieldName, port); } if (formerlySerializedAsAttribute != null) { From 5d3fa35067e659b2ca8dda121115f4b008942960 Mon Sep 17 00:00:00 2001 From: Simon Rodriguez Date: Mon, 28 Nov 2022 21:43:55 +0100 Subject: [PATCH 3/6] use string.substring instead of string.split that creates a array --- Scripts/NodeDataCache.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Scripts/NodeDataCache.cs b/Scripts/NodeDataCache.cs index c559fe9..e1b465c 100644 --- a/Scripts/NodeDataCache.cs +++ b/Scripts/NodeDataCache.cs @@ -125,10 +125,11 @@ namespace XNode { // Ports flagged as "dynamicPortList = true" end up having a "backing port" and a name with an index, but we have // no guarantee that a dynamic port called "output 0" is an element in a list backed by a static "output" port. // Thus, we need to check for attributes... (but at least we don't need to look at all fields this time) - string[] fieldNameParts = port.fieldName.Split(' '); - if (fieldNameParts.Length != 2) return false; + int fieldNameSpaceIndex = port.fieldName.IndexOf(' '); + if (fieldNameSpaceIndex < 0) return false; + string fieldNamePart = port.fieldName.Substring(0, fieldNameSpaceIndex); - FieldInfo backingPortInfo = port.node.GetType().GetField(fieldNameParts[0]); + FieldInfo backingPortInfo = port.node.GetType().GetField(fieldNamePart); if (backingPortInfo == null) return false; object[] attribs = backingPortInfo.GetCustomAttributes(true); From 837ffe4ae15b3ccc4d4160bf05e4006b28ef95d2 Mon Sep 17 00:00:00 2001 From: Simon Rodriguez Date: Mon, 28 Nov 2022 21:45:09 +0100 Subject: [PATCH 4/6] reuse dynamicListPorts, as it could be created for every port with one or two allocations --- Scripts/NodeDataCache.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Scripts/NodeDataCache.cs b/Scripts/NodeDataCache.cs index e1b465c..da3a86e 100644 --- a/Scripts/NodeDataCache.cs +++ b/Scripts/NodeDataCache.cs @@ -9,6 +9,7 @@ namespace XNode { private static PortDataCache portDataCache; private static Dictionary> formerlySerializedAsCache; private static Dictionary typeQualifiedNameCache; + private static List dynamicListPorts; private static bool Initialized { get { return portDataCache != null; } } public static string GetTypeQualifiedName(System.Type type) { @@ -32,7 +33,6 @@ namespace XNode { Dictionary formerlySerializedAs = null; if (formerlySerializedAsCache != null) formerlySerializedAsCache.TryGetValue(nodeType, out formerlySerializedAs); - List dynamicListPorts = new List(); Dictionary staticPorts; if (!portDataCache.TryGetValue(nodeType, out staticPorts)) { @@ -103,6 +103,8 @@ namespace XNode { listPort.connectionType = backingPort.connectionType; listPort.typeConstraint = backingPort.typeConstraint; } + + dynamicListPorts.Clear(); } /// @@ -144,6 +146,7 @@ namespace XNode { /// Cache node types private static void BuildCache() { portDataCache = new PortDataCache(); + dynamicListPorts = new List(); System.Type baseType = typeof(Node); List nodeTypes = new List(); System.Reflection.Assembly[] assemblies = System.AppDomain.CurrentDomain.GetAssemblies(); From 5641110416fa376b7d9b1d145fd03f7f370ef9aa Mon Sep 17 00:00:00 2001 From: Simon Rodriguez Date: Mon, 28 Nov 2022 21:45:44 +0100 Subject: [PATCH 5/6] lazy create removedPorts as its most often not used --- Scripts/NodeDataCache.cs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/Scripts/NodeDataCache.cs b/Scripts/NodeDataCache.cs index da3a86e..fa19ed0 100644 --- a/Scripts/NodeDataCache.cs +++ b/Scripts/NodeDataCache.cs @@ -27,8 +27,8 @@ namespace XNode { public static void UpdatePorts(Node node, Dictionary ports) { if (!Initialized) BuildCache(); - Dictionary> removedPorts = new Dictionary>(); System.Type nodeType = node.GetType(); + Dictionary> removedPorts = null; Dictionary formerlySerializedAs = null; if (formerlySerializedAsCache != null) formerlySerializedAsCache.TryGetValue(nodeType, out formerlySerializedAs); @@ -49,7 +49,10 @@ namespace XNode { // If port exists but with wrong settings, remove it. Re-add it later. if (port.IsDynamic || port.direction != staticPort.direction || port.connectionType != staticPort.connectionType || port.typeConstraint != staticPort.typeConstraint) { // If port is not dynamic and direction hasn't changed, add it to the list so we can try reconnecting the ports connections. - if (!port.IsDynamic && port.direction == staticPort.direction) removedPorts.Add(port.fieldName, port.GetConnections()); + if (!port.IsDynamic && port.direction == staticPort.direction) { + if (removedPorts == null) removedPorts = new Dictionary>(); + removedPorts.Add(port.fieldName, port.GetConnections()); + } port.ClearConnections(); ports.Remove(port.fieldName); } else port.ValueType = staticPort.ValueType; @@ -59,7 +62,10 @@ namespace XNode { //See if the field is tagged with FormerlySerializedAs, if so add the port with its new field name to removedPorts // so it can be reconnected in missing ports stage. string newName = null; - if (formerlySerializedAs != null && formerlySerializedAs.TryGetValue(port.fieldName, out newName)) removedPorts.Add(newName, port.GetConnections()); + if (formerlySerializedAs != null && formerlySerializedAs.TryGetValue(port.fieldName, out newName)) { + if (removedPorts == null) removedPorts = new Dictionary>(); + removedPorts.Add(newName, port.GetConnections()); + } port.ClearConnections(); ports.Remove(port.fieldName); @@ -76,7 +82,7 @@ namespace XNode { NodePort port = new NodePort(staticPort, node); //If we just removed the port, try re-adding the connections List reconnectConnections; - if (removedPorts.TryGetValue(staticPort.fieldName, out reconnectConnections)) { + if (removedPorts != null && removedPorts.TryGetValue(staticPort.fieldName, out reconnectConnections)) { for (int i = 0; i < reconnectConnections.Count; i++) { NodePort connection = reconnectConnections[i]; if (connection == null) continue; From c17804049423524fdad46848eeb5e9ee7218155f Mon Sep 17 00:00:00 2001 From: Simon Rodriguez Date: Wed, 30 Nov 2022 10:30:35 +0100 Subject: [PATCH 6/6] reduces reload time from 400ms to 7ms in our project probably very related to project size --- Scripts/NodeDataCache.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Scripts/NodeDataCache.cs b/Scripts/NodeDataCache.cs index fa19ed0..9ec08ed 100644 --- a/Scripts/NodeDataCache.cs +++ b/Scripts/NodeDataCache.cs @@ -153,6 +153,10 @@ namespace XNode { private static void BuildCache() { portDataCache = new PortDataCache(); dynamicListPorts = new List(); + +#if UNITY_2019_2_OR_NEWER && UNITY_EDITOR + List nodeTypes = UnityEditor.TypeCache.GetTypesDerivedFrom().Where(type => !type.IsAbstract).ToList(); +#else System.Type baseType = typeof(Node); List nodeTypes = new List(); System.Reflection.Assembly[] assemblies = System.AppDomain.CurrentDomain.GetAssemblies(); @@ -177,6 +181,7 @@ namespace XNode { break; } } +#endif for (int i = 0; i < nodeTypes.Count; i++) { CachePorts(nodeTypes[i]);