You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
150 lines
4.4 KiB
150 lines
4.4 KiB
// This code is part of the Fungus library (https://github.com/snozbot/fungus) |
|
// It is released for free under the MIT open source license (https://github.com/snozbot/fungus/blob/master/LICENSE) |
|
|
|
using UnityEngine; |
|
using System.Collections.Generic; |
|
using System; |
|
|
|
namespace Fungus |
|
{ |
|
/// <summary> |
|
/// A simple efficient event dispatcher with logging support. |
|
/// </summary> |
|
public class EventDispatcher : MonoBehaviour |
|
{ |
|
protected readonly Dictionary<Type, List<Delegate>> delegates = new Dictionary<Type, List<Delegate>>(); |
|
|
|
protected virtual event Action<string> onLog; |
|
|
|
/// <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> |
|
protected virtual List<Delegate> GetDelegateListCopy<T>(T evt) |
|
{ |
|
var type = typeof(T); |
|
return delegates.ContainsKey(type) ? new List<Delegate>(delegates[type]) : null; |
|
} |
|
|
|
protected virtual void Log(string message) |
|
{ |
|
if(onLog != null) |
|
{ |
|
onLog(message); |
|
} |
|
} |
|
|
|
#region Public members |
|
|
|
/// <summary> |
|
/// A typed delegate which contains information about the event. |
|
/// </summary> |
|
public delegate void TypedDelegate<T>(T e) where T : class; |
|
|
|
/// <summary> |
|
/// Adds a log callback action. |
|
/// </summary> |
|
public virtual void AddLog(Action<string> log) |
|
{ |
|
onLog += log; |
|
} |
|
|
|
/// <summary> |
|
/// Removes a log callback action. |
|
/// </summary> |
|
public virtual void RemoveLog(Action<string> log) |
|
{ |
|
onLog -= log; |
|
} |
|
|
|
/// <summary> |
|
/// Adds a listener for a specified event type. |
|
/// </summary> |
|
public virtual 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); |
|
} |
|
} |
|
|
|
/// <summary> |
|
/// Removes a listener for a specified event type. |
|
/// </summary> |
|
public virtual void RemoveListener<T>(TypedDelegate<T> listener) where T : class |
|
{ |
|
var type = typeof(T); |
|
if(delegates.ContainsKey(type)) |
|
{ |
|
delegates[type].Remove(listener); |
|
return; |
|
} |
|
} |
|
|
|
/// <summary> |
|
/// Raise an event of a specified type. |
|
/// </summary> |
|
public virtual 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); |
|
} |
|
} |
|
} |
|
} |
|
|
|
/// <summary> |
|
/// Raise an event of a specified type, creates an instance of the type automatically. |
|
/// </summary> |
|
public virtual void Raise<T>() where T : class, new() |
|
{ |
|
Raise<T>(new T()); |
|
} |
|
|
|
/// <summary> |
|
/// Unregisters all event listeners. |
|
/// </summary> |
|
public virtual void UnregisterAll() |
|
{ |
|
delegates.Clear(); |
|
} |
|
|
|
#endregion |
|
} |
|
} |