using System; using System.Collections; using System.Collections.Generic; using PrefsGUI.Utility; namespace PrefsGUI { /// /// List style PrefsGUI /// [Serializable] public class PrefsDictionary : PrefsListBase, List.KeyValue>>, IDictionary { public PrefsDictionary(string key) : base(key, new SerializableDictionary()) { } public PrefsDictionary(string key, IDictionary defaultValue ) : base(key, new SerializableDictionary(defaultValue)) { } protected void UpdateValue(Action> action) { var value = Get(); action(value); Set(value); } protected bool UpdateValueIfSuccess(Func, bool> func) { var value = Get(); var success = func(value); { Set(value); } return success; } #region Dictionary Methods public bool ContainsValue(TValue value) => Get().ContainsValue(value); public bool TryAdd(TKey dictionaryKey, TValue value) => UpdateValueIfSuccess(d => d.TryAdd(dictionaryKey, value)); #endregion #region PrefsListBase public override int DefaultValueCount => defaultValue.Count; public override bool IsDefaultAt(int idx) { var defaultList = defaultValue.SerializeList; if (idx >= defaultList.Count) return false; var list = Get().SerializeList; return PrefsAnyUtility.IsEqual(list[idx], defaultList[idx]); } public override void ResetToDefaultAt(int idx) { var defaultList = defaultValue.SerializeList; if (idx >= defaultList.Count) return; var serializableDictionary = Get(); var list = serializableDictionary.SerializeList; if (SetListItemIfNotEqual(list, idx, defaultList[idx])) { Set(serializableDictionary); } } protected override IListAccessor.KeyValue>> CreateListAccessor() => new ListAccessor(this); #endregion #region IEnumerable IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); #endregion #region IEnumerable>, public IEnumerator> GetEnumerator() => Get().GetEnumerator(); #endregion #region ICollection> public int Count => Get().Count; public bool IsReadOnly => ((ICollection>)Get()).IsReadOnly; public void Add(KeyValuePair item) => Add(item.Key, item.Value); public void Clear() => UpdateValue(d => d.Clear()); public bool Contains(KeyValuePair item) => Get().Contains(item); public void CopyTo(KeyValuePair[] array, int arrayIndex) { ((ICollection>)Get()).CopyTo(array, arrayIndex); } public bool Remove(TKey dictionaryKey) => UpdateValueIfSuccess(d => d.Remove(dictionaryKey)); #endregion #region IDictionary public TValue this[TKey dictionaryKey] { get => Get()[dictionaryKey]; set => UpdateValue(d => d[dictionaryKey] = value); } public ICollection Keys => Get().Keys; public ICollection Values => Get().Values; public void Add(TKey dictionaryKey, TValue value) => UpdateValue(d => d.Add(dictionaryKey, value)); public bool ContainsKey(TKey dictionaryKey) => Get().ContainsKey(dictionaryKey); public bool Remove(KeyValuePair item) => UpdateValueIfSuccess(d => ((ICollection>)d).Remove(item)); public bool TryGetValue(TKey dictionaryKey, out TValue value) => Get().TryGetValue(dictionaryKey, out value); #endregion private class ListAccessor : IListAccessor.KeyValue>> { private readonly PrefsDictionary prefs; public ListAccessor(PrefsDictionary prefs) => this.prefs = prefs; public List.KeyValue> InnerList { get => prefs.Get().SerializeList; // set が呼ばれることでUI側の変更を通知してもらう set { var serializedDictionary = prefs.Get(); serializedDictionary.SerializeList = value; // SerializeListでPrefsのInner(string)を更新する prefs.Set(serializedDictionary); // prefs.Set()でPrefsのOuterが更新される可能性を考慮して念のため再度Get() // 現状の作りでは更新はないはずだが serializedDictionary = prefs.Get(); // SerializedDictionaryのDictionaryをSerializeListで更新する serializedDictionary.OnAfterDeserialize(); } } } } }