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.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.