Skip to content

Instantly share code, notes, and snippets.

@DylanYasen
Created December 15, 2019 04:30
Show Gist options
  • Save DylanYasen/8227558e86a4b9ecc2c511c7592e7cf6 to your computer and use it in GitHub Desktop.
Save DylanYasen/8227558e86a4b9ecc2c511c7592e7cf6 to your computer and use it in GitHub Desktop.
TypeSafe/ThreadSafe Event Manager
using System;
using System.Collections.Concurrent;
using UnityEngine;
public class Event
{
public uint ID;
};
public delegate void EventDelegate<E>(E payload) where E : Event;
public struct EventListener
{
public System.Object Obj;
public System.Delegate EventHandler;
}
public class EventManager : MonoBehaviour
{
private ConcurrentDictionary<Type, ConcurrentBag<EventListener>> EventRegister = new ConcurrentDictionary<Type, ConcurrentBag<EventListener>>();
public void RegisterForEvent<T>(object obj, EventDelegate<T> eventHandler) where T : Event
{
ConcurrentBag<EventListener> listeners;
if (!EventRegister.TryGetValue(typeof(T), out listeners))
{
listeners = new ConcurrentBag<EventListener>();
if (!EventRegister.TryAdd(typeof(T), listeners))
{
// @todo: log
// Debug.LogError($"failed to register event {typeof(T).ToString()} {obj.ToString()}");
return;
}
}
listeners.Add(new EventListener
{
Obj = obj,
EventHandler = eventHandler
});
}
public void TriggerEvent<T>(T payload) where T : Event
{
ConcurrentBag<EventListener> listeners;
if (EventRegister.TryGetValue(typeof(T), out listeners))
{
foreach (var listener in listeners)
{
listener.EventHandler.DynamicInvoke(payload);
}
}
}
public void UnRegisterFromEvent<T>(object obj)
{
ConcurrentBag<EventListener> listeners;
if (EventRegister.TryGetValue(typeof(T), out listeners))
{
foreach (var listener in listeners)
{
if (listener.Obj == obj)
{
EventListener removedListener;
if (!listeners.TryTake(out removedListener))
{
// @todo: log
}
break;
}
}
}
}
public void DumpEvents()
{
System.Text.StringBuilder sb = new System.Text.StringBuilder();
foreach (var key in EventRegister.Keys)
{
ConcurrentBag<EventListener> listeners;
if (EventRegister.TryGetValue(key, out listeners))
{
sb.AppendLine($"{key.ToString()}:");
foreach (var listener in listeners)
{
sb.AppendLine($"\t [{listener.Obj?.ToString()}]:");
}
}
}
// @todo: logger
Debug.Log($"{sb.ToString()}");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment