Skip to content

Instantly share code, notes, and snippets.

@NikolajDL
Forked from DomGries/gist:3786466
Last active August 29, 2015 13:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save NikolajDL/10907556 to your computer and use it in GitHub Desktop.
Save NikolajDL/10907556 to your computer and use it in GitHub Desktop.
/**************************************************************************
*
* Original code from:
* https://gist.github.com/wmiller
*
* Updated by:
* https://gist.github.com/stfx
*
* Extended by:
* Me (https://gist.github.com/Excolo)
*
* Description:
* I've always used a game event management system based on the one
* described in Game Coding Complete (GCC) 3rd and 4th editions.
* This is my attempt to extend the functionality of the forked event
* manager by Will Miller, with functionality from GCC.
* What I've added, is support for a 'catch-all' listener, that is called
* on every event trigger. This can be used to e.g. log all events.
*
* I considered adding support for a event queue, where each event in the
* queue would be raised once an Update method is called.
* This was abandoned as I was unable to find a decent way to do it
* without using DynamicInvoke.
*
**************************************************************************/
using System;
using System.Collections.Generic;
public abstract class GameEvent
{
}
public sealed class EventManager
{
#region Singleton Impl
private static readonly EventManager _instance = new EventManager();
static EventManager()
{ }
private EventManager()
{ }
public static EventManager Instance
{
get
{
return _instance;
}
}
#endregion
public delegate void EventDelegate(GameEvent e);
public delegate void EventDelegate<T>(T e) where T : GameEvent;
private readonly Dictionary<Type, Delegate> _delegates = new Dictionary<Type, Delegate>();
private Delegate _catchAllDelegate;
public void AddListener<T>(EventDelegate<T> listener) where T : GameEvent
{
Delegate d;
if (_delegates.TryGetValue(typeof(T), out d))
{
_delegates[typeof(T)] = Delegate.Combine(d, listener);
}
else
{
_delegates[typeof(T)] = listener;
}
}
public void AddListener(EventDelegate listener)
{
_catchAllDelegate = Delegate.Combine(_catchAllDelegate, listener);
}
public void RemoveListener<T>(EventDelegate<T> listener) where T : GameEvent
{
Delegate d;
if (_delegates.TryGetValue(typeof(T), out d))
{
Delegate currentDel = Delegate.Remove(d, listener);
if (currentDel == null)
{
_delegates.Remove(typeof(T));
}
else
{
_delegates[typeof(T)] = currentDel;
}
}
}
public void RemoveListener(EventDelegate listener)
{
_catchAllDelegate = Delegate.Remove(_catchAllDelegate, listener);
}
public void RemoveListenersOf<T>() where T : GameEvent
{
if (_delegates.ContainsKey(typeof(T)))
{
_delegates.Remove(typeof(T));
}
}
public void Raise<T>(T e) where T : GameEvent
{
if (e == null)
{
throw new ArgumentNullException("e");
}
Delegate d;
if (_delegates.TryGetValue(typeof(T), out d))
{
EventDelegate<T> callback = d as EventDelegate<T>;
if (callback != null)
{
callback(e);
}
}
EventDelegate catchAllCallback = _catchAllDelegate as EventDelegate;
if (catchAllCallback != null)
{
catchAllCallback(e);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment