Created
January 30, 2017 20:56
-
-
Save DanPuzey/f41d87a2137af12098055dc64caefdfd to your computer and use it in GitHub Desktop.
Unity3d/C# EventAggregator (Unity v5.5+)
This file contains 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; | |
using System.Linq; | |
using Diagnostics; | |
using System.Collections.Generic; | |
using UnityEngine; | |
using UnityEngine.SceneManagement; | |
namespace Events | |
{ | |
public static class EventAggregator | |
{ | |
#region Scene-load autoflush | |
static EventAggregator() | |
{ | |
SceneManager.sceneLoaded += SceneLoaded; | |
} | |
private static void SceneLoaded(Scene arg0, LoadSceneMode arg1) | |
{ | |
FlushStaleListeners(); | |
} | |
#endregion | |
private class WeakListener | |
{ | |
public WeakListener(UnityEngine.Object listener, object handler) | |
{ | |
Listener = new WeakReference(listener); | |
Handler = handler; | |
} | |
public readonly WeakReference Listener; | |
public readonly object Handler; | |
public bool IsAlive | |
{ | |
get | |
{ | |
return Listener.IsAlive && (Listener.Target as UnityEngine.Object) != null; | |
} | |
} | |
} | |
private static Dictionary<string, List<WeakListener>> _listeners = new Dictionary<string, List<WeakListener>>(128); | |
public static void ClearAllListeners() | |
{ | |
_listeners.Clear(); | |
} | |
public static void FlushStaleListeners() | |
{ | |
foreach (var eventName in _listeners.Keys.ToArray()) | |
{ | |
var eventListeners = _listeners[eventName]; | |
eventListeners.RemoveAll(l => !l.IsAlive); | |
if (eventListeners.Count == 0) | |
{ | |
_listeners.Remove(eventName); | |
} | |
} | |
} | |
public static void Emit(string eventName) | |
{ | |
var listeners = GetLiveListeners(eventName); | |
if (listeners != null) | |
{ | |
foreach (var l in listeners) | |
{ | |
CallListener(l); | |
} | |
} | |
} | |
public static void Emit<T>(string eventName, T param0) | |
{ | |
var listeners = GetLiveListeners(eventName); | |
if (listeners != null) | |
{ | |
foreach (var l in listeners) | |
{ | |
CallListener(l, param0); | |
} | |
} | |
} | |
public static void Emit<T, U>(string eventName, T param0, U param1) | |
{ | |
var listeners = GetLiveListeners(eventName); | |
if (listeners != null) | |
{ | |
foreach (var l in listeners) | |
{ | |
CallListener(l, param0, param1); | |
} | |
} | |
} | |
#region Handler callers with fallback for overloads with less parameters | |
private static void CallListener<T, U>(WeakListener listener, T param0, U param1) | |
{ | |
var action = listener.Handler as Action<T, U>; | |
if (action != null) | |
{ | |
action(param0, param1); | |
} | |
else | |
{ | |
CallListener(listener, param0); | |
} | |
} | |
private static void CallListener<T>(WeakListener listener, T param0) | |
{ | |
var action = listener.Handler as Action<T>; | |
if (action != null) | |
{ | |
action(param0); | |
} | |
else | |
{ | |
CallListener(listener); | |
} | |
} | |
private static void CallListener(WeakListener listener) | |
{ | |
var action = listener.Handler as Action; | |
if (action != null) | |
{ | |
action(); | |
} | |
else | |
{ | |
Log.WarningFormat("Handler for event was of unexpected type. Listener is '{0}'", listener.Listener.Target); | |
} | |
} | |
#endregion | |
private static List<WeakListener> GetLiveListeners(string eventName) | |
{ | |
if (!_listeners.ContainsKey(eventName)) return null; | |
var listeners = _listeners[eventName]; | |
for (var i = listeners.Count - 1; i >= 0; i--) | |
{ | |
if (!listeners[i].IsAlive) | |
{ | |
listeners.RemoveAt(i); | |
Debug.LogFormat("Removing index {0}", i); | |
} | |
} | |
return listeners; | |
} | |
public static void Listen(this UnityEngine.Object listener, string eventName, Action handler) | |
{ | |
AddListener(eventName, listener, handler); | |
} | |
public static void Listen<T>(this UnityEngine.Object listener, string eventName, Action<T> handler) | |
{ | |
AddListener(eventName, listener, handler); | |
} | |
public static void Listen<T, U>(this UnityEngine.Object listener, string eventName, Action<T, U> handler) | |
{ | |
AddListener(eventName, listener, handler); | |
} | |
private static void AddListener(string eventName, UnityEngine.Object listener, object handler) | |
{ | |
if (!_listeners.ContainsKey(eventName)) | |
{ | |
_listeners[eventName] = new List<WeakListener>(16); | |
}; | |
_listeners[eventName].Add(new WeakListener(listener, handler)); | |
} | |
public static void StopListening(this UnityEngine.Object listener, string eventName) | |
{ | |
if (_listeners.ContainsKey(eventName)) | |
{ | |
var listeners = _listeners[eventName]; | |
listeners.RemoveAll(l => l.IsAlive && object.ReferenceEquals(l.Listener.Target, listener)); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment