perf: ListenerList

This commit is contained in:
cneicy committed 2026-03-08 16:57:30 +08:00
1 parent 98acdda3b2
commit f64289406f
3 files changed
+68 -45

No files matched your search

+1 -1
View File
@@ -10,7 +10,7 @@ namespace ShrinkEventBus
public static class EventBus
{
#if UNITY_EDITOR
public static bool EnableDebugRecord { get; set; } = true;
public static bool EnableDebugRecord { get; set; }
public static event Action<EventBase, string, string> OnEventTriggeredForEditor;
#endif
+66 -43
View File
@@ -1,5 +1,6 @@
#nullable enable
using System;
using System.Collections.Generic;
using System.Reflection;
namespace ShrinkEventBus
@@ -7,90 +8,112 @@ namespace ShrinkEventBus
public class ListenerList
{
private readonly object _lock = new();
private EventHandlerInfo[] _handlers = Array.Empty<EventHandlerInfo>();
private readonly List<EventHandlerInfo> _list = new();
private EventHandlerInfo[] _snapshot = Array.Empty<EventHandlerInfo>();
private bool _dirty;
public void Add(Delegate handler, EventPriority priority, int numericPriority,
bool receiveCanceled, string debugInfo = "", MethodInfo? originalMethod = null)
{
var newInfo = new EventHandlerInfo(handler, priority, numericPriority,
receiveCanceled, debugInfo, originalMethod);
lock (_lock)
{
var newInfo = new EventHandlerInfo(handler, priority, numericPriority,
receiveCanceled, debugInfo, originalMethod);
var newArray = new EventHandlerInfo[_handlers.Length + 1];
Array.Copy(_handlers, newArray, _handlers.Length);
newArray[^1] = newInfo;
Array.Sort(newArray, CompareHandlers);
_handlers = newArray;
var index = BinarySearchInsertIndex(priority, numericPriority);
_list.Insert(index, newInfo);
_dirty = true;
}
}
public bool Remove(Delegate handler)
{
lock (_lock)
{
var index = -1;
for (var i = 0; i < _handlers.Length; i++)
for (var i = 0; i < _list.Count; i++)
{
if (_handlers[i].Handler.Equals(handler))
if (_list[i].Handler.Equals(handler))
{
index = i;
break;
_list.RemoveAt(i);
_dirty = true;
return true;
}
}
if (index == -1) return false;
var newArray = new EventHandlerInfo[_handlers.Length - 1];
if (index > 0) Array.Copy(_handlers, 0, newArray, 0, index);
if (index < _handlers.Length - 1)
Array.Copy(_handlers, index + 1, newArray, index, _handlers.Length - index - 1);
_handlers = newArray;
return true;
return false;
}
}
public void RemoveTarget(object target)
{
lock (_lock)
{
var removeCount = 0;
for (var i = 0; i < _handlers.Length; i++)
var removed = false;
for (var i = _list.Count - 1; i >= 0; i--)
{
if (_handlers[i].Target == target) removeCount++;
}
if (removeCount == 0) return;
var newArray = new EventHandlerInfo[_handlers.Length - removeCount];
var dst = 0;
for (var i = 0; i < _handlers.Length; i++)
{
if (_handlers[i].Target != target)
if (_list[i].Target == target)
{
newArray[dst++] = _handlers[i];
_list.RemoveAt(i);
removed = true;
}
}
_handlers = newArray;
if (removed) _dirty = true;
}
}
public EventHandlerInfo[] GetHandlers() => _handlers;
public EventHandlerInfo[] GetHandlers()
{
lock (_lock)
{
if (_dirty)
{
_snapshot = _list.ToArray();
_dirty = false;
}
return _snapshot;
}
}
public int Count => _handlers.Length;
public int Count
{
get { lock (_lock) return _list.Count; }
}
public void Clear()
{
lock (_lock)
{
_handlers = Array.Empty<EventHandlerInfo>();
_list.Clear();
_snapshot = Array.Empty<EventHandlerInfo>();
_dirty = false;
}
}
private static int CompareHandlers(EventHandlerInfo a, EventHandlerInfo b)
private int BinarySearchInsertIndex(EventPriority priority, int numericPriority)
{
var priorityCompare = a.Priority.CompareTo(b.Priority);
return priorityCompare != 0 ? priorityCompare : b.NumericPriority.CompareTo(a.NumericPriority);
var lo = 0;
var hi = _list.Count;
while (lo < hi)
{
var mid = (lo + hi) >> 1;
var existing = _list[mid];
var cmp = existing.Priority.CompareTo(priority);
if (cmp == 0)
cmp = numericPriority.CompareTo(existing.NumericPriority); // 降序
if (cmp < 0)
lo = mid + 1;
else
hi = mid;
}
return lo;
}
}
}
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "com.cneicy.shrink-eventbus",
"version": "1.0.0",
"version": "1.1.0",
"displayName": "ShrinkEventBus",
"description": "高性能、类型安全的 Unity 事件总线,支持优先级调度与自动注册。",
"unity": "2022.3",