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