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();
}
}
}
}
}