cocos eventDispatcher 事件分发机制

本文介绍了cocos2d-x的事件分发机制,包括_eventDispatcher的使用,事件监听器的创建与监听,事件优先级,事件吞噬等概念。事件监听器通过EventDispatch的API进行管理,优先级低的监听器先响应,事件吞噬在触摸事件中尤为重要,如新手引导和物品拖动。同时,文章提供了一个封装的用户自定义事件的lua层代码示例,并指出在C++导出给lua的API中,直接派发用户自定义事件的函数被拦截。
摘要由CSDN通过智能技术生成
简介
  1. cocos的事件分发机制,先创建事件,然后注册到事件管理中心_eventDispatcher,通过发布事件得到响应进行回调,完成事件流。
  2. _eventDispatcher是Node的属性,通过它管理当前节点(场景、层、精灵等)的所有事件的分发。但它本身是一个单例模式值的引用,在Node的构造函数中,通过Director::getInstance()->getEventDispatcher() 获取,有了这个属性,就能方便的处理事件。
事件相关的类
Event (基类) 
EventCustom (自定义事件) 
EventTouch (触摸事件)
EventMouse (鼠标事件) 
EventKeyboard (键盘事件) 
EventFocus (控件获取焦点事件) 
EventAcceleration (加速计事件)
事件监听器
EventListener, EventListenerCustom, EventListenerFocus, EventListenerMouse, EventListenerTouch, EventListenerKeyboard, EventListenerAcceleration
事件分发器
EventDispatcher (事件分发机制逻辑集合体)
事件监听器的创建与监听

创建:直接new一个Event的子类即可。

监听:添加事件监听器有三个方法,都在 EventDispatch 类中,分别是:

void addEventListenerWithSceneGraphPriority(EventListener* listener, Node* node);
void addEventListenerWithFixedPriority(EventListener* listener, int fixedPriority);
EventListenerCustom* addCustomEventListener(const std::string &eventName, const std::function<void(EventCustom*)>& callback);
事件的优先级
  1. 优先级越低,越先响应事件
  2. 如果优先级相同,则上层的(z轴)先接收触摸事件。
void EventDispatcher::dispatchEvent(Event* event)
{
   
    if (!_isEnabled)
        return;
    
    updateDirtyFlagForSceneGraph();
    
    
    DispatchGuard guard(_inDispatch);
    
    // 如果是触摸事件,走这里
    if (event->getType() == Event::Type::TOUCH)
    {
   
    	//该方法介绍了单指多指的优先逻辑(先走单指,再走多指)
        dispatchTouchEvent(static_cast<EventTouch*>(event));
        return;
    }
    // 先通过event获取到事件的标志ListenerID
    auto listenerID = __getListenerID(event);
    // 排序此事件的所有的监听器
    sortEventListeners(listenerID);
    // 分发事件逻辑的函数指针
    auto pfnDispatchEventToListeners = &EventDispatcher::dispatchEventToListeners;
    if (event->getType() == Event::Type::MOUSE) {
   
        // 如果是鼠标事件重新赋值分发事件的函数指针
        pfnDispatchEventToListeners = &EventDispatcher::dispatchTouchEventToListeners;
    }
    // 获取改事件的所有的监听器
    auto iter = _listenerMap.find(listenerID);
    if (iter != _listenerMap.end())
    {
   
        // 如果有,取出里面监听器的Vector
        auto listeners = iter->second;
        // 找到对应的监听器的时候会触发的回调函数
        auto onEvent = [&event](EventListener* listener) -> bool{
   
            event->setCurrentTarget(listener->getAssociatedNode());
            // 触发onEvent回调
            listener->_onEvent(event);
            return event->isStopped();
        };
        // 调用函数指针分发事件
        (this->*pfnDispatchEventToListeners)(listeners, onEvent);
    }
 
    updateListeners(event);
}

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 优先处理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);
                // 判断是否可以执行事件,如果可以最后调用onEvent执行,如果onEvent返回true,说明吞噬事件,结束分发。
                if (l->isEnabled() && !l->isPaused() && l->isRegistered
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值