停止事件流
self.listener1_ = cc.EventListenerCustom:create("Test_Event", function (event)
print("listener test successful")
end)
leaderInfoWidget:getEventDispatcher():addEventListenerWithFixedPriority(self.listener1_, 2)
self.listener2_ = cc.EventListenerCustom:create("Test_Event", function (event)
print("listener2 test successful")
-- 在这里调用方法停止事件流
event:stopPropagation()
end)
self:getEventDispatcher():addEventListenerWithFixedPriority(self.listener2_, 1)
调用event:stopPropagation()就可以.优先级低的事件就不会执行.
那么调用这个方法为什么会停止事件流呢,从EventDispatcher:dispatchEvent方法看起
void EventDispatcher::dispatchEvent(Event* event)
{
if (!_isEnabled)
return;
updateDirtyFlagForSceneGraph();
DispatchGuard guard(_inDispatch);
if (event->getType() == Event::Type::TOUCH){
dispatchTouchEvent(static_cast<EventTouch*>(event));
return;
}
auto listenerID = __getListenerID(event);
sortEventListeners(listenerID);
auto iter = _listenerMap.find(listenerID);
if (iter != _listenerMap.end()){
auto listeners = iter->second;
---------------- 注意这里--------------
----- 这个onEvent方法被传入到了dispatchEventToListeners方法中,说明
----- onEvent方法很有可能在dispatchEventToListeners中执行,当在
----- dispatchEventToListeners方法中执行时调用这里,注意,这里的调用
----- 里面有行listener->_onEvent(event);这个_onEvent方法就是我们
----- 所传入的callback,如果是自定义事件,这个callback进行了二次封装
----- 在EventListenerCustom中的init方法里.最后执行event->isStopped()
----- 这里如果返回的是true,那么这个事件流将会停止.这里就能结合到
----- 刚才我们在自己的代码中调用event:stopPropagation(),当我们调用
----- 这个方法时,Event里的_isStopped就会被设置成true,所以返回的
----- event->isStopped()就是true,事件流停止.接下来我们看看进入
----- dispatchEventToListeners方法查看在为什么返回isStopped为true
----- 就会停止事件流.接下
auto onEvent = [&event](EventListener* listener) -> bool{
event->setCurrentTarget(listener->getAssociatedNode());
listener->_onEvent(event);
return event->isStopped();
};
dispatchEventToListeners(listeners, onEvent);
}
updateListeners(event);
}
-----------------------------------------------------接上
---主要查看下面方法中三处onEvent(l),这里就是调用上面的onEvent方法.
---当onEvent方法返回true,如果下面if里前面的条件也满足,那么就会进入if
---并且设置shouldStopPropagation = true;跳出循环,也无法进入后面的条件语句
---所以onEvent方法不能再次被调用,这样就形成优先级较低的事件不会被执行.
void EventDispatcher::dispatchEventToListeners(EventListenerVector* listeners, const std::function<bool(EventListener*)>& onEvent)
{
bool shouldStopPropagation = false;
auto fixedPriorityListeners = listeners->getFixedPriorityListeners();
auto sceneGraphPriorityListeners = listeners->getSceneGraphPriorityListeners();
ssize_t i = 0;
// priority < 0
if (fixedPriorityListeners)
{
CCASSERT(listeners->getGt0Index() <= static_cast<ssize_t>(fixedPriorityListeners->size()), "Out of range exception!");
if (!fixedPriorityListeners->empty())
{
for (; i < listeners->getGt0Index(); ++i)
{
auto l = fixedPriorityListeners->at(i);
if (l->isEnabled() && !l->isPaused() && l->isRegistered() && onEvent(l))
{
shouldStopPropagation = true;
break;
}
}
}
}
if (sceneGraphPriorityListeners)
{
if (!shouldStopPropagation)
{
// priority == 0, scene graph priority
for (auto& l : *sceneGraphPriorityListeners)
{
if (l->isEnabled() && !l->isPaused() && l->isRegistered() && onEvent(l))
{
shouldStopPropagation = true;
break;
}
}
}
}
if (fixedPriorityListeners)
{
if (!shouldStopPropagation)
{
// priority > 0
ssize_t size = fixedPriorityListeners->size();
for (; i < size; ++i)
{
auto l = fixedPriorityListeners->at(i);
if (l->isEnabled() && !l->isPaused() && l->isRegistered() && onEvent(l))
{
shouldStopPropagation = true;
break;
}
}
}
}
}
self.listener1_ = cc.EventListenerCustom:create("Test_Event", function (event)
print("listener test successful")
end)
leaderInfoWidget:getEventDispatcher():addEventListenerWithFixedPriority(self.listener1_, 2)
self.listener2_ = cc.EventListenerCustom:create("Test_Event", function (event)
print("listener2 test successful")
-- 在这里调用方法停止事件流
event:stopPropagation()
end)
self:getEventDispatcher():addEventListenerWithFixedPriority(self.listener2_, 1)
调用event:stopPropagation()就可以.优先级低的事件就不会执行.
那么调用这个方法为什么会停止事件流呢,从EventDispatcher:dispatchEvent方法看起
void EventDispatcher::dispatchEvent(Event* event)
{
if (!_isEnabled)
return;
updateDirtyFlagForSceneGraph();
DispatchGuard guard(_inDispatch);
if (event->getType() == Event::Type::TOUCH){
dispatchTouchEvent(static_cast<EventTouch*>(event));
return;
}
auto listenerID = __getListenerID(event);
sortEventListeners(listenerID);
auto iter = _listenerMap.find(listenerID);
if (iter != _listenerMap.end()){
auto listeners = iter->second;
---------------- 注意这里--------------
----- 这个onEvent方法被传入到了dispatchEventToListeners方法中,说明
----- onEvent方法很有可能在dispatchEventToListeners中执行,当在
----- dispatchEventToListeners方法中执行时调用这里,注意,这里的调用
----- 里面有行listener->_onEvent(event);这个_onEvent方法就是我们
----- 所传入的callback,如果是自定义事件,这个callback进行了二次封装
----- 在EventListenerCustom中的init方法里.最后执行event->isStopped()
----- 这里如果返回的是true,那么这个事件流将会停止.这里就能结合到
----- 刚才我们在自己的代码中调用event:stopPropagation(),当我们调用
----- 这个方法时,Event里的_isStopped就会被设置成true,所以返回的
----- event->isStopped()就是true,事件流停止.接下来我们看看进入
----- dispatchEventToListeners方法查看在为什么返回isStopped为true
----- 就会停止事件流.接下
auto onEvent = [&event](EventListener* listener) -> bool{
event->setCurrentTarget(listener->getAssociatedNode());
listener->_onEvent(event);
return event->isStopped();
};
dispatchEventToListeners(listeners, onEvent);
}
updateListeners(event);
}
-----------------------------------------------------接上
---主要查看下面方法中三处onEvent(l),这里就是调用上面的onEvent方法.
---当onEvent方法返回true,如果下面if里前面的条件也满足,那么就会进入if
---并且设置shouldStopPropagation = true;跳出循环,也无法进入后面的条件语句
---所以onEvent方法不能再次被调用,这样就形成优先级较低的事件不会被执行.
void EventDispatcher::dispatchEventToListeners(EventListenerVector* listeners, const std::function<bool(EventListener*)>& onEvent)
{
bool shouldStopPropagation = false;
auto fixedPriorityListeners = listeners->getFixedPriorityListeners();
auto sceneGraphPriorityListeners = listeners->getSceneGraphPriorityListeners();
ssize_t i = 0;
// priority < 0
if (fixedPriorityListeners)
{
CCASSERT(listeners->getGt0Index() <= static_cast<ssize_t>(fixedPriorityListeners->size()), "Out of range exception!");
if (!fixedPriorityListeners->empty())
{
for (; i < listeners->getGt0Index(); ++i)
{
auto l = fixedPriorityListeners->at(i);
if (l->isEnabled() && !l->isPaused() && l->isRegistered() && onEvent(l))
{
shouldStopPropagation = true;
break;
}
}
}
}
if (sceneGraphPriorityListeners)
{
if (!shouldStopPropagation)
{
// priority == 0, scene graph priority
for (auto& l : *sceneGraphPriorityListeners)
{
if (l->isEnabled() && !l->isPaused() && l->isRegistered() && onEvent(l))
{
shouldStopPropagation = true;
break;
}
}
}
}
if (fixedPriorityListeners)
{
if (!shouldStopPropagation)
{
// priority > 0
ssize_t size = fixedPriorityListeners->size();
for (; i < size; ++i)
{
auto l = fixedPriorityListeners->at(i);
if (l->isEnabled() && !l->isPaused() && l->isRegistered() && onEvent(l))
{
shouldStopPropagation = true;
break;
}
}
}
}
}