using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Linq; using Microsoft.SqlServer.Server; namespace BITKit { /// /// 支持二进制化的的物品容器,适用于网络化物品容器 /// 支持属性 /// 支持回调 /// public interface IRuntimeItemContainer:IBinarySerialize { public bool AllowAdd { get; set; } public bool AllowRemove { get; set; } public ValidHandle IsBusy { get; } /// /// 物品容器的唯一Id /// int Id { get; } /// /// 获取所有Item的只读副本 /// IRuntimeItem[] GetItems(); IReadOnlyDictionary ItemDictionary { get; } /// /// 添加物品的接口 /// bool Add(IRuntimeItem item); /// /// 通过Id移除物品(推荐) /// bool Remove(int id); /// /// 设置物品 /// /// void Set(IRuntimeItem id); /// /// 通过通过Id丢下物品 /// bool Drop(int id); /// /// 注册添加物品的工厂方法, /// event Func AddFactory; /// /// 注册移除物品的工厂方法 /// event Func RemoveFactory; /// /// 注册丢下物品的工厂方法 /// event Func DropFactory; /// /// 已添加Item的回调 /// event Action OnAdd; /// /// 已移除Item的回调 /// event Action OnRemove; /// /// 已设置Item的回调 /// event Action OnSet; /// /// 已丢下Item的回调 /// event Action OnDrop; /// /// 已重构Items的回调 /// event Action OnRebuild; /// /// 是否已完成物品交换,例如false就是开始交换物品true就是已完成交换物品,可以处理物品了 /// event Action OnRelease; } public class RuntimeItemContainer : IRuntimeItemContainer { public RuntimeItemContainer() { IsBusy.AddListener(x=>OnRelease?.Invoke(!x)); } public readonly ConcurrentDictionary Items = new(); public void Read(BinaryReader r) { throw new NotImplementedException(); } public void Write(BinaryWriter w) { throw new NotImplementedException(); } public bool AllowAdd { get; set; } public bool AllowRemove { get; set; } public ValidHandle IsBusy { get; } = new(); public int Id { get; set; } public IRuntimeItem[] GetItems()=>Items.Values.ToArray(); public IReadOnlyDictionary ItemDictionary => Items; public bool Add(IRuntimeItem item) { using var _ = IsBusy.GetHandle(); foreach (var func in AddFactory.CastAsFunc()) { if (func.Invoke(item) is false) { return false; } } Items.Set(item.Id, item); OnAdd?.Invoke(item); //BIT4Log.Log($"添加了了:{item.Id}"); return true; } public bool Remove(int id) { using var _ = IsBusy.GetHandle(); if (Items.TryGetValue(id, out var item) is false) return false; foreach (var func in RemoveFactory.CastAsFunc()) { if (func.Invoke(item) is false) { return false; } } Items.TryRemove(item.Id); OnRemove?.Invoke(item); //BIT4Log.Log($"移除了:{id}"); return true; } public void Set(IRuntimeItem id) { using var _ = IsBusy.GetHandle(); if (!Items.TryGetValue(id.Id, out var item)) return; item = id; OnSet?.Invoke(item); } public bool Drop(int id) { using var _ = IsBusy.GetHandle(); if (Items.TryGetValue(id, out var item) is false) return false; foreach (var func in DropFactory.CastAsFunc()) { if (func.Invoke(item) is false) { return false; } } Items.TryRemove(item.Id); OnDrop?.Invoke(item); //BIT4Log.Log($"丢下了:{id}"); return true; } public event Func AddFactory; public event Func RemoveFactory; public event Func DropFactory; public event Action OnAdd; public event Action OnRemove; public event Action OnSet; public event Action OnDrop; public event Action OnRebuild; public event Action OnRelease; } }