From dc73568d5e7096ba0f8d3691a56654c8ccc13706 Mon Sep 17 00:00:00 2001 From: Luke Stampfli Date: Tue, 13 Apr 2021 11:07:00 +0200 Subject: [PATCH] feat: NodePortDictionary serialize keys and value lists directly to retain port order. --- Scripts/Node.cs | 88 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 81 insertions(+), 7 deletions(-) diff --git a/Scripts/Node.cs b/Scripts/Node.cs index 704e99d3..c3f18c49 100644 --- a/Scripts/Node.cs +++ b/Scripts/Node.cs @@ -389,27 +389,101 @@ public NodeWidthAttribute(int width) { } #endregion - [Serializable] private class NodePortDictionary : Dictionary, ISerializationCallbackReceiver { + [Serializable] private class NodePortDictionary : ISerializationCallbackReceiver { [SerializeField] private List keys = new List(); [SerializeField] private List values = new List(); + private Dictionary dictionary = new Dictionary(); + + /// + /// Gets the underlying dictionary of the NodePortDictionary. This dictionary should be used as read only. Changes to this dictionary will not be serialized. + /// + public Dictionary Dictionary => dictionary; + /// + /// Gets the keys of the NodePortDictionary. Keys are ordered by insertion time.. + /// + public List Keys => keys; + /// + /// Gets the values in the NodePortDictionary. Values are ordered by insertion time. + /// + public List Values => values; + + /// + /// Adds the specified key and value to the NodePortDictionary. + /// + /// The key of the element to add. + /// The value of the element to add. + public void Add(string key, NodePort value) { + keys.Add(key); + values.Add(value); + dictionary.Add(key, value); + } - public void OnBeforeSerialize() { + /// + /// Gets the value associated with the specified key. + /// + /// The key of the value to get. + /// The value associated with the specified key. + public NodePort this[string key] { + get => dictionary[key]; + } + + /// + /// Determines whether the NodePortDictionary contains the specified key. + /// + /// The key to locate in the NodePortDictionary. + /// true if the NodePortDictionary contains an element with the specified key; otherwise, false. + public bool ContainsKey(string key) { + return dictionary.ContainsKey(key); + } + + /// + /// Gets the value associated with the specified key. + /// + /// The key of the value to get. + /// When this method returns, contains the value associated with the specified key, if the key is found; otherwise, the default value for the type of the value parameter. + /// true if the NodePortDictionary contains an element with the specified key; otherwise, false. + public bool TryGetValue(string key, out NodePort value) { + var result = dictionary.TryGetValue(key, out NodePort dictionaryValue); + value = dictionaryValue; + return result; + } + + /// + /// Removes all keys and values from the NodePortDictionary + /// + public void Clear() + { + dictionary.Clear(); keys.Clear(); values.Clear(); - foreach (KeyValuePair pair in this) { - keys.Add(pair.Key); - values.Add(pair.Value); + } + + /// + /// Removes the value with the specified key from the NodePortDictionary. + /// + /// The key of the element to remove. + /// true if the element is successfully found and removed; otherwise, false. + public bool Remove(string key) { + if (dictionary.ContainsKey(key)) + { + var index = keys.IndexOf(key); + keys.RemoveAt(index); + values.RemoveAt(index); } + return dictionary.Remove(key); + } + + public void OnBeforeSerialize() { } public void OnAfterDeserialize() { - this.Clear(); + dictionary.Clear(); if (keys.Count != values.Count) throw new System.Exception("there are " + keys.Count + " keys and " + values.Count + " values after deserialization. Make sure that both key and value types are serializable."); for (int i = 0; i < keys.Count; i++) - this.Add(keys[i], values[i]); + dictionary.Add(keys[i], values[i]); } } }