89 lines
2.5 KiB
C#
89 lines
2.5 KiB
C#
using System.Collections.Generic;
|
|
using System;
|
|
using UnityEngine;
|
|
|
|
public static class EventBus
|
|
{
|
|
|
|
private static readonly Dictionary<Type, object> _eventHandlers = new Dictionary<Type, object>();
|
|
private static readonly object _lock = new object();
|
|
|
|
public static void Register<TEvent>(IEventHandler<TEvent> handler) where TEvent : IEvent
|
|
{
|
|
lock (_lock)
|
|
{
|
|
Type eventType = typeof(TEvent);
|
|
if (!_eventHandlers.ContainsKey(eventType))
|
|
{
|
|
_eventHandlers[eventType] = new List<IEventHandler<TEvent>>();
|
|
}
|
|
|
|
var handlers = _eventHandlers[eventType] as List<IEventHandler<TEvent>>;
|
|
if (handler != null && !handlers.Contains(handler))
|
|
{
|
|
handlers.Add(handler);
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void Unregister<TEvent>(IEventHandler<TEvent> handler) where TEvent : IEvent
|
|
{
|
|
lock (_lock)
|
|
{
|
|
Type eventType = typeof(TEvent);
|
|
if (_eventHandlers.ContainsKey(eventType))
|
|
{
|
|
var handlers = _eventHandlers[eventType] as List<IEventHandler<TEvent>>;
|
|
handlers?.Remove(handler);
|
|
|
|
if (handlers != null && handlers.Count == 0)
|
|
{
|
|
_eventHandlers.Remove(eventType);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void Publish<TEvent>(TEvent eventData) where TEvent : IEvent
|
|
{
|
|
List<IEventHandler<TEvent>> handlersToInvoke = null;
|
|
|
|
lock (_lock)
|
|
{
|
|
Type eventType = typeof(TEvent);
|
|
if (_eventHandlers.ContainsKey(eventType))
|
|
{
|
|
var handlers = _eventHandlers[eventType] as List<IEventHandler<TEvent>>;
|
|
if (handlers != null && handlers.Count > 0)
|
|
{
|
|
handlersToInvoke = new List<IEventHandler<TEvent>>(handlers);
|
|
}
|
|
}
|
|
}
|
|
|
|
// 在锁外执行事件处理,避免死锁
|
|
if (handlersToInvoke != null)
|
|
{
|
|
foreach (var handler in handlersToInvoke)
|
|
{
|
|
try
|
|
{
|
|
handler?.HandleEvent(eventData);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Debug.LogError($"Event handling error in {handler.GetType().Name}: {e}");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void Clear()
|
|
{
|
|
lock (_lock)
|
|
{
|
|
_eventHandlers.Clear();
|
|
}
|
|
}
|
|
}
|