// This code is part of the Fungus library (http://fungusgames.com) maintained by Chris Gregan (http://twitter.com/gofungus). // 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 { /// /// A simple efficient event dispatcher with logging support. /// public class EventDispatcher : MonoBehaviour { protected readonly Dictionary> delegates = new Dictionary>(); protected virtual event Action onLog; /// /// Gets the delegate list copy. /// /// /// As listener can modify the list while iterating it, it is better to iterate a copy of the delegates list instead of a reference. /// /// A copy of the delegates list if found. Null if the dictionary does not contain a delegate list for this event. /// Event instance. /// Type of the received event. protected virtual List GetDelegateListCopy(T evt) { var type = typeof(T); return delegates.ContainsKey(type) ? new List(delegates[type]) : null; } protected virtual void Log(string message) { if(onLog != null) { onLog(message); } } #region Public members /// /// A typed delegate which contains information about the event. /// public delegate void TypedDelegate(T e) where T : class; /// /// Adds a log callback action. /// public virtual void AddLog(Action log) { onLog += log; } /// /// Removes a log callback action. /// public virtual void RemoveLog(Action log) { onLog -= log; } /// /// Adds a listener for a specified event type. /// public virtual void AddListener(TypedDelegate listener) where T : class { var type = typeof(T); if(!delegates.ContainsKey(type)) { delegates.Add(type, new List()); } var list = delegates[type]; if(!list.Contains(listener)) { list.Add(listener); } } /// /// Removes a listener for a specified event type. /// public virtual void RemoveListener(TypedDelegate listener) where T : class { var type = typeof(T); if(delegates.ContainsKey(type)) { delegates[type].Remove(listener); return; } } /// /// Raise an event of a specified type. /// public virtual void Raise(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; if(callback != null) { try { callback(evt); } catch(Exception gotcha) { Log(gotcha.Message); } } } } /// /// Raise an event of a specified type, creates an instance of the type automatically. /// public virtual void Raise() where T : class, new() { Raise(new T()); } /// /// Unregisters all event listeners. /// public virtual void UnregisterAll() { delegates.Clear(); } #endregion } }