Files

55 lines
2.1 KiB
C#
Raw Permalink Normal View History

using System;
using System.Collections.Generic;
// Шина событий: модуль сообщает "что случилось", не зная, кто это слушает.
//
// EventBus.Publish(new MarchReturnedEvent { ... }); // модуль Мира
// EventBus.Subscribe<MarchReturnedEvent>(OnMarchReturned); // задания, статистика, UI
//
// Подписчик обязан отписаться (OnDestroy / OnDisable), иначе получит событие уже уничтоженным.
public static class EventBus
{
private static readonly Dictionary<Type, Delegate> handlers = new Dictionary<Type, Delegate>();
// Ошибка в одном подписчике не должна ломать остальных. Ядро не знает про Unity,
// поэтому куда писать ошибку, задаёт Core.Unity (там это Debug.LogException).
public static Action<Exception> OnHandlerError;
public static void Subscribe<T>(Action<T> handler)
{
handlers.TryGetValue(typeof(T), out Delegate existing);
handlers[typeof(T)] = Delegate.Combine(existing, handler);
}
public static void Unsubscribe<T>(Action<T> handler)
{
if (!handlers.TryGetValue(typeof(T), out Delegate existing)) return;
Delegate remaining = Delegate.Remove(existing, handler);
if (remaining == null) handlers.Remove(typeof(T));
else handlers[typeof(T)] = remaining;
}
public static void Publish<T>(T gameEvent)
{
if (!handlers.TryGetValue(typeof(T), out Delegate existing)) return;
// Копия списка: подписчик может отписаться прямо во время рассылки
foreach (Delegate d in existing.GetInvocationList())
{
try
{
((Action<T>)d)(gameEvent);
}
catch (Exception e)
{
OnHandlerError?.Invoke(e);
}
}
}
public static void Clear()
{
handlers.Clear();
}
}