eye-therapy-2 / Assets / Scripts / Events / EventManager.cs
EventManager.cs
Raw
using UnityEngine;
using System.Collections.Generic;
using UnityEngine.SceneManagement;

public class EventManager : MonoBehaviour
{
    #region C# properties
    //-----------------------------------
    //Public access to instance
    public static EventManager Instance
    {
        get { return instance; }
        set { }
    }
    #endregion

    #region variables
    // Notifications Manager instance (singleton design pattern)
    private static EventManager instance = null;

    //Array of listeners (all objects registered for events)
    private Dictionary<EVENT_TYPE, List<IListener>> Listeners = new Dictionary<EVENT_TYPE, List<IListener>>();
    #endregion
    
    #region methods
    //Called at start-up to initialize
    void Awake()
    {
        //If no instance exists, then assign this instance
        if (instance == null)
        {
            instance = this;
            DontDestroyOnLoad(gameObject);
            SceneManager.sceneLoaded += OnLevelFinishedLoading;
        }
        else
            DestroyImmediate(this);
    }

    private void OnDisable()
    {
        SceneManager.sceneLoaded -= OnLevelFinishedLoading;
    }

    /// <summary>
    /// Function to add listener to array of listeners
    /// </summary>
    /// <param name="Event_Type">Event to Listen for</param>
    /// <param name="Listener">Object to listen for event</param>
    public void AddListener(EVENT_TYPE Event_Type, IListener Listener)
    {
        //List of listeners for this event
        List<IListener> ListenList = null;

        // Check existing event type key. If exists, add to list
        if (Listeners.TryGetValue(Event_Type, out ListenList))
        {
            //List exists, so add new item
            ListenList.Add(Listener);
            return;
        }

        //Otherwise create new list as dictionary key
        ListenList = new List<IListener>();
        ListenList.Add(Listener);
        Listeners.Add(Event_Type, ListenList);
    }

    /// <summary>
    /// Function to post event to listeners
    /// </summary>
    /// <param name="Event_Type">Event to invoke</param>
    /// <param name="Sender">Object invoking event</param>
    /// <param name="Param">Optional argument</param>
    //public void PostNotification(EVENT_TYPE Event_Type, Component Sender, Object Param = null)
    //{
    //    //Notify all listeners of an event

    //    //List of listeners for this event only
    //    List<IListener> ListenList = null;

    //    //If no event exists, then exit
    //    if (!Listeners.TryGetValue(Event_Type, out ListenList))
    //        return;

    //    //Entry exists. Now notify appropriate listeners
    //    for (int i = 0; i < ListenList.Count; i++)
    //    {
    //        if (!ListenList[i].Equals(null))
    //        {
    //            ListenList[i].OnEvent(Event_Type, Sender, Param);
    //        }
    //    }

    //}
    public void PostNotification<T>(EVENT_TYPE Event_Type, Component Sender, T Param = default)
    {
        //Notify all listeners of an event

        //List of listeners for this event only
        List<IListener> ListenList = null;

        //If no event exists, then exit
        if (!Listeners.TryGetValue(Event_Type, out ListenList))
            return;

        //Entry exists. Now notify appropriate listeners
        for (int i = 0; i < ListenList.Count; i++)
        {
            if (!ListenList[i].Equals(null))
            {
                ListenList[i].OnEvent<T>(Event_Type, Sender, Param);
            }
        }

    }

    //Remove event from dictionary, including all listeners
    public void RemoveEvent(EVENT_TYPE Event_Type)
    {
        //Remove entry from dictionary
        Listeners.Remove(Event_Type);
    }
    
    //Remove all redundant entries from the Dictionary
    public void RemoveRedundancies()
    {
        //Create new dictionary
        Dictionary<EVENT_TYPE, List<IListener>> TmpListeners = new Dictionary<EVENT_TYPE, List<IListener>>();

        //Cycle through all dictionary entries
        foreach (KeyValuePair<EVENT_TYPE, List<IListener>> Item in Listeners)
        {
            //Cycle all listeners, remove null objects
            for (int i = Item.Value.Count - 1; i >= 0; i--)
            {
                //If null, then remove item
                if (Item.Value[i].Equals(null))
                    Item.Value.RemoveAt(i);
            }

            //If items remain in list, then add to tmp dictionary
            if (Item.Value.Count > 0)
                TmpListeners.Add(Item.Key, Item.Value);
        }

        //Replace listeners object with new dictionary
        Listeners = TmpListeners;
    }
    
    //Called on scene change. Clean up dictionary
    private void OnLevelFinishedLoading(Scene scene, LoadSceneMode mode)
    {
        RemoveRedundancies();
    }
    #endregion
}