// 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
}
}