Files
TuanTuan-Engine/Assets/GameFramework/Runtime/EventSystem/EventBus.cs
2025-11-12 07:04:31 +08:00

91 lines
2.8 KiB
C#

using System.Collections.Generic;
using System;
using UnityEngine;
namespace Tuan.GameFramework
{
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();
}
}
}
}