Last active
August 29, 2015 14:19
-
-
Save grahamboree/36a815a7aeba50a2c1f2 to your computer and use it in GitHub Desktop.
Unity Messenger
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.Collections.Generic; | |
using UnityEngine; | |
public enum EventType { | |
// Add events here. | |
testOne, | |
testTwo, | |
testThree | |
} | |
public enum MessengerMode { | |
DONT_REQUIRE_LISTENER, | |
REQUIRE_LISTENER, | |
DEFAULT = DONT_REQUIRE_LISTENER, | |
} | |
/// No parameters | |
public static class Messenger { | |
public static void AddListener(EventType eventName, Action handler) { | |
MessengerInternal.OnListenerAdding(eventName, handler); | |
MessengerInternal.eventTable[eventName] = (Action)MessengerInternal.eventTable[eventName] + handler; | |
} | |
public static void RemoveListener(EventType eventName, Action handler) { | |
MessengerInternal.OnListenerRemoving(eventName, handler); | |
MessengerInternal.eventTable[eventName] = (Action)MessengerInternal.eventTable[eventName] - handler; | |
MessengerInternal.OnListenerRemoved(eventName); | |
} | |
public static void Broadcast(EventType eventName, MessengerMode mode = MessengerMode.DEFAULT) { | |
MessengerInternal.OnBroadcasting(eventName, mode); | |
Delegate d; | |
if (MessengerInternal.eventTable.TryGetValue(eventName, out d)) { | |
Action callback = d as Action; | |
if (callback != null) { | |
callback(); | |
} else { | |
MessengerInternal.BroadcastSignatureError(eventName); | |
} | |
} | |
} | |
} | |
/// One parameter | |
public static class Messenger<T> { | |
public static void AddListener(EventType eventName, Action<T> handler) { | |
MessengerInternal.OnListenerAdding(eventName, handler); | |
MessengerInternal.eventTable[eventName] = (Action<T>)MessengerInternal.eventTable[eventName] + handler; | |
} | |
public static void RemoveListener(EventType eventName, Action<T> handler) { | |
MessengerInternal.OnListenerRemoving(eventName, handler); | |
MessengerInternal.eventTable[eventName] = (Action<T>)MessengerInternal.eventTable[eventName] - handler; | |
MessengerInternal.OnListenerRemoved(eventName); | |
} | |
public static void Broadcast(EventType eventName, T arg1, MessengerMode mode = MessengerMode.DEFAULT) { | |
MessengerInternal.OnBroadcasting(eventName, mode); | |
Delegate d; | |
if (MessengerInternal.eventTable.TryGetValue(eventName, out d)) { | |
Action<T> callback = d as Action<T>; | |
if (callback != null) { | |
callback(arg1); | |
} else { | |
MessengerInternal.BroadcastSignatureError(eventName); | |
} | |
} | |
} | |
} | |
/// Two parameters | |
public static class Messenger<T, U> { | |
public static void AddListener(EventType eventName, Action<T, U> handler) { | |
MessengerInternal.OnListenerAdding(eventName, handler); | |
MessengerInternal.eventTable[eventName] = (Action<T, U>)MessengerInternal.eventTable[eventName] + handler; | |
} | |
public static void RemoveListener(EventType eventName, Action<T, U> handler) { | |
MessengerInternal.OnListenerRemoving(eventName, handler); | |
MessengerInternal.eventTable[eventName] = (Action<T, U>)MessengerInternal.eventTable[eventName] - handler; | |
MessengerInternal.OnListenerRemoved(eventName); | |
} | |
public static void Broadcast(EventType eventName, T arg1, U arg2, MessengerMode mode = MessengerMode.DEFAULT) { | |
MessengerInternal.OnBroadcasting(eventName, mode); | |
Delegate d; | |
if (MessengerInternal.eventTable.TryGetValue(eventName, out d)) { | |
Action<T, U> callback = d as Action<T, U>; | |
if (callback != null) { | |
callback(arg1, arg2); | |
} else { | |
MessengerInternal.BroadcastSignatureError(eventName); | |
} | |
} | |
} | |
} | |
/// Three parameters | |
public static class Messenger<T, U, V> { | |
public static void AddListener(EventType eventName, Action<T, U, V> handler) { | |
MessengerInternal.OnListenerAdding(eventName, handler); | |
MessengerInternal.eventTable[eventName] = (Action<T, U, V>)MessengerInternal.eventTable[eventName] + handler; | |
} | |
public static void RemoveListener(EventType eventName, Action<T, U, V> handler) { | |
MessengerInternal.OnListenerRemoving(eventName, handler); | |
MessengerInternal.eventTable[eventName] = (Action<T, U, V>)MessengerInternal.eventTable[eventName] - handler; | |
MessengerInternal.OnListenerRemoved(eventName); | |
} | |
public static void Broadcast(EventType eventName, T arg1, U arg2, V arg3, MessengerMode mode = MessengerMode.DEFAULT) { | |
MessengerInternal.OnBroadcasting(eventName, mode); | |
Delegate d; | |
if (MessengerInternal.eventTable.TryGetValue(eventName, out d)) { | |
Action<T, U, V> callback = d as Action<T, U, V>; | |
if (callback != null) { | |
callback(arg1, arg2, arg3); | |
} else { | |
MessengerInternal.BroadcastSignatureError(eventName); | |
} | |
} | |
} | |
} | |
internal static class MessengerInternal { | |
/// Maps event names to delegate chains. | |
public static Dictionary<EventType, Delegate> eventTable = new Dictionary<EventType, Delegate>(); | |
#region Methods. | |
public static void OnListenerAdding(EventType eventName, Delegate callback) { | |
if (!eventTable.ContainsKey(eventName)) { | |
eventTable.Add(eventName, null); | |
} | |
Delegate d = eventTable[eventName]; | |
if (d != null && d.GetType() != callback.GetType()) { | |
Debug.LogError(string.Format("Attempting to add listener with inconsistent signature for event type {0}. " + | |
"Current listeners have type {1} and listener being added has type {2}", | |
eventName, | |
d.GetType().Name, | |
callback.GetType().Name)); | |
} | |
} | |
public static void OnListenerRemoving(EventType eventName, Delegate listenerBeingRemoved) { | |
if (eventTable.ContainsKey(eventName)) { | |
Delegate d = eventTable[eventName]; | |
if (d == null) { | |
Debug.LogError(string.Format( | |
"Attempting to remove listener with for event type {0} but current listener is null.", eventName)); | |
} | |
if (d.GetType() != listenerBeingRemoved.GetType()) { | |
Debug.LogError(string.Format("Attempting to remove listener with inconsistent signature for event " + | |
"type {0}. Current listeners have type {1} and listener being removed has type {2}", | |
eventName, | |
d.GetType().Name, | |
listenerBeingRemoved.GetType().Name)); | |
} | |
} else { | |
Debug.LogError(string.Format("Attempting to remove listener for type {0} but Messenger doesn't know " + | |
"about this event type.", eventName)); | |
} | |
} | |
public static void OnListenerRemoved(EventType eventName) { | |
if (eventTable[eventName] == null) { | |
eventTable.Remove(eventName); | |
} | |
} | |
public static void OnBroadcasting(EventType eventName, MessengerMode mode) { | |
if (mode == MessengerMode.REQUIRE_LISTENER && !eventTable.ContainsKey(eventName)) { | |
Debug.LogError(string.Format("Broadcasting message {0} but no listener found.", eventName)); | |
} | |
} | |
public static void BroadcastSignatureError(EventType eventName) { | |
Debug.LogError(string.Format( | |
"Broadcasting message {0} but listeners have a different signature than the broadcaster.", eventName)); | |
} | |
#endregion | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment