using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using Unity.IL2CPP.CompilerServices; using UnityEngine; namespace AlicizaX { [Il2CppSetOption(Option.NullChecks, false)] [Il2CppSetOption(Option.DivideByZeroChecks, false)] [Il2CppSetOption(Option.ArrayBoundsChecks, false)] public static class EventContainer where TPayload : struct, IEventArgs { private static readonly int InitialSize = EventInitialSize.Size; private static readonly int TypeId; // 优化3: SoA布局,提升缓存命中率 private static Action[] _callbacks; private static int[] _versions; private static int[] _activeSlots; private static int[] _freeSlots; private static int _freeCount; private static int[] _activeIndices; private static int _activeCount; private static int _version; #if Event_StrictCheck private static System.Collections.Generic.HashSet> _activeHandlers; #endif static EventContainer() { TypeId = UnsubscribeRegistry.Register(Unsubscribe); _callbacks = new Action[InitialSize]; _versions = new int[InitialSize]; _activeSlots = new int[InitialSize]; _freeSlots = new int[InitialSize]; _activeIndices = new int[InitialSize]; _freeCount = InitialSize; for (int i = 0; i < InitialSize; i++) { _freeSlots[i] = i; } #if Event_StrictCheck _activeHandlers = new System.Collections.Generic.HashSet>(); #endif } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static EventRuntimeHandle Subscribe(Action callback) { #if Event_StrictCheck if (_activeHandlers.Contains(callback)) { UnityEngine.Debug.LogWarning($"重复订阅事件处理程序: {callback.Method.Name}"); return default; } _activeHandlers.Add(callback); #endif int handlerIndex = GetFreeSlot(); // 优化4: 提前扩容检查 if (_activeCount >= _activeIndices.Length) { Array.Resize(ref _activeIndices, _activeIndices.Length << 1); } int activeIndex = _activeCount++; _activeIndices[activeIndex] = handlerIndex; int version = ++_version; _callbacks[handlerIndex] = callback; _versions[handlerIndex] = version; _activeSlots[handlerIndex] = activeIndex; return new EventRuntimeHandle(TypeId, handlerIndex, version); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static int GetFreeSlot() { if (_freeCount > 0) { return _freeSlots[--_freeCount]; } int oldLen = _callbacks.Length; int newSize = oldLen == 0 ? 64 : oldLen << 1; // 批量扩容 Array.Resize(ref _callbacks, newSize); Array.Resize(ref _versions, newSize); Array.Resize(ref _activeSlots, newSize); Array.Resize(ref _freeSlots, newSize); // 逆序添加,保持小索引优先(缓存友好) for (int i = newSize - 1; i >= oldLen; i--) { _freeSlots[_freeCount++] = i; } return _freeSlots[--_freeCount]; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void Unsubscribe(int handlerIndex, int version) { // 优化5: 提前版本检查 if (_versions[handlerIndex] != version) return; int lastActiveIndex = --_activeCount; int lastHandlerIndex = _activeIndices[lastActiveIndex]; int currentActiveIndex = _activeSlots[handlerIndex]; // Swap-remove _activeIndices[currentActiveIndex] = lastHandlerIndex; _activeSlots[lastHandlerIndex] = currentActiveIndex; #if Event_StrictCheck _activeHandlers.Remove(_callbacks[handlerIndex]); #endif _callbacks[handlerIndex] = null; _versions[handlerIndex] = 0; if (_freeCount >= _freeSlots.Length) { Array.Resize(ref _freeSlots, _freeSlots.Length << 1); } _freeSlots[_freeCount++] = handlerIndex; } // 优化6: 改进Publish,减少数组访问和分支 [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Publish(in TPayload payload) { int count = _activeCount; if (count == 0) return; // 快速路径 int[] indices = _activeIndices; Action[] callbacks = _callbacks; // 优化7: 更高效的循环展开 int i = 0; int unrolled = count & ~3; // count - (count % 4) // 4路展开主循环 for (; i < unrolled; i += 4) { int idx0 = indices[i]; int idx1 = indices[i + 1]; int idx2 = indices[i + 2]; int idx3 = indices[i + 3]; callbacks[idx0](payload); callbacks[idx1](payload); callbacks[idx2](payload); callbacks[idx3](payload); } // 优化8: 使用Duff's Device处理剩余 switch (count - i) { case 3: callbacks[indices[i + 2]](payload); goto case 2; case 2: callbacks[indices[i + 1]](payload); goto case 1; case 1: callbacks[indices[i]](payload); break; } } // 额外优化方法 public static int SubscriberCount { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => _activeCount; } // 预热容量,避免运行时扩容 public static void EnsureCapacity(int capacity) { if (_callbacks.Length >= capacity) return; int oldLen = _callbacks.Length; Array.Resize(ref _callbacks, capacity); Array.Resize(ref _versions, capacity); Array.Resize(ref _activeSlots, capacity); Array.Resize(ref _freeSlots, capacity); Array.Resize(ref _activeIndices, capacity); for (int i = capacity - 1; i >= oldLen; i--) { _freeSlots[_freeCount++] = i; } } // 清空所有订阅 public static void Clear() { for (int i = 0; i < _activeCount; i++) { int idx = _activeIndices[i]; _callbacks[idx] = null; _versions[idx] = 0; _freeSlots[_freeCount++] = idx; } _activeCount = 0; #if Event_StrictCheck _activeHandlers.Clear(); #endif } } }