/// <summary>
        /// Remove callback from the instance.
        /// </summary>
        /// <param name="callback">The callback to remove.</param>
        /// <param name="useTrickleDown">Set this parameter to true to remove the callback from the TrickleDown phase. Set this parameter to false to remove the callback from the BubbleUp phase.</param>
        public void UnregisterCallback <TEventType, TUserArgsType>(EventCallback <TEventType, TUserArgsType> callback, TrickleDown useTrickleDown = TrickleDown.NoTrickleDown) where TEventType : EventBase <TEventType>, new()
        {
            if (m_CallbackRegistry != null)
            {
                m_CallbackRegistry.UnregisterCallback(callback, useTrickleDown);
            }

            GlobalCallbackRegistry.UnregisterListeners <TEventType>(this, callback);
        }
        public void UnregisterCallback <TEventType>(EventCallback <TEventType> callback, TrickleDown useTrickleDown = TrickleDown.NoTrickleDown) where TEventType : EventBase <TEventType>, new()
        {
            bool flag = this.m_CallbackRegistry != null;

            if (flag)
            {
                this.m_CallbackRegistry.UnregisterCallback <TEventType>(callback, useTrickleDown);
            }
            GlobalCallbackRegistry.UnregisterListeners <TEventType>(this, callback);
        }
        public void RegisterCallback <TEventType, TUserArgsType>(EventCallback <TEventType, TUserArgsType> callback, TUserArgsType userArgs, TrickleDown useTrickleDown = TrickleDown.NoTrickleDown) where TEventType : EventBase <TEventType>, new()
        {
            bool flag = this.m_CallbackRegistry == null;

            if (flag)
            {
                this.m_CallbackRegistry = new EventCallbackRegistry();
            }
            this.m_CallbackRegistry.RegisterCallback <TEventType, TUserArgsType>(callback, userArgs, useTrickleDown);
            GlobalCallbackRegistry.RegisterListeners <TEventType>(this, callback, useTrickleDown);
        }
        internal void RegisterCallback <TEventType>(EventCallback <TEventType> callback, InvokePolicy invokePolicy, TrickleDown useTrickleDown = TrickleDown.NoTrickleDown) where TEventType : EventBase <TEventType>, new()
        {
            if (m_CallbackRegistry == null)
            {
                m_CallbackRegistry = new EventCallbackRegistry();
            }

            m_CallbackRegistry.RegisterCallback(callback, useTrickleDown, invokePolicy);

            GlobalCallbackRegistry.RegisterListeners <TEventType>(this, callback, useTrickleDown);

            AddEventCategories <TEventType>();
        }
        /// <summary>
        /// Adds an event handler to the instance. If the event handler has already been registered for the same phase (either TrickleDown or BubbleUp) then this method has no effect.
        /// </summary>
        /// <param name="callback">The event handler to add.</param>
        /// <param name="userArgs">Data to pass to the callback.</param>
        /// <param name="useTrickleDown">By default, this callback is called during the BubbleUp phase. Pass TrickleDown.TrickleDown to call this callback during the TrickleDown phase.</param>
        public void RegisterCallback <TEventType, TUserArgsType>(EventCallback <TEventType, TUserArgsType> callback, TUserArgsType userArgs, TrickleDown useTrickleDown = TrickleDown.NoTrickleDown) where TEventType : EventBase <TEventType>, new()
        {
            if (m_CallbackRegistry == null)
            {
                m_CallbackRegistry = new EventCallbackRegistry();
            }

            m_CallbackRegistry.RegisterCallback(callback, userArgs, useTrickleDown, default);

            GlobalCallbackRegistry.RegisterListeners <TEventType>(this, callback, useTrickleDown);

            AddEventCategories <TEventType>();
        }