Skip to content

Instantly share code, notes, and snippets.

@simonwittber
Last active July 31, 2018 08:56
Show Gist options
  • Save simonwittber/4c29b304665fc5ec28aa1604d3a9028e to your computer and use it in GitHub Desktop.
Save simonwittber/4c29b304665fc5ec28aa1604d3a9028e to your computer and use it in GitHub Desktop.
A pub-sub system used for coordinating loosely coupled systems.
/// <summary>
/// This is a pubsub system used for coordinating loosely coupled systems.
/// It does some tricks with an internal class to improve the appearance
/// of the public API.
/// </summary>
public static class GameEvent
{
/* Public API */
public static void Publish<T>(T ev) => _InternalGameEvent<T>.Publish(ev);
public static void Subscribe<T>(System.Action<T> ev) => _InternalGameEvent<T>.Subscribe(ev);
public static void Unsubscribe<T>(System.Action<T> ev) => _InternalGameEvent<T>.Unsubscribe(ev);
public static void Clear<T>() => _InternalGameEvent<T>.Clear();
/* Internal API */
private static class _InternalGameEvent<T>
{
static List<System.Action<T>> subscribers = new List<System.Action<T>>();
internal static void Publish(T ev)
{
for (int i = 0, count = subscribers.Count; i < count; i++)
subscribers[i](ev);
}
internal static void Subscribe(System.Action<T> evListener) => subscribers.Add(evListener);
internal static void Unsubscribe(System.Action<T> evListener)
{
var idx = subscribers.IndexOf(evListener);
subscribers[idx] = subscribers[subscribers.Count - 1];
subscribers.RemoveAt(subscribers.Count - 1);
}
internal static void Clear() => subscribers.Clear();
}
}
/* Example Usage to avoid allocation:
/// <summary>
/// This class produces TouchGesture events.
/// </summary>
class TouchRecognizer {
public struct TouchGesture {
public Touch touch;
}
public void OnEventIsReady() {
GameEvent.Publish(new TouchGesture() { touch = Input.GetTouch(0) });
}
}
/// <summary>
/// This class consumes TouchGesture events.
/// </summary>
class TouchReceiver {
System.Action<TouchRecognizer.TouchGesture> onTouchGesture;
void OnEnable()
{
if(onTouchGesture == null)
onTouchGesture = HandleOnTouchGesture;
GameEvent.Subscribe<TouchRecognizer.TouchGesture>(onTouchGesture);
}
void OnDisable()
{
GameEvent.Unsubscribe<TouchRecognizer.TouchGesture>(onTouchGesture);
}
void HandleOnTouchGesture(TouchRecognizer.TouchGesture gesture) {
}
}
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment