cocos2d-x 源码分析 : EventDispatcher、EventListener、Event 源码分析 (新触摸机制,新的NotificationCenter机制)【中】

admin 2018-3-27 3184


        首先我要说明的是两个非常非常重要的变量。fixedListeners和sceneGraphListeners,这是两个截然不同的Listener列表。
        1.sceneGraph类型的事件,是与当前正在运行的scene下node相关的事件,也就是说一个事件(比如说触摸事件),需要按照一定的响应序列,依次对这些Node进行事件响应,所以该类型的事件都会绑定一个与此相关联的node,并且响应顺序是与node在scene下的zorder相关的。该类型下的事件优先级统一为0.
        2.fixed类型的事件相对就比较简单了,但是有一个限制就是其优先级不能为0.
在EventDispatcher的成员变量中有一个map :std::unordered_map<EventListener::ListenerID, EventListenerVector*> _listenerMap;  一种ListenerID对应了一个Vector。
       
  1. size_t EventDispatcher::EventListenerVector::size() const  
  2. {  
  3.     //vector内部的size大小是两个list的和  
  4.     size_t ret = 0;  
  5.     if (_sceneGraphListeners)  
  6.         ret += _sceneGraphListeners->size();  
  7.     if (_fixedListeners)  
  8.         ret += _fixedListeners->size();  
  9.       
  10.     return ret;  
  11. }  

  1. void EventDispatcher::EventListenerVector::push_back(EventListener* listener)  
  2. {  
  3.     //查看listener的priority,如果为0,加入sceneGraphList,否则加入fixedList  
  4.     if (listener->getFixedPriority() == 0)  
  5.     {  
  6.         if (_sceneGraphListeners == nullptr)  
  7.         {  
  8.             _sceneGraphListeners = new std::vector<EventListener*>();  
  9.             _sceneGraphListeners->reserve(100);  
  10.         }  
  11.           
  12.         _sceneGraphListeners->push_back(listener);  
  13.     }  
  14.     else  
  15.     {  
  16.         if (_fixedListeners == nullptr)  
  17.         {  
  18.             _fixedListeners = new std::vector<EventListener*>();  
  19.             _fixedListeners->reserve(100);  
  20.         }  
  21.           
  22.         _fixedListeners->push_back(listener);  
  23.     }  
  24. }  

       上面两个函数是与一般Vector不一样的地方,需要注意的地方我已经标注了注释。

3.2 Add操作

       既然是一个类似于Manager的类,那就先从Add操作开始吧。
       三种事件的添加方式:

    3.2.1 sceneGraph类

  
  1. void EventDispatcher::addEventListenerWithSceneGraphPriority(EventListener* listener, Node* node)  
  2. {  
  3.     CCASSERT(listener && node, "Invalid parameters.");  
  4.     CCASSERT(!listener->isRegistered(), "The listener has been registered.");  
  5.       
  6.     //检查Listener可用性  
  7.     if (!listener->checkAvailable())  
  8.         return;  
  9.     //设置listener相关属性  
  10.     listener->setAssociatedNode(node);  
  11.     listener->setFixedPriority(0);  
  12.     listener->setRegistered(true);  
  13.       
  14.     addEventListener(listener);  
  15. }  

3.2.2 fixed类

     
  1. void EventDispatcher::addEventListenerWithFixedPriority(EventListener* listener, int fixedPriority)  
  2. {  
  3.     CCASSERT(listener, "Invalid parameters.");  
  4.     //一个事件只能被注册一次  
  5.     CCASSERT(!listener->isRegistered(), "The listener has been registered.");  
  6.     //Fixed类型的事件优先级不能是0  
  7.     CCASSERT(fixedPriority != 0, "0 priority is forbidden for fixed priority since it's used for scene graph based priority.");  
  8.       
  9.     //检查可用性  
  10.     if (!listener->checkAvailable())  
  11.         return;  
  12.       
  13.     //设置关联属性  
  14.     listener->setAssociatedNode(nullptr);  
  15.     listener->setFixedPriority(fixedPriority);  
  16.     listener->setRegistered(true);  
  17.     listener->setPaused(false);  
  18.   
  19.     addEventListener(listener);  
  20. }  

