private EventGenericDelegate addDelegate <T> (EventGenericDelegate <T> del) where T : GameEvent
    {
        // Early-out if we've already registered this delegate
        if (delegateLookup.ContainsKey(del))
        {
            return(null);
        }

        // Create a new non-generic delegate which calls our generic one.
        // This is the delegate we actually invoke.
        EventGenericDelegate internalDelegate = (e) => del((T)e);

        delegateLookup[del] = internalDelegate;

        EventGenericDelegate thisEvent = null;

        if (delegates.TryGetValue(typeof(T), out thisEvent))
        {
            delegates[typeof(T)] = thisEvent += internalDelegate;
        }
        else
        {
            delegates[typeof(T)] = internalDelegate;
        }
        Debugger.printLog("Start listening to event: " + internalDelegate.ToString());
        return(internalDelegate);
    }
    public void AddListenerOnce <T>(EventGenericDelegate <T> del) where T : GameEvent
    {
        EventGenericDelegate result = addDelegate <T>(del);

        if (result != null)
        {
            // remember this is only called once
            onceLookups[result] = del;
        }
    }
    /// <summary>
    /// Removes method to be invoked when event raised.
    /// </summary>
    /// <typeparam name="T">The event associated with the event delegate.</typeparam>
    /// <param name="del">The method to be removed.</param>
    public void RemoveListener <T>(EventGenericDelegate <T> del) where T : GameEvent
    {
        EventGenericDelegate internalDelegate;

        if (delegateLookup.TryGetValue(del, out internalDelegate))
        {
            EventGenericDelegate tempDel;
            if (delegates.TryGetValue(typeof(T), out tempDel))
            {
                tempDel -= internalDelegate;
                if (tempDel == null)
                {
                    delegates.Remove(typeof(T));
                }
                else
                {
                    delegates[typeof(T)] = tempDel;
                }
            }
            Debugger.printLog("Remove event: " + del.ToString());
            delegateLookup.Remove(del);
        }
    }
 ///<summary>
 /// Adds method to be invoked when event raised.
 /// </summary>
 /// <typeparam name="T">The event associated with the event delegate.</typeparam>
 /// <param name="del">The method to be stored and invoked if the event is raised.</param>
 public void AddListener <T>(EventGenericDelegate <T> del) where T : GameEvent
 {
     addDelegate <T>(del);
 }
 public bool HasListener <T>(EventGenericDelegate <T> del) where T : GameEvent
 {
     return(delegateLookup.ContainsKey(del));
 }