Browse Source

Add a simple event dispatcher with static accessors.

master
fjruizpo 8 years ago
parent
commit
a65aff09da
  1. 174
      Assets/Fungus/Scripts/EventHandlers/EventDispatcher.cs
  2. 12
      Assets/Fungus/Scripts/EventHandlers/EventDispatcher.cs.meta

174
Assets/Fungus/Scripts/EventHandlers/EventDispatcher.cs

@ -0,0 +1,174 @@
using System.Collections.Generic;
using System;
namespace Fungus
{
public class EventDispatcher
{
public delegate void TypedDelegate<T>(T e) where T : class;
#region Statics
static EventDispatcher _instance;
public static EventDispatcher Instance
{
get
{
if(_instance == null)
{
_instance = new EventDispatcher();
}
return _instance;
}
}
public static void AddLog(Action<string> log)
{
Instance.addLog(log);
}
public static void RemoveLog(Action<string> log)
{
Instance.removeLog(log);
}
public static void AddListener<T>(TypedDelegate<T> listener) where T : class
{
Instance.addListener(listener);
}
public static void RemoveListener<T>(TypedDelegate<T> listener) where T : class
{
Instance.removeListener(listener);
}
public static void Raise<T>(T evt) where T : class
{
Instance.raise(evt);
}
public static void Raise<T>() where T : class, new()
{
Instance.raise<T>(new T());
}
public static void UnregisterAll()
{
Instance.unregisterAll();
}
#endregion
#region Private Members
readonly Dictionary<Type, List<Delegate>> _delegates;
event Action<string> _onLog;
#endregion
#region Private Functions
private EventDispatcher()
{
_delegates = new Dictionary<Type, List<Delegate>>();
}
/// <summary>
/// Gets the delegate list copy.
/// </summary>
/// <remarks>
/// As listener can modify the list while iterating it, it is better to iterate a copy of the delegates list instead of a reference.
/// </remarks>
/// <returns>A copy of the delegates list if found. Null if the dictionary does not contain a delegate list for this event.</returns>
/// <param name="evt">Event instance.</param>
/// <typeparam name="T">Type of the received event.</typeparam>
List<Delegate> getDelegateListCopy<T>(T evt)
{
var type = typeof(T);
return _delegates.ContainsKey(type) ? new List<Delegate>(_delegates[type]) : null;
}
void log(string message)
{
if(_onLog != null)
{
_onLog(message);
}
}
#endregion
#region Public Functions
public void addLog(Action<string> log)
{
_onLog += log;
}
public void removeLog(Action<string> log)
{
_onLog -= log;
}
public void addListener<T>(TypedDelegate<T> listener) where T : class
{
var type = typeof(T);
if(!_delegates.ContainsKey(type))
{
_delegates.Add(type, new List<Delegate>());
}
var list = _delegates[type];
if(!list.Contains(listener))
{
list.Add(listener);
}
}
public void removeListener<T>(TypedDelegate<T> listener) where T : class
{
var type = typeof(T);
if(_delegates.ContainsKey(type))
{
_delegates[type].Remove(listener);
return;
}
}
public void raise<T>(T evt) where T : class
{
if(evt == null)
{
log("Raised a null event");
return;
}
var list = getDelegateListCopy(evt);
if(list == null || list.Count < 1)
{
log("Raised an event with no listeners");
return;
}
for(int i = 0; i < list.Count; ++i)
{
var callback = list[i] as TypedDelegate<T>;
if(callback != null)
{
try
{
callback(evt);
}
catch(Exception gotcha)
{
log(gotcha.Message);
}
}
}
}
public void raise<T>() where T : class, new()
{
raise<T>(new T());
}
public void unregisterAll()
{
_delegates.Clear();
}
#endregion
}
}

12
Assets/Fungus/Scripts/EventHandlers/EventDispatcher.cs.meta

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: d6bacc8888852c94bab5c3b36cdf1574
timeCreated: 1483696929
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
Loading…
Cancel
Save