using System; using System.Collections.Generic; namespace VRC.SDK3.ClientSim { /// /// The Event Dispatcher is how ClientSim implements the Observer Pattern. /// Systems can subscribe to specific event types, and other systems can then send the event. /// public class ClientSimEventDispatcher : IClientSimEventDispatcher, IDisposable { private readonly Dictionary _eventSubscribers; public ClientSimEventDispatcher() { _eventSubscribers = new Dictionary(); } public void Subscribe(Action eventHandler) where T : IClientSimEvent { Type t = typeof(T); if (_eventSubscribers.TryGetValue(t, out Delegate eventDelegate)) { _eventSubscribers[t] = Delegate.Combine(eventDelegate, eventHandler); } else { _eventSubscribers.Add(t, eventHandler); } } public void Unsubscribe(Action eventHandler) where T : IClientSimEvent { Type t = typeof(T); if (_eventSubscribers.TryGetValue(t, out Delegate eventDelegate)) { Delegate remainingDelegate = Delegate.Remove(eventDelegate, eventHandler); if (remainingDelegate == null) { _eventSubscribers.Remove(t); } else { _eventSubscribers[t] = remainingDelegate; } } } /// /// Sends the event to subscribed receivers /// /// /// public void SendEvent(T clientSimEvent) where T : IClientSimEvent { // TODO log warning if trying to send events while another is still being processed. if (_eventSubscribers.TryGetValue(typeof(T), out Delegate eventDelegate) && eventDelegate is Action action) { action.Invoke(clientSimEvent); } } public void Dispose() { _eventSubscribers.Clear(); } } }