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(已注册监听器)。