3.2.3 custom类

  1. EventListenerCustom* EventDispatcher::addCustomEventListener(const std::string &eventName, const std::function<void(EventCustom*)>& callback)  
  2. {  
  3.     //custom类的事件添加是通过eventName 和 eventcallBack来进行添加的  
  4.     EventListenerCustom *listener = EventListenerCustom::create(eventName, callback);  
  5.       
  6.     //custom的事件优先级被默认为1  
  7.     addEventListenerWithFixedPriority(listener, 1);  
  8.       
  9.     return listener;  
  10. }  

   可以看出,添加函数最后都用到了一个函数addEventListener,下面对其进行剖析(这个函数又用到了其他函数,又,又,又。。。。。。)

3.2.4 addEventListener

  1. void EventDispatcher::addEventListener(EventListener* listener)  
  2. {  
  3.     //如果当前Dispatcher正在进行事件Dispatch,则放到toAddList中。  
  4.     if (_inDispatch == 0)  
  5.     {  
  6.         forceAddEventListener(listener);  
  7.     }  
  8.     else  
  9.     {  
  10.         // std::vector  
  11.         _toAddedListeners.push_back(listener);  
  12.     }  
  13.   
  14.     listener->retain();  
  15. }  

3.2.5 forceAddEventListener

   
  1. void EventDispatcher::forceAddEventListener(EventListener* listener)  
  2. {  
  3.     EventListenerVector* listeners = nullptr;  
  4.     EventListener::ListenerID listenerID = listener->getListenerID();  
  5.       
  6.     //找到该类eventlistener的vector,此处的vector是EventVector  
  7.     auto itr = _listenerMap.find(listenerID);  
  8.     //如果没有找到,则需要向map中添加一个pair  
  9.     if (itr == _listenerMap.end())  
  10.     {  
  11.           
  12.         listeners = new EventListenerVector();  
  13.         _listenerMap.insert(std::make_pair(listenerID, listeners));  
  14.     }  
  15.     else  
  16.     {  
  17.         listeners = itr->second;  
  18.     }  
  19.     //将该类别listenerpush_back进去(这个函数调用的是EventVector的pushback哦)  
  20.     listeners->push_back(listener);  
  21.       
  22.     //如果优先级是0,则设置为graph。  
  23.     if (listener->getFixedPriority() == 0)  
  24.     {  
  25.         //设置该listenerID的DirtyFlag  
  26.         //(setDirty函数可以这样理解,每个ListenerID都有特定的dirtyFlag,每次进行add操作后,都要更新该ID的flag)  
  27.         setDirty(listenerID, DirtyFlag::SCENE_GRAPH_PRIORITY);  
  28.           
  29.         //如果是sceneGraph类的事件,则需要处理两个方面:  
  30.         //1.将node 与event 关联  
  31.         //2.如果该node是运行中的,则需要恢复其事件(因为默认的sceneGraph listener的状态时pause)  
  32.         //增加该listener与node的关联  
  33.         auto node = listener->getAssociatedNode();  
  34.         CCASSERT(node != nullptr, "Invalid scene graph priority!");  
  35.           
  36.         associateNodeAndEventListener(node, listener);  
  37.           
  38.         //恢复node的运行状态  
  39.         if (node->isRunning())  
  40.         {  
  41.             resumeEventListenersForTarget(node);  
  42.         }  
  43.     }  
  44.     else  
  45.     {  
  46.         setDirty(listenerID, DirtyFlag::FIXED_PRIORITY);  
  47.     }  
  48. }  

3.2.6associateNodeAndEventListener

   
  1. void EventDispatcher::associateNodeAndEventListener(Node* node, EventListener* listener)  
  2. {  
  3.     //将listener与node关联,先从map中找到与该node相关的listener vector  
  4.     std::vector<EventListener*>* listeners = nullptr;  
  5.     auto found = _nodeListenersMap.find(node);  
  6.     if (found != _nodeListenersMap.end())  
  7.     {  
  8.         listeners = found->second;  
  9.     }  
  10.     else  
  11.     {  
  12.         listeners = new std::vector<EventListener*>();  
  13.         _nodeListenersMap.insert(std::make_pair(node, listeners));  
  14.     }  
  15.     //vector内添加该listener,这里的vector 是std::vector  
  16.     listeners->push_back(listener);  
  17. }  

3.2.7  removeEventListenersForTarget

     
  1. void EventDispatcher::resumeEventListenersForTarget(Node* target, bool recursive/* = false */)  
  2. {  
  3.     //恢复Node的运行状态  
  4.     auto listenerIter = _nodeListenersMap.find(target);  
  5.     if (listenerIter != _nodeListenersMap.end())  
  6.     {  
  7.         auto listeners = listenerIter->second;  
  8.         for (auto& l : *listeners)  
  9.         {  
  10.             l->setPaused(false);  
  11.         }  
  12.     }  
  13.     // toAdd List中也要进行恢复  
  14.     for (auto& listener : _toAddedListeners)  
  15.     {  
  16.         if (listener->getAssociatedNode() == target)  
  17.         {  
  18.             listener->setPaused(false);  
  19.         }  
  20.     }  
  21.     //将该Node 与 node的child 都放到dirtyNode中,来记录与event相关的node  
  22.     setDirtyForNode(target);  
  23.       
  24.     if (recursive)  
  25.     {  
  26.         const auto& children = target->getChildren();  
  27.         for (const auto& child : children)  
  28.         {  
  29.             resumeEventListenersForTarget(child, true);  
  30.         }  
  31.     }  
  32. }  

3.3 Remove

        看完了Add,当然要讲remove

    3.3.1 removeEventListener

     
  1. void EventDispatcher::removeEventListener(EventListener* listener)  
  2. {  
  3.     //说在前面,移除一个事件的代价比较大,如果没有必要,请不要无故移除事件。  
  4.     //删除一个listener的步骤:  
  5.     if (listener == nullptr)  
  6.         return;  
  7.   
  8.     bool isFound = false;  
  9.       
  10.     //lambda函数,函数从std::vector<EventListener*>* listeners 中移除该listener  
  11.     auto removeListenerInVector = [&](std::vector<EventListener*>* listeners){  
  12.         if (listeners == nullptr)  
  13.             return;  
  14.         //遍历  
  15.         for (auto iter = listeners->begin(); iter != listeners->end(); ++iter)  
  16.         {  
  17.             auto l = *iter;  
  18.             if (l == listener)  
  19.             {  
  20.                 //找到后的处理方法,标记状态位,并处理关联Node  
  21.                 CC_SAFE_RETAIN(l);  
  22.                 l->setRegistered(false);  
  23.                 if (l->getAssociatedNode() != nullptr)  
  24.                 {  
  25.                     dissociateNodeAndEventListener(l->getAssociatedNode(), l);  
  26.                     l->setAssociatedNode(nullptr);  // NULL out the node pointer so we don't have any dangling pointers to destroyed nodes.  
  27.                 }  
  28.                 //当前没有在分发事件 则直接从listeners中移除该listener(因为标记了状态未,如果此时在分发事件,则会等结束后再移除)  
  29.                 if (_inDispatch == 0)  
  30.                 {  
  31.                     listeners->erase(iter);  
  32.                     CC_SAFE_RELEASE(l);  
  33.                 }  
  34.                   
  35.                 isFound = true;  
  36.                 break;  
  37.             }  
  38.         }  
  39.     };  
  40.       
  41.     for (auto iter = _listenerMap.begin(); iter != _listenerMap.end();)  
  42.     {  
  43.         //从listenersmap 中遍历所有,拿出所有的vector  
  44.         auto listeners = iter->second;  
  45.         auto fixedPriorityListeners = listeners->getFixedPriorityListeners();  
  46.         auto sceneGraphPriorityListeners = listeners->getSceneGraphPriorityListeners();  
  47.   
  48.         //从graphList中寻找。找到后需要更新该listenerID的dirty flag。  
  49.         removeListenerInVector(sceneGraphPriorityListeners);  
  50.         if (isFound)  
  51.         {  
  52.             // fixed #4160: Dirty flag need to be updated after listeners were removed.  
  53.             setDirty(listener->getListenerID(), DirtyFlag::SCENE_GRAPH_PRIORITY);  
  54.         }  
  55.         //从fixedList中寻找  
  56.         else  
  57.         {  
  58.             removeListenerInVector(fixedPriorityListeners);  
  59.             if (isFound)  
  60.             {  
  61.                 setDirty(listener->getListenerID(), DirtyFlag::FIXED_PRIORITY);  
  62.             }  
  63.         }  
  64.           
  65.   
  66.         //如果vector在删除后是空的,则需要移除该vector,并且将相应的listenerID从_priorityDirtyFlagMap中移除。  
  67.         if (iter->second->empty())  
  68.         {  
  69.             _priorityDirtyFlagMap.erase(listener->getListenerID());  
  70.             auto list = iter->second;  
  71.             iter = _listenerMap.erase(iter);  
  72.             CC_SAFE_DELETE(list);  
  73.         }  
  74.         else  
  75.         {  
  76.             ++iter;  
  77.         }  
  78.           
  79.         if (isFound)  
  80.             break;  
  81.     }  
  82.   
  83.     if (isFound)  
  84.     {  
  85.         CC_SAFE_RELEASE(listener);  
  86.     }  
  87.     //如果在上述过程中未找到,则从toAddList中寻找  
  88.     else  
  89.     {  
  90.         for(auto iter = _toAddedListeners.begin(); iter != _toAddedListeners.end(); ++iter)  
  91.         {  
  92.             if (*iter == listener)  
  93.             {  
  94.                 listener->setRegistered(false);  
  95.                 listener->release();  
  96.                 _toAddedListeners.erase(iter);  
  97.                 break;  
  98.             }  
  99.         }  
  100.     }  
  101. }  

3.3.2  removeEventListenersForListenerID

 
  1. void EventDispatcher::removeEventListenersForListenerID(const EventListener::ListenerID& listenerID)  
  2. {  
  3.     auto listenerItemIter = _listenerMap.find(listenerID);  
  4.     if (listenerItemIter != _listenerMap.end())  
  5.     {  
  6.         auto listeners = listenerItemIter->second;  
  7.         auto fixedPriorityListeners = listeners->getFixedPriorityListeners();  
  8.         auto sceneGraphPriorityListeners = listeners->getSceneGraphPriorityListeners();  
  9.           
  10.         //啊哦 又是一个lambda函数,将std::vector<EventListener*>* listenerVector中的Listener全部移除  
  11.         auto removeAllListenersInVector = [&](std::vector<EventListener*>* listenerVector){  
  12.             if (listenerVector == nullptr)  
  13.                 return;  
  14.               
  15.             for (auto iter = listenerVector->begin(); iter != listenerVector->end();)  
  16.             {  
  17.                 //设置要删除的listener状态,清空与其相关的node信息  
  18.                 auto l = *iter;  
  19.                 l->setRegistered(false);  
  20.                 if (l->getAssociatedNode() != nullptr)  
  21.                 {  
  22.                     dissociateNodeAndEventListener(l->getAssociatedNode(), l);  
  23.                     l->setAssociatedNode(nullptr);  // NULL out the node pointer so we don't have any dangling pointers to destroyed nodes.  
  24.                 }  
  25.                   
  26.                 if (_inDispatch == 0)  
  27.                 {  
  28.                     iter = listenerVector->erase(iter);  
  29.                     CC_SAFE_RELEASE(l);  
  30.                 }  
  31.                 else  
  32.                 {  
  33.                     ++iter;  
  34.                 }  
  35.             }  
  36.         };  
  37.           
  38.         //两种类型的事件哦  
  39.         removeAllListenersInVector(sceneGraphPriorityListeners);  
  40.         removeAllListenersInVector(fixedPriorityListeners);  
  41.           
  42.         // Remove the dirty flag according the 'listenerID'.  
  43.         // No need to check whether the dispatcher is dispatching event.  
  44.         _priorityDirtyFlagMap.erase(listenerID);  
  45.           
  46.         if (!_inDispatch)  
  47.         {  
  48.             listeners->clear();  
  49.             delete listeners;  
  50.             _listenerMap.erase(listenerItemIter);  
  51.         }  
  52.     }  
  53.       
  54.     //toAddList 的清理,真可怜,还没来得及进入家门就要被扫地出门了么。。。。  
  55.     for (auto iter = _toAddedListeners.begin(); iter != _toAddedListeners.end();)  
  56.     {  
  57.         if ((*iter)->getListenerID() == listenerID)  
  58.         {  
  59.             (*iter)->setRegistered(false);  
  60.             (*iter)->release();  
  61.             iter = _toAddedListeners.erase(iter);  
  62.         }  
  63.         else  
  64.         {  
  65.             ++iter;  
  66.         }  
  67.     }  
  68. }  

     与其相关的两个remove函数
    
  1. void EventDispatcher::removeEventListenersForType(EventListener::Type listenerType)  
  2. {  
  3.     if (listenerType == EventListener::Type::TOUCH_ONE_BY_ONE)  
  4.     {  
  5.         removeEventListenersForListenerID(EventListenerTouchOneByOne::LISTENER_ID);  
  6.     }  
  7.     else if (listenerType == EventListener::Type::TOUCH_ALL_AT_ONCE)  
  8.     {  
  9.         removeEventListenersForListenerID(EventListenerTouchAllAtOnce::LISTENER_ID);  
  10.     }  
  11.     else if (listenerType == EventListener::Type::MOUSE)  
  12.     {  
  13.         removeEventListenersForListenerID(EventListenerMouse::LISTENER_ID);  
  14.     }  
  15.     else if (listenerType == EventListener::Type::ACCELERATION)  
  16.     {  
  17.         removeEventListenersForListenerID(EventListenerAcceleration::LISTENER_ID);  
  18.     }  
  19.     else if (listenerType == EventListener::Type::KEYBOARD)  
  20.     {  
  21.         removeEventListenersForListenerID(EventListenerKeyboard::LISTENER_ID);  
  22.     }  
  23.     else  
  24.     {  
  25.         CCASSERT(false"Invalid listener type!");  
  26.     }  
  27. }  

   
  1. void EventDispatcher::removeCustomEventListeners(const std::string& customEventName)  
  2. {  
  3.     removeEventListenersForListenerID(customEventName);  
  4. }  

3.3.3 removeAllEventListeners

  
  1. void EventDispatcher::removeAllEventListeners()  
  2. {  
  3.     bool cleanMap = true;  
  4.     std::vector<EventListener::ListenerID> types(_listenerMap.size());  
  5.       
  6.     for (const auto& e : _listenerMap)  
  7.     {  
  8.         if (_internalCustomListenerIDs.find(e.first) != _internalCustomListenerIDs.end())  
  9.         {  
  10.             cleanMap = false;  
  11.         }  
  12.         else  
  13.         {  
  14.             types.push_back(e.first);  
  15.         }  
  16.     }  
  17.   
  18.     for (const auto& type : types)  
  19.     {  
  20.         removeEventListenersForListenerID(type);  
  21.     }  
  22.       
  23.     if (!_inDispatch && cleanMap)  
  24.     {  
  25.         _listenerMap.clear();  
  26.     }  
  27. }  



最新回复 (0)
返回