停止事件流

来源:互联网 发布:战争是必然的 知乎 编辑:程序博客网 时间:2024/05/16 05:48
停止事件流
    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;
                }
            }
        }
    }
}
0 0
原创粉丝点击