XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFEExtension.NetCore.AutoConfig

【DLL】自动实现配置文件的存储

公开
关注 0 Fork 0 Star 0
UTF-8
using System.Collections;

namespace XFEExtension.NetCore.AutoConfig;

/// <summary>
/// 支持线程安全访问和合并自动保存的配置文件列表
/// </summary>
/// <typeparam name="TValue">列表泛型</typeparam>
public class ProfileList<TValue> : ICollection<TValue>, IEnumerable<TValue>, IEnumerable, IList<TValue>, IReadOnlyCollection<TValue>, IReadOnlyList<TValue>, ICollection, IList, IProfileOwnedCollection
{
    private readonly List<TValue> _innerList;
    private readonly object _syncRoot = new();
    private XFEProfile? _currentProfile;

    /// <summary>
    /// 创建空列表
    /// </summary>
    public ProfileList() => _innerList = [];

    /// <summary>
    /// 使用已有列表创建
    /// </summary>
    /// <param name="innerList">已有列表</param>
    public ProfileList(List<TValue> innerList) => _innerList = innerList;

    ///<inheritdoc/>
    public TValue this[int index]
    {
        get
        {
            lock (_syncRoot)
                return _innerList[index];
        }
        set
        {
            lock (_syncRoot)
            {
                _innerList[index] = value;
                RequestSave();
            }
        }
    }

    object? IList.this[int index]
    {
        get
        {
            lock (_syncRoot)
                return ((IList)_innerList)[index];
        }
        set
        {
            lock (_syncRoot)
            {
                ((IList)_innerList)[index] = value;
                RequestSave();
            }
        }
    }

    /// <summary>
    /// 当前配置文件实例
    /// </summary>
    public XFEProfile? CurrentProfile
    {
        get
        {
            lock (_syncRoot)
                return _currentProfile;
        }
        set
        {
            lock (_syncRoot)
                _currentProfile = value;
        }
    }

    ///<inheritdoc/>
    public int Count
    {
        get
        {
            lock (_syncRoot)
                return _innerList.Count;
        }
    }

    ///<inheritdoc/>
    public bool IsReadOnly => ((ICollection<TValue>)_innerList).IsReadOnly;

    ///<inheritdoc/>
    public bool IsSynchronized => true;

    ///<inheritdoc/>
    public object SyncRoot => _syncRoot;

    ///<inheritdoc/>
    public bool IsFixedSize => ((IList)_innerList).IsFixedSize;

    ///<inheritdoc/>
    public void Add(TValue item)
    {
        lock (_syncRoot)
        {
            _innerList.Add(item);
            RequestSave();
        }
    }

    ///<inheritdoc/>
    public int Add(object? value)
    {
        lock (_syncRoot)
        {
            var result = ((IList)_innerList).Add(value);
            RequestSave();
            return result;
        }
    }

    ///<inheritdoc/>
    public void AddRange(IEnumerable<TValue> collection)
    {
        var items = collection.ToArray();
        if (items.Length == 0)
            return;
        lock (_syncRoot)
        {
            _innerList.AddRange(items);
            RequestSave();
        }
    }

    ///<inheritdoc/>
    public void AddRange(ReadOnlySpan<TValue> source)
    {
        if (source.IsEmpty)
            return;
        lock (_syncRoot)
        {
            _innerList.AddRange(source);
            RequestSave();
        }
    }

    ///<inheritdoc/>
    public void Clear()
    {
        lock (_syncRoot)
        {
            if (_innerList.Count == 0)
                return;
            _innerList.Clear();
            RequestSave();
        }
    }

    ///<inheritdoc/>
    public bool Contains(TValue item)
    {
        lock (_syncRoot)
            return _innerList.Contains(item);
    }

    ///<inheritdoc/>
    public bool Contains(object? value)
    {
        lock (_syncRoot)
            return ((IList)_innerList).Contains(value);
    }

    ///<inheritdoc/>
    public void CopyTo(TValue[] array, int arrayIndex)
    {
        lock (_syncRoot)
            _innerList.CopyTo(array, arrayIndex);
    }

    ///<inheritdoc/>
    public void CopyTo(Array array, int index)
    {
        lock (_syncRoot)
            ((ICollection)_innerList).CopyTo(array, index);
    }

    ///<inheritdoc/>
    public IEnumerator<TValue> GetEnumerator()
    {
        lock (_syncRoot)
            return ((IEnumerable<TValue>)_innerList.ToArray()).GetEnumerator();
    }

    ///<inheritdoc/>
    public int IndexOf(TValue item)
    {
        lock (_syncRoot)
            return _innerList.IndexOf(item);
    }

    ///<inheritdoc/>
    public int IndexOf(object? value)
    {
        lock (_syncRoot)
            return ((IList)_innerList).IndexOf(value);
    }

    ///<inheritdoc/>
    public void Insert(int index, TValue item)
    {
        lock (_syncRoot)
        {
            _innerList.Insert(index, item);
            RequestSave();
        }
    }

    ///<inheritdoc/>
    public void Insert(int index, object? value)
    {
        lock (_syncRoot)
        {
            ((IList)_innerList).Insert(index, value);
            RequestSave();
        }
    }

    ///<inheritdoc/>
    public bool Remove(TValue item)
    {
        lock (_syncRoot)
        {
            var result = _innerList.Remove(item);
            if (result)
                RequestSave();
            return result;
        }
    }

    ///<inheritdoc/>
    public void Remove(object? value)
    {
        lock (_syncRoot)
        {
            var count = _innerList.Count;
            ((IList)_innerList).Remove(value);
            if (_innerList.Count != count)
                RequestSave();
        }
    }

    ///<inheritdoc/>
    public void RemoveAt(int index)
    {
        lock (_syncRoot)
        {
            _innerList.RemoveAt(index);
            RequestSave();
        }
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        lock (_syncRoot)
            return _innerList.ToArray().GetEnumerator();
    }

    private void RequestSave() => _currentProfile?.InstanceRequestSaveProfile();
}