BITKit/Src/Core/Item/ItemContainer.cs

180 lines
5.4 KiB
C#

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.SqlServer.Server;
namespace BITKit
{
/// <summary>
/// 支持二进制化的的物品容器,适用于网络化物品容器
/// 支持属性
/// 支持回调
/// </summary>
public interface IRuntimeItemContainer:IBinarySerialize
{
public bool AllowAdd { get; set; }
public bool AllowRemove { get; set; }
public ValidHandle IsBusy { get; }
/// <summary>
/// 物品容器的唯一Id
/// </summary>
int Id { get; }
/// <summary>
/// 获取所有Item的只读副本
/// </summary>
IRuntimeItem[] GetItems();
/// <summary>
/// 添加物品的接口
/// </summary>
bool Add(IRuntimeItem item);
/// <summary>
/// 通过Id移除物品(推荐)
/// </summary>
bool Remove(int id);
/// <summary>
/// 设置物品
/// </summary>
/// <param name="id"></param>
void Set(IRuntimeItem id);
/// <summary>
/// 通过通过Id丢下物品
/// </summary>
bool Drop(int id);
/// <summary>
/// 注册添加物品的工厂方法,
/// </summary>
event Func<IRuntimeItem, bool> AddFactory;
/// <summary>
/// 注册移除物品的工厂方法
/// </summary>
event Func<IRuntimeItem, bool> RemoveFactory;
/// <summary>
/// 注册丢下物品的工厂方法
/// </summary>
event Func<IRuntimeItem, bool> DropFactory;
/// <summary>
/// 已添加Item的回调
/// </summary>
event Action<IRuntimeItem> OnAdd;
/// <summary>
/// 已移除Item的回调
/// </summary>
event Action<IRuntimeItem> OnRemove;
/// <summary>
/// 已设置Item的回调
/// </summary>
event Action<IRuntimeItem> OnSet;
/// <summary>
/// 已丢下Item的回调
/// </summary>
event Action<IRuntimeItem> OnDrop;
/// <summary>
/// 已重构Items的回调
/// </summary>
event Action<IRuntimeItemContainer> OnRebuild;
/// <summary>
/// 是否已完成物品交换,例如false就是开始交换物品true就是已完成交换物品,可以处理物品了
/// </summary>
event Action<bool> OnRelease;
}
public class RuntimeItemContainer : IRuntimeItemContainer
{
public RuntimeItemContainer()
{
IsBusy.AddListener(x=>OnRelease?.Invoke(!x));
}
public readonly ConcurrentDictionary<int, IRuntimeItem> 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 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<RuntimeItemContainer>($"添加了了:{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<RuntimeItemContainer>($"移除了:{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<RuntimeItemContainer>($"丢下了:{id}");
return true;
}
public event Func<IRuntimeItem, bool> AddFactory;
public event Func<IRuntimeItem, bool> RemoveFactory;
public event Func<IRuntimeItem, bool> DropFactory;
public event Action<IRuntimeItem> OnAdd;
public event Action<IRuntimeItem> OnRemove;
public event Action<IRuntimeItem> OnSet;
public event Action<IRuntimeItem> OnDrop;
public event Action<IRuntimeItemContainer> OnRebuild;
public event Action<bool> OnRelease;
}
}