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