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) { _isExecute = true; for (var i = 0; i < _handlerCount; i++) { _handlers[i](arg1); } 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; } } }