perf: ListenerList
This commit is contained in:
3 files changed
+68
-45
No files matched your search
+1
-1
@@ -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
@@ -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
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "com.cneicy.shrink-eventbus",
|
||||
"version": "1.0.0",
|
||||
"version": "1.1.0",
|
||||
"displayName": "ShrinkEventBus",
|
||||
"description": "高性能、类型安全的 Unity 事件总线,支持优先级调度与自动注册。",
|
||||
"unity": "2022.3",
|
||||
|
||||
Reference in new issue
Block a user