using GameCore.Events.Interfaces; namespace GameCore.Events; public class EventBus { private readonly Queue _eventQueue = new(); private readonly Dictionary>> _subscribers = new(); public void Subscribe(Action listener) where T : IEvent { var eventType = typeof(T); if (!_subscribers.ContainsKey(eventType)) _subscribers[eventType] = []; _subscribers[eventType].Add(e => listener((T)e)); } public void Unsubscribe(Action listener) where T : IEvent { var eventType = typeof(T); if (!_subscribers.TryGetValue(eventType, out var listeners)) return; listeners.RemoveAll(e => e.Equals((Action)(e1 => listener((T)e1)))); if (listeners.Count == 0) _subscribers.Remove(eventType); } public void Publish(IEvent gameEvent) { _eventQueue.Enqueue(gameEvent); } public void ProcessEvents() { while (_eventQueue.Count > 0) { var gameEvent = _eventQueue.Dequeue(); var eventType = gameEvent.GetType(); if (!_subscribers.TryGetValue(eventType, out var listeners)) continue; foreach (var listener in listeners) listener.Invoke(gameEvent); } } }