‎Cocos2d-x 学习笔记(14.2) EventListener _paused _isEnabled _isRegistered

监听器3个bool类型成员变量。

监听器能设置是否能够接收事件。

能随时接收事件进行处理,此时把它看做工作状态,需要满足条件:

    _paused = false;
    _isEnabled = true;

监听器init方法执行上述语句,使得不管哪种监听器,初始化时都默认处于工作状态。

监听器init方法还执行了:

    _isRegistered = false;

也就是说,监听器默认没有注册。

1. _paused

init方法置_paused为false。

监听器的暂停与否仅用于场景图的监听器。自定义优先级的监听器的暂停标志一直为false。

场景图监听器关联的node运行onEnter onExit方法中,监听器会被自动设置暂停标志。

在onEnter方法中,会调用到resume()。该方法中,事件分发器对node关联的所有监听器设置setPaused(false),包括待添加容器里的监听器。

void Node::resume()
{
    _scheduler->resumeTarget(this);
    _actionManager->resumeTarget(this);
    _eventDispatcher->resumeEventListenersForTarget(this);
}

同理,在onExit方法,事件分发器对这些监听器setPaused(true)。

void Node::pause()
{
    _scheduler->pauseTarget(this);
    _actionManager->pauseTarget(this);
    _eventDispatcher->pauseEventListenersForTarget(this);
}

2. _isEnabled

init方法置_isEnabled为true。

当自定义优先级监听器需要“暂停”,需要不接收事件时,不能更改暂停标志,要调用setEnabled(false)更改_isEnabled标志。

自定义优先级监听器暂停标志永远为false。

3. _isRegistered

init方法置_isRegistered为false。

当调用addEventListenerWithFixedPriority addEventListenerWithSceneGraphPriority两方法添加监听器到监听器容器时,先断言,条件是!listener->isRegistered(),即要求参数监听器未注册才能添加到容器里,之后再设置注册标记setRegistered(true)。

简而言之,未注册的监听器才能加到容器里。

remove方法删除监听器时,都要先对监听器先setRegistered(false)。如果正在进行事件分发,删除的操作在分发后的updateListeners方法执行,该方法会把之前setRegistered(false)的监听器删除。

4. 进行事件分发时 

分发事件时dispatchEvent(Event*)函数的分发过程在dispatchEventToListeners方法中。

该方法对遍历到的每个监听器执行:

                if (l->isEnabled() && !l->isPaused() && l->isRegistered() && onEvent(l))
                {
                    shouldStopPropagation = true;
                    break;
                }

&&是短路操作,也就是说在监听器处理事件之前,需要确保_isEnabled(启用监听器)_paused(没暂停监听器)_isRegistered(已注册监听器)。

posted @ 2019-08-05 14:54  deepcho  阅读(293)  评论(0编辑  收藏  举报

博客园提供博客支持
爱我所选,选我所爱。
❤️