Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Custom event system between GameObjects
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
/// <summary>
/// Event notification.
/// This class implements an event notification system between MonoBehaviours.
/// The MonoBehaviour that wants to receive a specific Event needs to add himself to
/// the listeners poll of this class like this:
/// EventNotification.center.addListnerOn(typeof(EventNotification.Notification), this, eventRespond);
/// Any GameObject who wants to send a specific message has to call the send method like this:
/// EventNotification.center.send(new EventNotification.Notification(this));
/// Very useful with UI.
/// </summary>
public class EventNotification
{
public class Notification
{
public Component sender { get { return m_sender; } }
protected Component m_sender;
protected Notification(Component aSender)
{
m_sender = aSender;
}
}
public static EventNotification center {
get { if (instance != null) return instance; return new EventNotification(); } }
public EventNotification()
{
if (instance == null)
instance = this;
}
public delegate void EventCB(object notif);
private static EventNotification instance;
private Hashtable eventTable = new Hashtable();
/// <summary>
/// Adds a listner component on a specific event.
/// </summary>
/// <param name="onEvent">The type of event the listner wants to handle.</param>
/// <param name="listener">The Component listener.</param>
/// <param name="cb">Callback of the listener that handle that event. </param>
public void addListnerOn(Type onEvent, Component listener, EventCB cb)
{
string eventName = EventNotification.getEventName(onEvent);
if (eventTable[eventName] == null)
eventTable[eventName] = new Dictionary<Component, EventCB>();
Dictionary<Component, EventCB> notifyList = eventTable[eventName] as Dictionary<Component, EventCB>;
if (!notifyList.ContainsKey(listener))
notifyList.Add(listener, cb);
}
/// <summary>
/// Remove a listner component from a specific event.
/// </summary>
/// <param name="onEvent">The type of event the listner wants to remove.</param>
/// <param name="listener">The Component listener.</param>
public void removeListnerOn(Type onEvent, Component listener)
{
string eventName = EventNotification.getEventName(onEvent);
Dictionary<Component, EventCB> notifyList = eventTable[eventName] as Dictionary<Component, EventCB>;
if (notifyList != null)
{
if (notifyList.ContainsKey(listener))
{
notifyList.Remove(listener);
}
if (notifyList.Count == 0)
eventTable.Remove(listener);
}
}
/// <summary>
/// Send the specified Notification to all the listeners subscribed to it.
/// </summary>
/// <param name="eventToSend">Event to send.</param>
public void send(Notification eventToSend)
{
string eventName = EventNotification.getEventName(eventToSend.GetType());
Dictionary<Component, EventCB> notifyList = eventTable[eventName] as Dictionary<Component, EventCB>;
if (notifyList == null)
{
Debug.Log("Notify list not found on Event: " + eventName);
return;
}
foreach(KeyValuePair<Component, EventCB> entry in notifyList)
{
EventCB callBack = entry.Value;
callBack(eventToSend);
}
}
private static string getEventName(Type onEvent)
{
char[] delimiterChars = {'.', '+'};
string[] split = (onEvent.ToString().Split(delimiterChars));
string eventName = split[split.Length - 1];
return eventName;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.