diff --git a/Editor/Scripts/Data/PropertyData.cs b/Editor/Scripts/Data/PropertyData.cs index 208445e..515e41e 100644 --- a/Editor/Scripts/Data/PropertyData.cs +++ b/Editor/Scripts/Data/PropertyData.cs @@ -7,6 +7,8 @@ namespace AYellowpaper.SerializedCollections.Editor.Data [System.Serializable] internal class PropertyData { + [SerializeField] + private float _keyLabelWidth; [SerializeField] private ElementData _keyData; [SerializeField] @@ -20,6 +22,12 @@ public bool AlwaysShowSearch set => _alwaysShowSearch = value; } + public float KeyLabelWidth + { + get => _keyLabelWidth; + set => _keyLabelWidth = value; + } + public ElementData GetElementData(bool fieldType) { return fieldType == SCEditorUtility.KeyFlag ? _keyData : _valueData; diff --git a/Editor/Scripts/SerializedDictionaryDrawer.cs b/Editor/Scripts/SerializedDictionaryDrawer.cs index afc3980..67a1f76 100644 --- a/Editor/Scripts/SerializedDictionaryDrawer.cs +++ b/Editor/Scripts/SerializedDictionaryDrawer.cs @@ -13,7 +13,10 @@ namespace AYellowpaper.SerializedCollections.Editor { - [CustomPropertyDrawer(typeof(SerializedDictionary<,>))] +#if ODIN_INSPECTOR + [Sirenix.OdinInspector.Editor.DrawerPriority(Sirenix.OdinInspector.Editor.DrawerPriorityLevel.SuperPriority)] +#endif + [CustomPropertyDrawer(typeof(SerializedDictionary<,>), true)] public class SerializedDictionaryDrawer : PropertyDrawer { public const string KeyName = nameof(SerializedKeyValuePair.Key); diff --git a/Editor/Scripts/SerializedDictionaryInstanceDrawer.cs b/Editor/Scripts/SerializedDictionaryInstanceDrawer.cs index 2656453..ce8f52b 100644 --- a/Editor/Scripts/SerializedDictionaryInstanceDrawer.cs +++ b/Editor/Scripts/SerializedDictionaryInstanceDrawer.cs @@ -15,6 +15,8 @@ namespace AYellowpaper.SerializedCollections.Editor { public class SerializedDictionaryInstanceDrawer { + private const float MinKeyValueLabelWidth = 40f; + private FieldInfo _fieldInfo; private ReorderableList _unexpandedList; private SingleEditingData _singleEditingData; @@ -156,17 +158,30 @@ private void UpdateAfterInput() { InitializeSettingsIfNeeded(); ProcessState(); + CheckIfNewDictionary(); CheckPaging(); var elementsPerPage = EditorUserSettings.Get().ElementsPerPage; int pageCount = Mathf.Max(1, Mathf.CeilToInt((float)DefaultState.ListSize / elementsPerPage)); ToggleSearchBar(_propertyData.AlwaysShowSearch ? true : SCEditorUtility.ShouldShowSearch(pageCount)); } + // TODO: This works for now, but isn't perfect. This checks if the serialized dictionary was reassigned with new(), simply by comparing the count. Should be instead done by reference equality in the future + private void CheckIfNewDictionary() + { + if (_singleEditingData.IsValid && _singleEditingData.LookupTable.GetCount() != _activeState.ListSize) + { + var dictionary = SCEditorUtility.GetPropertyValue(ListProperty, ListProperty.serializedObject.targetObject); + _singleEditingData.LookupTable = GetLookupTable(dictionary); + _singleEditingData.LookupTable.RecalculateOccurences(); + } + } + private void InitializeSettingsIfNeeded() { void InitializeSettings(bool fieldFlag) { - var genericArgs = _fieldInfo.FieldType.GetGenericArguments(); + var dictionaryType = FindGenericBaseType(typeof(SerializedDictionary<,>), _fieldInfo.FieldType); + var genericArgs = dictionaryType.GetGenericArguments(); var firstProperty = ListProperty.GetArrayElementAtIndex(0); var keySettings = CreateDisplaySettings(GetElementProperty(firstProperty, fieldFlag), genericArgs[fieldFlag == SCEditorUtility.KeyFlag ? 0 : 1]); var settings = _propertyData.GetElementData(fieldFlag).Settings; @@ -183,6 +198,19 @@ void InitializeSettings(bool fieldFlag) } } + private static Type FindGenericBaseType(Type generic, Type toCheck) + { + while (toCheck != null && toCheck != typeof(object)) + { + var cur = toCheck.IsGenericType ? toCheck.GetGenericTypeDefinition() : toCheck; + if (generic == cur) { + return toCheck; + } + toCheck = toCheck.BaseType; + } + return null; + } + private void CheckPaging() { // TODO: Is there a better solution to check for Revert/delete/add? @@ -253,7 +281,7 @@ private ReorderableList MakeList() private ReorderableList MakeUnexpandedList() { var list = new ReorderableList(SerializedDictionaryDrawer.NoEntriesList, typeof(int)); - list.drawHeaderCallback = DrawUnexpandedHeader; + list.drawHeaderCallback = OnDrawUnexpandedHeader; return list; } @@ -276,7 +304,7 @@ private void OnDrawNoneElement(Rect rect) private (DisplayType displayType, bool canToggleListDrawer) CreateDisplaySettings(SerializedProperty property, Type type) { - bool hasCustomEditor = SCEditorUtility.HasDrawerForType(type); + bool hasCustomEditor = SCEditorUtility.HasDrawerForProperty(property, type); bool isGenericWithChildren = property.propertyType == SerializedPropertyType.Generic && property.hasVisibleChildren; bool isArray = property.isArray && property.propertyType != SerializedPropertyType.String; bool canToggleListDrawer = isArray || (isGenericWithChildren && hasCustomEditor); @@ -288,18 +316,6 @@ private void OnDrawNoneElement(Rect rect) return (displayType, canToggleListDrawer); } - private void DrawUnexpandedHeader(Rect rect) - { - EditorGUI.BeginProperty(rect, _label, ListProperty); - ListProperty.isExpanded = EditorGUI.Foldout(rect.WithX(rect.x - 5), ListProperty.isExpanded, _label, true); - - var detailsStyle = EditorStyles.miniLabel; - var detailsRect = rect.AppendRight(0).AppendLeft(detailsStyle.CalcSize(_shortDetailsContent).x); - GUI.Label(detailsRect, _shortDetailsContent, detailsStyle); - - EditorGUI.EndProperty(); - } - private void DoPaging(Rect rect) { EditorGUI.BeginChangeCheck(); @@ -326,6 +342,20 @@ private void OnDrawHeader(Rect rect) UpdateAfterInput(); } + + private void OnDrawUnexpandedHeader(Rect rect) + { + EditorGUI.BeginProperty(rect, _label, ListProperty); + ListProperty.isExpanded = EditorGUI.Foldout(rect.WithX(rect.x - 5), ListProperty.isExpanded, _label, true); + + var detailsStyle = EditorStyles.miniLabel; + var detailsRect = rect.AppendRight(0).AppendLeft(detailsStyle.CalcSize(_shortDetailsContent).x); + GUI.Label(detailsRect, _shortDetailsContent, detailsStyle); + + EditorGUI.EndProperty(); + + UpdateAfterInput(); + } private void DoMainHeader(Rect rect) { @@ -405,14 +435,26 @@ private void ToggleAlwaysShowSearchPropertyData() private void DoKeyValueRect(Rect rect) { - float width = EditorGUIUtility.labelWidth + 22; + var width = GetDesiredKeyLabelWidth(rect.width, 22); Rect leftRect = rect.WithWidth(width); Rect rightRect = leftRect.AppendRight(rect.width - width); - if (Event.current.type == EventType.Repaint && _propertyData != null) + if (_propertyData != null) { - _keyValueStyle.Draw(leftRect, EditorGUIUtility.TrTextContent(_propertyData.GetElementData(SerializedDictionaryDrawer.KeyFlag).Settings.DisplayName), false, false, false, false); - _keyValueStyle.Draw(rightRect, EditorGUIUtility.TrTextContent(_propertyData.GetElementData(SerializedDictionaryDrawer.ValueFlag).Settings.DisplayName), false, false, false, false); + if (Event.current.type == EventType.Repaint) + { + _keyValueStyle.Draw(leftRect, EditorGUIUtility.TrTextContent(_propertyData.GetElementData(SerializedDictionaryDrawer.KeyFlag).Settings.DisplayName), false, false, false, false); + _keyValueStyle.Draw(rightRect, EditorGUIUtility.TrTextContent(_propertyData.GetElementData(SerializedDictionaryDrawer.ValueFlag).Settings.DisplayName), false, false, false, false); + } + var changeSizeRect = leftRect.AppendRight(5); + changeSizeRect.x -= 2; + EditorGUI.BeginChangeCheck(); + float newWidth = SCEditorUtility.DoHorizontalScale(changeSizeRect, _propertyData.KeyLabelWidth > 0f ? _propertyData.KeyLabelWidth : width); + if (EditorGUI.EndChangeCheck()) + { + _propertyData.KeyLabelWidth = Mathf.Max(newWidth, MinKeyValueLabelWidth); + SavePropertyData(); + } } if (ListProperty.minArraySize > 0) @@ -424,6 +466,14 @@ private void DoKeyValueRect(Rect rect) EditorGUI.DrawRect(rect.AppendDown(1, -1), SerializedDictionaryDrawer.BorderColor); } + private float GetDesiredKeyLabelWidth(float maxWidth, float offset = 0f) + { + float desiredWidth = _propertyData is { KeyLabelWidth: > 0 } + ? _propertyData.KeyLabelWidth + : EditorGUIUtility.labelWidth; + return Mathf.Clamp(desiredWidth + offset, MinKeyValueLabelWidth, maxWidth - MinKeyValueLabelWidth); + } + private void DoSearch(Rect rect) { EditorGUI.DrawRect(rect.AppendLeft(1), SerializedDictionaryDrawer.BorderColor); @@ -555,7 +605,7 @@ private float OnGetElementHeight(int index) { int actualIndex = _pagedIndices[index]; var element = _activeState.GetPropertyAtIndex(actualIndex); - return CalculateHeightOfElement(element, _propertyData.GetElementData(SerializedDictionaryDrawer.KeyFlag).EffectiveDisplayType == DisplayType.List ? true : false, _propertyData.GetElementData(SerializedDictionaryDrawer.ValueFlag).EffectiveDisplayType == DisplayType.List ? true : false); + return CalculateHeightOfElement(element, _propertyData.GetElementData(SerializedDictionaryDrawer.KeyFlag).EffectiveDisplayType == DisplayType.List, _propertyData.GetElementData(SerializedDictionaryDrawer.ValueFlag).EffectiveDisplayType == DisplayType.List); } private void OnDrawElement(Rect rect, int index, bool isActive, bool isFocused) @@ -568,7 +618,7 @@ private void OnDrawElement(Rect rect, int index, bool isActive, bool isFocused) int actualIndex = _pagedIndices[index]; SerializedProperty kvp = _activeState.GetPropertyAtIndex(actualIndex); - Rect keyRect = rect.WithSize(EditorGUIUtility.labelWidth - lineLeftSpace, EditorGUIUtility.singleLineHeight); + Rect keyRect = rect.WithSize(GetDesiredKeyLabelWidth(rect.width) - lineLeftSpace, EditorGUIUtility.singleLineHeight); Rect lineRect = keyRect.WithXAndWidth(keyRect.x + keyRect.width + lineLeftSpace, lineWidth).WithHeight(rect.height); Rect valueRect = keyRect.AppendRight(rect.width - keyRect.width - totalSpace, totalSpace); @@ -673,11 +723,6 @@ private void OnRemove(ReorderableList list) { _activeState.RemoveElementAt(_pagedIndices[list.index]); UpdatePaging(); - //int actualIndex = _pagedIndices[list.index]; - //ListProperty.DeleteArrayElementAtIndex(actualIndex); - //UpdatePaging(); - //if (actualIndex >= ListProperty.minArraySize) - // list.index = _pagedIndices.Count - 1; } } } \ No newline at end of file diff --git a/Editor/Scripts/Utility/SCEditorUtility.cs b/Editor/Scripts/Utility/SCEditorUtility.cs index 2d488ca..131d998 100644 --- a/Editor/Scripts/Utility/SCEditorUtility.cs +++ b/Editor/Scripts/Utility/SCEditorUtility.cs @@ -15,21 +15,6 @@ internal static class SCEditorUtility public const bool KeyFlag = true; public const bool ValueFlag = false; - public static bool GetPersistentBool(string path, bool defaultValue) - { - return EditorPrefs.GetBool(EditorPrefsPrefix + path, defaultValue); - } - - public static bool HasKey(string path) - { - return EditorPrefs.HasKey( EditorPrefsPrefix + path ); - } - - public static void SetPersistentBool(string path, bool value) - { - EditorPrefs.SetBool(EditorPrefsPrefix + path, value); - } - public static float CalculateHeight(SerializedProperty property, DisplayType displayType) { return CalculateHeight(property, displayType == DisplayType.List ? true : false); @@ -64,11 +49,6 @@ public static IEnumerable GetChildren(SerializedProperty pro } while (property.NextVisible(recursive) && !SerializedProperty.EqualContents(property, end)); } - public static int GetActualArraySize(SerializedProperty arrayProperty) - { - return GetChildren(arrayProperty).Count() - 1; - } - public static PropertyData GetPropertyData(SerializedProperty property) { var data = new PropertyData(); @@ -90,15 +70,15 @@ public static bool ShouldShowSearch(int pages) return settings.AlwaysShowSearch ? true : pages >= settings.PageCountForSearch; } - public static bool HasDrawerForType(Type type) + public static bool HasDrawerForProperty(SerializedProperty property, Type type) { Type attributeUtilityType = typeof(SerializedProperty).Assembly.GetType("UnityEditor.ScriptAttributeUtility"); if (attributeUtilityType == null) return false; - var getDrawerMethod = attributeUtilityType.GetMethod("GetDrawerTypeForType", BindingFlags.Static | BindingFlags.NonPublic); + var getDrawerMethod = attributeUtilityType.GetMethod("GetDrawerTypeForPropertyAndType", BindingFlags.Static | BindingFlags.NonPublic); if (getDrawerMethod == null) return false; - return getDrawerMethod.Invoke(null, new object[] { type }) != null; + return getDrawerMethod.Invoke(null, new object[] { property, type }) != null; } internal static void AddGenericMenuItem(GenericMenu genericMenu, bool isOn, bool isEnabled, GUIContent content, GenericMenu.MenuFunction action) @@ -134,8 +114,71 @@ internal static bool TryGetTypeFromProperty(SerializedProperty property, out Typ return false; } } + + internal static float DoHorizontalScale(Rect rect, float value) + { + var controlId = GUIUtility.GetControlID(FocusType.Passive); + var isMovingMouse = Event.current.type == EventType.MouseDrag; + DoButtonControl(rect, controlId, false, false, GUIContent.none, GUIStyle.none); + + if (controlId == GUIUtility.hotControl && isMovingMouse) + { + value += Event.current.delta.x; + GUI.changed = true; + } + + EditorGUIUtility.AddCursorRect(rect, MouseCursor.ResizeHorizontal); + return value; + } + + internal static bool DoButtonControl(Rect rect, int id, bool on, bool hover, GUIContent content, GUIStyle style) + { + Event current = Event.current; + switch (current.type) + { + case EventType.MouseDown: + if (HitTest(rect, current.mousePosition)) + { + GUIUtility.hotControl = id; + current.Use(); + } + break; + case EventType.MouseUp: + if (GUIUtility.hotControl == id) + { + GUIUtility.hotControl = 0; + current.Use(); + if (HitTest(rect, current.mousePosition)) + { + GUI.changed = true; + return !on; + } + } + break; + case EventType.MouseDrag: + if (GUIUtility.hotControl == id) + { + current.Use(); + } + break; + case EventType.KeyDown: + bool flag = current.alt || current.shift || current.command || current.control; + if ((current.keyCode == KeyCode.Space || current.keyCode == KeyCode.Return || current.keyCode == KeyCode.KeypadEnter) && !flag && GUIUtility.keyboardControl == id) + { + current.Use(); + GUI.changed = true; + return !on; + } + break; + case EventType.Repaint: + style.Draw(rect, content, id, on, hover); + break; + } + return on; + } + internal static bool HitTest(Rect rect, Vector2 point) => point.x >= rect.xMin && point.x < rect.xMax && point.y >= rect.yMin && point.y < rect.yMax; public static object GetPropertyValue(SerializedProperty prop, object target) @@ -163,10 +206,10 @@ public static object GetValue(object source, string name) if (source == null) return null; var type = source.GetType(); - var f = type.GetField(name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); + var f = type.GetFieldRecursive(name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); if (f == null) { - var p = type.GetProperty(name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase); + var p = type.GetPropertyRecursive(name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase); if (p == null) return null; return p.GetValue(source, null); @@ -182,5 +225,21 @@ public static object GetValue(object source, string name, int index) enm.MoveNext(); return enm.Current; } + + private static FieldInfo GetFieldRecursive(this Type type, string name, BindingFlags bindingFlags) + { + var fieldInfo = type.GetField(name, bindingFlags); + if (fieldInfo == null && type.BaseType != null) + return type.BaseType.GetFieldRecursive(name, bindingFlags); + return fieldInfo; + } + + private static PropertyInfo GetPropertyRecursive(this Type type, string name, BindingFlags bindingFlags) + { + var propertyInfo = type.GetProperty(name, bindingFlags); + if (propertyInfo == null && type.BaseType != null) + return type.BaseType.GetPropertyRecursive(name, bindingFlags); + return propertyInfo; + } } } \ No newline at end of file diff --git a/Runtime/LookupTables/DictionaryLookupTable.cs b/Runtime/LookupTables/DictionaryLookupTable.cs index 0f9fab8..cb85b39 100644 --- a/Runtime/LookupTables/DictionaryLookupTable.cs +++ b/Runtime/LookupTables/DictionaryLookupTable.cs @@ -1,6 +1,7 @@ using System.Collections; using System.Collections.Generic; using System.Linq; +using UnityEngine; namespace AYellowpaper.SerializedCollections { @@ -49,7 +50,7 @@ public void RemoveKey(object key) for (int i = _dictionary._serializedList.Count - 1; i >= 0; i--) { var dictKey = _dictionary._serializedList[i].Key; - if ((object)dictKey == key || dictKey.Equals(key)) + if (SerializedCollectionsUtility.KeysAreEqual(dictKey, key)) _dictionary._serializedList.RemoveAt(i); } } @@ -64,6 +65,11 @@ public object GetKeyAt(int index) return _dictionary._serializedList[index]; } + public int GetCount() + { + return _dictionary._serializedList.Count; + } + public void RemoveDuplicates() { _dictionary._serializedList = _dictionary._serializedList diff --git a/Runtime/LookupTables/IKeyable.cs b/Runtime/LookupTables/IKeyable.cs index 936f076..a0f0791 100644 --- a/Runtime/LookupTables/IKeyable.cs +++ b/Runtime/LookupTables/IKeyable.cs @@ -14,6 +14,7 @@ internal interface IKeyable void RemoveKey(object key); void RemoveAt(int index); object GetKeyAt(int index); + int GetCount(); void RemoveDuplicates(); } } diff --git a/Runtime/Scripts/SerializedCollectionsUtility.cs b/Runtime/Scripts/SerializedCollectionsUtility.cs index a612562..f3f7b29 100644 --- a/Runtime/Scripts/SerializedCollectionsUtility.cs +++ b/Runtime/Scripts/SerializedCollectionsUtility.cs @@ -11,12 +11,17 @@ public static bool IsValidKey(object obj) // we catch this error if we are not on the main thread and simply return false as we assume the object is null try { - return !(obj is Object unityObject && unityObject == null); + return !(obj == null || (obj is Object unityObject && unityObject == null)); } catch { return false; } } + + public static bool KeysAreEqual(T key, object otherKey) + { + return (object)key == otherKey || key.Equals(otherKey); + } } } \ No newline at end of file diff --git a/Runtime/Scripts/SerializedDictionary.cs b/Runtime/Scripts/SerializedDictionary.cs index 3af95db..f932f3d 100644 --- a/Runtime/Scripts/SerializedDictionary.cs +++ b/Runtime/Scripts/SerializedDictionary.cs @@ -1,15 +1,16 @@ using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using UnityEngine; namespace AYellowpaper.SerializedCollections { [System.Serializable] - public partial class SerializedDictionary : Dictionary, ISerializationCallbackReceiver + public class SerializedDictionary : Dictionary, ISerializationCallbackReceiver { [SerializeField] internal List> _serializedList = new List>(); - + #if UNITY_EDITOR internal IKeyable LookupTable { @@ -23,16 +24,127 @@ internal IKeyable LookupTable private DictionaryLookupTable _lookupTable; #endif + + public SerializedDictionary() : base() {} + + public SerializedDictionary(SerializedDictionary serializedDictionary) : base(serializedDictionary) + { +#if UNITY_EDITOR + foreach (var kvp in serializedDictionary._serializedList) + _serializedList.Add(new SerializedKeyValuePair(kvp.Key, kvp.Value)); +#endif + } + + public SerializedDictionary(IDictionary dictionary) : base(dictionary) + { + SyncDictionaryToBackingField_Editor(); + } + + public SerializedDictionary(IDictionary dictionary, IEqualityComparer comparer) : base( + dictionary, comparer) + { + SyncDictionaryToBackingField_Editor(); + } + + public SerializedDictionary(IEnumerable> collection) : base(collection) + { + SyncDictionaryToBackingField_Editor(); + } + + public SerializedDictionary(IEnumerable> collection, + IEqualityComparer comparer) : base(collection, comparer) + { + SyncDictionaryToBackingField_Editor(); + } + public SerializedDictionary(IEqualityComparer comparer) : base(comparer) { } + public SerializedDictionary(int capacity) : base(capacity) { } + public SerializedDictionary(int capacity, IEqualityComparer comparer) : base(capacity, comparer) { } + + [Conditional("UNITY_EDITOR")] + private void SyncDictionaryToBackingField_Editor() + { + foreach (var kvp in this) + _serializedList.Add(new SerializedKeyValuePair(kvp.Key, kvp.Value)); + } + +#if UNITY_EDITOR + public new TValue this[TKey key] + { + get => base[key]; + set + { + base[key] = value; + bool anyEntryWasFound = false; + for (int i = 0; i < _serializedList.Count; i++) + { + var kvp = _serializedList[i]; + if (!SerializedCollectionsUtility.KeysAreEqual(key, kvp.Key)) + continue; + anyEntryWasFound = true; + kvp.Value = value; + _serializedList[i] = kvp; + } + + if (!anyEntryWasFound) + _serializedList.Add(new SerializedKeyValuePair(key, value)); + } + } + + public new void Add(TKey key, TValue value) + { + base.Add(key, value); + _serializedList.Add(new SerializedKeyValuePair(key, value)); + } + + public new void Clear() + { + base.Clear(); + _serializedList.Clear(); + } + + public new bool Remove(TKey key) + { + if (TryGetValue(key, out var value)) + { + base.Remove(key); + _serializedList.Remove(new SerializedKeyValuePair(key, value)); + return true; + } + + return false; + } + + public new bool TryAdd(TKey key, TValue value) + { + if (base.TryAdd(key, value)) + { + _serializedList.Add(new SerializedKeyValuePair(key, value)); + return true; + } + + return false; + } + + /// + /// Only available in Editor. Add a key value pair, even if the key already exists in the dictionary. + /// + public void AddConflictAllowed(TKey key, TValue value) + { + if (!ContainsKey(key)) + base.Add(key, value); + _serializedList.Add(new SerializedKeyValuePair(key, value)); + } +#endif public void OnAfterDeserialize() { - Clear(); + base.Clear(); foreach (var kvp in _serializedList) { #if UNITY_EDITOR - if (!ContainsKey(kvp.Key)) - Add(kvp.Key, kvp.Value); + if (SerializedCollectionsUtility.IsValidKey(kvp.Key) && !ContainsKey(kvp.Key)) + base.Add(kvp.Key, kvp.Value); #else Add(kvp.Key, kvp.Value); #endif @@ -50,6 +162,14 @@ public void OnBeforeSerialize() #if UNITY_EDITOR if (UnityEditor.BuildPipeline.isBuildingPlayer) LookupTable.RemoveDuplicates(); + + // TODO: is there a better way to check if the dictionary was deserialized with reflection? + if (_serializedList.Count == 0 && Count > 0) + SyncDictionaryToBackingField_Editor(); +#else + _serializedList.Clear(); + foreach (var kvp in this) + _serializedList.Add(new SerializedKeyValuePair(kvp.Key, kvp.Value)); #endif } } diff --git a/Samples~/Usage/SerializedDictionarySample.unity b/Samples~/Usage/SerializedDictionarySample.unity index 4cb2419..dbc6053 100644 --- a/Samples~/Usage/SerializedDictionarySample.unity +++ b/Samples~/Usage/SerializedDictionarySample.unity @@ -209,6 +209,58 @@ Transform: m_Father: {fileID: 0} m_RootOrder: 2 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1275956276 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1275956278} + - component: {fileID: 1275956279} + m_Layer: 0 + m_Name: UnityObjectKeys + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &1275956278 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1275956276} + 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: 3 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &1275956279 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1275956276} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 62752a297e2d2104eb3704071566e844, type: 3} + m_Name: + m_EditorClassIdentifier: + _nameOverrides: + _serializedList: + - Key: {fileID: 0} + Value: + - Key: {fileID: 0} + Value: + - Key: {fileID: 0} + Value: --- !u!4 &3293770536253637320 Transform: m_ObjectHideFlags: 0 diff --git a/Samples~/Usage/SerializedDictionarySampleThree.cs b/Samples~/Usage/SerializedDictionarySampleThree.cs new file mode 100644 index 0000000..f89d1d1 --- /dev/null +++ b/Samples~/Usage/SerializedDictionarySampleThree.cs @@ -0,0 +1,12 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +namespace AYellowpaper.SerializedCollections +{ + public class SerializedDictionarySampleThree : MonoBehaviour + { + [SerializeField] + private SerializedDictionary _nameOverrides; + } +} \ No newline at end of file diff --git a/Samples~/Usage/SerializedDictionarySampleThree.cs.meta b/Samples~/Usage/SerializedDictionarySampleThree.cs.meta new file mode 100644 index 0000000..5afe49a --- /dev/null +++ b/Samples~/Usage/SerializedDictionarySampleThree.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 62752a297e2d2104eb3704071566e844 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/package.json b/package.json index 5e5c301..76eebc4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ayellowpaper.serialized-dictionary", - "version": "1.0.0", + "version": "1.1.0", "displayName": "Serialized Dictionary", "unity": "2021.3", "description": "Serialized Dictionary enables you to serialize dictionaries, including a very easy to use, native-feeling editor, search, duplicate keys in editor for testing and debugging and much more.",