using System;
using System.Buffers;
using System.Runtime.CompilerServices;
using AlicizaX.Runtime;
namespace AlicizaX.EventKit.Runtime
{
///
/// 游戏事件数据类。
///
public struct EventInvokerData
{
private readonly string _eventType;
private Action[] _handlers;
private int _handlerCount;
private Action[] _addList;
private int _addCount;
private Action[] _deleteList;
private int _deleteCount;
private bool _isExecute;
private bool _dirty;
private bool _init;
// 使用对象池来管理委托数组
private static readonly ArrayPool> ActionArrayPool = ArrayPool>.Shared;
public bool IsEmpty => _handlerCount == 0 && !_init;
///
/// 构造函数。
///
/// 事件类型。
public EventInvokerData(string eventType)
{
_init = true;
_eventType = eventType;
_handlers = ActionArrayPool.Rent(16); // 预分配16个委托的空间
_handlerCount = 0;
_addList = ActionArrayPool.Rent(4); // 预分配4个
_addCount = 0;
_deleteList = ActionArrayPool.Rent(4); // 预分配4个
_deleteCount = 0;
_isExecute = false;
_dirty = false;
}
///
/// 添加注册委托。
///
/// 事件处理回调。
/// 是否添加回调成功。
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool AddHandler(Action handler)
{
if (Array.IndexOf(_handlers, handler, 0, _handlerCount) >= 0)
{
Log.Warning("Repeated Add Handler {0}",handler.Method.Name);
return false;
}
if (_isExecute)
{
EnsureCapacity(ref _addList, ref _addCount);
_addList[_addCount++] = handler;
_dirty = true;
}
else
{
EnsureCapacity(ref _handlers, ref _handlerCount);
_handlers[_handlerCount++] = handler;
}
return true;
}
///
/// 移除反注册委托。
///
/// 事件处理回调。
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void RemoveHandler(Action handler)
{
if (_isExecute)
{
EnsureCapacity(ref _deleteList, ref _deleteCount);
_deleteList[_deleteCount++] = handler;
_dirty = true;
}
else
{
int index = Array.IndexOf(_handlers, handler, 0, _handlerCount);
if (index >= 0)
{
_handlers[index] = _handlers[--_handlerCount];
_handlers[_handlerCount] = null; // 避免内存泄漏
}
else
{
Log.Warning("Delete handle failed, not exist, EventId: {0}", _eventType);
}
}
}
///
/// 确保数组容量足够,必要时扩容。
///
/// 数组引用。
/// 当前元素数量。
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void EnsureCapacity(ref Action[] array, ref int count)
{
if (count >= array.Length)
{
var newArray = ActionArrayPool.Rent(array.Length * 2);
Array.Copy(array, newArray, array.Length);
ActionArrayPool.Return(array, clearArray: true);
array = newArray;
}
}
///
/// 检测脏数据修正。
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void CheckModify()
{
_isExecute = false;
if (_dirty)
{
for (int i = 0; i < _addCount; i++)
{
EnsureCapacity(ref _handlers, ref _handlerCount);
_handlers[_handlerCount++] = _addList[i];
}
_addCount = 0;
for (int i = 0; i < _deleteCount; i++)
{
int index = Array.IndexOf(_handlers, _deleteList[i], 0, _handlerCount);
if (index >= 0)
{
_handlers[index] = _handlers[--_handlerCount];
_handlers[_handlerCount] = null;
}
}
_deleteCount = 0;
_dirty = false;
}
}
///
/// 带参数回调调用。
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Callback(TArgs1 arg1, TArgs2 args2, TArgs3 args3)
{
_isExecute = true;
for (var i = 0; i < _handlerCount; i++)
{
_handlers[i](arg1, args2, args3);
}
CheckModify();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Reset()
{
_init = false;
ActionArrayPool.Return(_handlers, true);
ActionArrayPool.Return(_addList, true);
ActionArrayPool.Return(_deleteList, true);
_handlerCount = 0;
_addCount = 0;
_deleteCount = 0;
_isExecute = false;
_dirty = false;
}
}
}