Last active
August 30, 2023 14:21
-
-
Save bfollington/39aa48eb09dc904c7636a6c676b98a1c to your computer and use it in GitHub Desktop.
EventManager messaging layer designed for Unity
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.ComponentModel.Design; | |
using System; | |
using System.Collections; | |
using System.Collections.Generic; | |
using UnityEngine; | |
using UnityEngine.Events; | |
using System.Linq; | |
namespace Events | |
{ | |
public class Disposer<T> : IDisposable | |
{ | |
private EventManager _eventManager; | |
private Action<T> _listener; | |
public Disposer(EventManager em, Action<T> listener) { | |
_eventManager = em; | |
_listener = listener; | |
} | |
public void Dispose() | |
{ | |
_eventManager.RemoveListener<T>(_listener); | |
} | |
} | |
public class EventManager | |
{ | |
private ServiceContainer _serviceContainer; | |
private IList<Action> _pendingActions; | |
private int _isDispatching = 0; | |
public EventManager() { | |
_serviceContainer = new ServiceContainer(); | |
_pendingActions = new List<Action>(); | |
} | |
private IList<Action<T>> GetListenerList<T>() { | |
return _serviceContainer.GetService(typeof(IList<Action<T>>)) as IList<Action<T>>; | |
} | |
public Disposer<T> AddListener<T>(Action<T> action) { | |
var disposer = new Disposer<T>(this, action); | |
var listenerList = GetListenerList<T>(); | |
if (listenerList == null) { | |
_serviceContainer.AddService(typeof(IList<Action<T>>), new List<Action<T>>()); | |
listenerList = GetListenerList<T>(); | |
} | |
if (_isDispatching > 0) { | |
_pendingActions.Add(() => listenerList.Add(action)); | |
} else { | |
listenerList.Add(action); | |
} | |
return disposer; | |
} | |
public void RemoveListener<T>(Action<T> action) { | |
var listenerList = GetListenerList<T>(); | |
if (listenerList != null) { | |
if (_isDispatching > 0) { | |
_pendingActions.Add(() => listenerList.Remove(action)); | |
} else { | |
listenerList.Remove(action); | |
} | |
} | |
} | |
private void RunPendingActions() { | |
foreach (var action in _pendingActions) { | |
action.Invoke(); | |
} | |
_pendingActions.Clear(); | |
} | |
public bool Dispatch<T>() { | |
return Dispatch<T>(default(T)); | |
} | |
public bool Dispatch<T>(T eventData) { | |
var listenerList = GetListenerList<T>(); | |
if (eventData != null) { | |
Debug.Log($"{eventData.GetType().ToString()}: {eventData.ToString()}"); | |
} else { | |
Debug.Log($"{typeof(T).Name}"); | |
} | |
if (_isDispatching == 0) { | |
RunPendingActions(); | |
} | |
if (listenerList != null && listenerList.Count > 0) { | |
_isDispatching++; | |
foreach (var listener in listenerList) | |
{ | |
listener.Invoke(eventData); | |
} | |
_isDispatching--; | |
return true; | |
} | |
return false; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment