• 从零开始のcocos2dx生活(六)EventDispatcher


    EventDispatcher可能是所有的里面比较不容易理解也不容易看的
    我说自己的理解可能会误导到你们…【索了你们看不下去><
    我写了几乎所有的代码的注释,有的是废话跳过就好
    主要的代码是在dispatchEvent中,然后再进入不同的函数中
    dispatchTouchEvent
    dispatchTouchEventToListeners
    dispatchEventToListeners
    都是很重要的逻辑代码,可以多看几遍,加深理解
    然后直接看代码吧

    //触摸不使用这个方法获取
    static EventListener::ListenerID __getListenerID(Event* event)
    {
        EventListener::ListenerID ret;
        switch (event->getType())
        {
            case Event::Type::ACCELERATION:
                ret = EventListenerAcceleration::LISTENER_ID;
                break;
            case Event::Type::CUSTOM:
                {
                    auto customEvent = static_cast<EventCustom*>(event);
                    ret = customEvent->getEventName();
                }
                break;
            case Event::Type::KEYBOARD:
                ret = EventListenerKeyboard::LISTENER_ID;
                break;
            case Event::Type::MOUSE:
                ret = EventListenerMouse::LISTENER_ID;
                break;
            case Event::Type::FOCUS:
                ret = EventListenerFocus::LISTENER_ID;
                break;
            case Event::Type::TOUCH:
                // Touch listener is very special, it contains two kinds of listeners, EventListenerTouchOneByOne and EventListenerTouchAllAtOnce.
                // return UNKNOWN instead.
                CCASSERT(false, "Don't call this method if the event is for touch.");
                break;
    #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_MAC || CC_TARGET_PLATFORM == CC_PLATFORM_LINUX || CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
            case Event::Type::GAME_CONTROLLER:
                ret = EventListenerController::LISTENER_ID;
                break;
    #endif
            default:
                CCASSERT(false, "Invalid type!");
                break;
        }
        
        return ret;
    }
    
    EventDispatcher::EventListenerVector::EventListenerVector() :
     _fixedListeners(nullptr),
     _sceneGraphListeners(nullptr),
     _gt0Index(0)
    {
    }
    
    EventDispatcher::EventListenerVector::~EventListenerVector()
    {
        CC_SAFE_DELETE(_sceneGraphListeners);
        CC_SAFE_DELETE(_fixedListeners);
    }
    
    size_t EventDispatcher::EventListenerVector::size() const
    {
        size_t ret = 0;
        if (_sceneGraphListeners)
            ret += _sceneGraphListeners->size();
        if (_fixedListeners)
            ret += _fixedListeners->size();
        
        return ret;
    }
    
    bool EventDispatcher::EventListenerVector::empty() const
    {
        return (_sceneGraphListeners == nullptr || _sceneGraphListeners->empty())
            && (_fixedListeners == nullptr || _fixedListeners->empty());
    }
    
    void EventDispatcher::EventListenerVector::push_back(EventListener* listener)
    {
    #if CC_NODE_DEBUG_VERIFY_EVENT_LISTENERS
        CCASSERT(_sceneGraphListeners == nullptr ||
                 std::count(_sceneGraphListeners->begin(), _sceneGraphListeners->end(), listener) == 0,
                 "Listener should not be added twice!");
            
        CCASSERT(_fixedListeners == nullptr ||
                 std::count(_fixedListeners->begin(), _fixedListeners->end(), listener) == 0,
                 "Listener should not be added twice!");
    #endif
    
        if (listener->getFixedPriority() == 0)
        {
            if (_sceneGraphListeners == nullptr)
            {
                _sceneGraphListeners = new (std::nothrow) std::vector<EventListener*>();
                _sceneGraphListeners->reserve(100);
            }
            
            _sceneGraphListeners->push_back(listener);
        }
        else
        {
            if (_fixedListeners == nullptr)
            {
                _fixedListeners = new std::vector<EventListener*>();
                _fixedListeners->reserve(100);
            }
            
            _fixedListeners->push_back(listener);
        }
    }
    
    //清理场景图优先级监听器数组
    void EventDispatcher::EventListenerVector::clearSceneGraphListeners()
    {
        //这里的delete只是删除了_sceneGraphListeners指针指向的目标,不是指针本身,之后又把它置空了
        if (_sceneGraphListeners)
        {
            _sceneGraphListeners->clear();
            delete _sceneGraphListeners;
            _sceneGraphListeners = nullptr;
        }
    }
    //清理自定义优先级监听器数组
    void EventDispatcher::EventListenerVector::clearFixedListeners()
    {
        if (_fixedListeners)
        {
            _fixedListeners->clear();
            delete _fixedListeners;
            _fixedListeners = nullptr;
        }
    }
    
    //同时清理
    void EventDispatcher::EventListenerVector::clear()
    {
        clearSceneGraphListeners();
        clearFixedListeners();
    }
    
    
    EventDispatcher::EventDispatcher()
    : _inDispatch(0)
    , _isEnabled(false)
    , _nodePriorityIndex(0)
    {
        _toAddedListeners.reserve(50);
        _toRemovedListeners.reserve(50);
        
        // fixed #4129: Mark the following listener IDs for internal use.
        // Therefore, internal listeners would not be cleaned when removeAllEventListeners is invoked.
        _internalCustomListenerIDs.insert(EVENT_COME_TO_FOREGROUND);
        _internalCustomListenerIDs.insert(EVENT_COME_TO_BACKGROUND);
        _internalCustomListenerIDs.insert(EVENT_RENDERER_RECREATED);
    }
    
    EventDispatcher::~EventDispatcher()
    {
        // Clear internal custom listener IDs from set,
        // so removeAllEventListeners would clean internal custom listeners.
        _internalCustomListenerIDs.clear();
        removeAllEventListeners();
    }
    
    void EventDispatcher::visitTarget(Node* node, bool isRootNode)
    {
        //给所有的字节点排序
        node->sortAllChildren();
        
        int i = 0;
        auto& children = node->getChildren();
        
        auto childrenCount = children.size();
        
        //中序遍历并添加相对的父节点到_globalZOrderNodeMap中
        if(childrenCount > 0)
        {
            Node* child = nullptr;
            //遍历zorder<0的节点
            // visit children zOrder < 0
            for( ; i < childrenCount; i++ )
            {
                child = children.at(i);
                
                if ( child && child->getLocalZOrder() < 0 )
                    visitTarget(child, false);
                else
                    break;
            }
            
            //将相对的父节点加入到_globalZOrderNodeMap中
            if (_nodeListenersMap.find(node) != _nodeListenersMap.end())
            {
                _globalZOrderNodeMap[node->getGlobalZOrder()].push_back(node);
            }
            
            //遍历zorder>0的节点
            for( ; i < childrenCount; i++ )
            {
                child = children.at(i);
                if (child)
                    visitTarget(child, false);
            }
        }
        //如果没有子节点,将自己加入到_globalZOrderNodeMap中
        else
        {
            if (_nodeListenersMap.find(node) != _nodeListenersMap.end())
            {
                _globalZOrderNodeMap[node->getGlobalZOrder()].push_back(node);
            }
        }
        
        //形参isRootNode如果是true
        if (isRootNode)
        {
            std::vector<float> globalZOrders;
            globalZOrders.reserve(_globalZOrderNodeMap.size());
            
            //获取所有的优先级等级
            for (const auto& e : _globalZOrderNodeMap)
            {
                globalZOrders.push_back(e.first);
            }
            
            //稳定排序,排序完成后,相同的数相对位置不发生改变
            std::stable_sort(globalZOrders.begin(), globalZOrders.end(), [](const float a, const float b){
                return a < b;
            });
            
            //遍历所有的zorder
            for (const auto& globalZ : globalZOrders)
            {
                //遍历所有zorder对应的node
                for (const auto& n : _globalZOrderNodeMap[globalZ])
                {
                    //设置每个节点的优先级,存储在_nodePriorityMap
                    _nodePriorityMap[n] = ++_nodePriorityIndex;
                }
            }
            
            //这个全局变量只是一个中间值,用来存储globalZOrder和Node的关系,用完之后需要重置
            _globalZOrderNodeMap.clear();
        }
    }
    
    //暂停target对应的listener
    void EventDispatcher::pauseEventListenersForTarget(Node* target, bool recursive/* = false */)
    {
        //找到它,暂停它
        auto listenerIter = _nodeListenersMap.find(target);
        if (listenerIter != _nodeListenersMap.end())
        {
            auto listeners = listenerIter->second;
            for (auto& l : *listeners)
            {
                l->setPaused(true);
            }
        }
    
        //如果在_toAddedListeners中,还未添加,那也暂停它
        for (auto& listener : _toAddedListeners)
        {
            if (listener->getAssociatedNode() == target)
            {
                listener->setPaused(true);
            }
        }
        
        //子节点根据形参也暂停或者不暂停
        if (recursive)
        {
            const auto& children = target->getChildren();
            for (const auto& child : children)
            {
                pauseEventListenersForTarget(child, true);
            }
        }
    }
    
    //恢复target的listener
    void EventDispatcher::resumeEventListenersForTarget(Node* target, bool recursive/* = false */)
    {
        auto listenerIter = _nodeListenersMap.find(target);
        if (listenerIter != _nodeListenersMap.end())
        {
            auto listeners = listenerIter->second;
            for (auto& l : *listeners)
            {
                l->setPaused(false);
            }
        }
        //如果在_toAddedListeners中,还未添加,那也恢复它
        for (auto& listener : _toAddedListeners)
        {
            if (listener->getAssociatedNode() == target)
            {
                listener->setPaused(false);
            }
        }
    
        //标记脏节点,待刷新
        setDirtyForNode(target);
        
        if (recursive)
        {
            const auto& children = target->getChildren();
            for (const auto& child : children)
            {
                resumeEventListenersForTarget(child, true);
            }
        }
    }
    
    //根据target移除对应的listener
    void EventDispatcher::removeEventListenersForTarget(Node* target, bool recursive/* = false */)
    {
        // Ensure the node is removed from these immediately also.
        // Don't want any dangling pointers or the possibility of dealing with deleted objects..
        //从节点-优先级map中移除,并且也从脏节点容器中移除,确保不会再被访问
        _nodePriorityMap.erase(target);
        _dirtyNodes.erase(target);
    
        //找到节点-监听器map中的target,将它对应的监听器数组全部移除
        auto listenerIter = _nodeListenersMap.find(target);
        if (listenerIter != _nodeListenersMap.end())
        {
            auto listeners = listenerIter->second;
            auto listenersCopy = *listeners;
            for (auto& l : listenersCopy)
            {
                removeEventListener(l);
            }
        }
        
        // Bug fix: ensure there are no references to the node in the list of listeners to be added.
        // If we find any listeners associated with the destroyed node in this list then remove them.
        // This is to catch the scenario where the node gets destroyed before it's listener
        // is added into the event dispatcher fully. This could happen if a node registers a listener
        // and gets destroyed while we are dispatching an event (touch etc.)
        //从要添加的监听器列表中移除,也是为了确保不会再访问这个移除的节点
        for (auto iter = _toAddedListeners.begin(); iter != _toAddedListeners.end(); )
        {
            EventListener * listener = *iter;
                
            if (listener->getAssociatedNode() == target)
            {
                listener->setAssociatedNode(nullptr);   // Ensure no dangling ptr to the target node.
                listener->setRegistered(false);
                releaseListener(listener);
                iter = _toAddedListeners.erase(iter); //返回删除iter后一个元素
            }
            else
            {
                ++iter;
            }
        }
        
        //是否对子节点遍历移除
        if (recursive)
        {
            const auto& children = target->getChildren();
            for (const auto& child : children)
            {
                removeEventListenersForTarget(child, true);
            }
        }
    }
    
    //将节点和监听器链接起来
    void EventDispatcher::associateNodeAndEventListener(Node* node, EventListener* listener)
    {
        std::vector<EventListener*>* listeners = nullptr;
        //查找nodeListenerMap中是否已经有了要链接的node
        auto found = _nodeListenersMap.find(node);
        //如果找到了,就获取它对应的listener数组
        if (found != _nodeListenersMap.end())
        {
            listeners = found->second;
        }
        //没找到就创建一个存放监听器的数组,并将node和监听器空数组加入_nodeListenersMap中,
        else
        {
            listeners = new (std::nothrow) std::vector<EventListener*>();
            _nodeListenersMap.emplace(node, listeners);
        }
        
        //将想要添加的监听器加入到与节点关联的监听器数组中
        listeners->push_back(listener);
    }
    
    //解除节点和监听器的关联
    void EventDispatcher::dissociateNodeAndEventListener(Node* node, EventListener* listener)
    {
        std::vector<EventListener*>* listeners = nullptr;
        //查找是否已经存储了形参node
        auto found = _nodeListenersMap.find(node);
        //如果找到了
        if (found != _nodeListenersMap.end())
        {
            listeners = found->second;  ///<获取节点对应的监听器数组
            auto iter = std::find(listeners->begin(), listeners->end(), listener); ///<查找监听器数组中有没有要删除的监听器
            if (iter != listeners->end()) ///< 如果找到了,移除
            {
                listeners->erase(iter);
            }
            
            if (listeners->empty())  ///<如果此时监听器数组是空的,就在_nodeListenersMap移除这个节点key,并且删除listener
            {
                _nodeListenersMap.erase(found);
                delete listeners;
            }
        }
    }
    
    void EventDispatcher::addEventListener(EventListener* listener)
    {
        //如果没有被调用,直接添加
        if (_inDispatch == 0)
        {
            forceAddEventListener(listener);
        }
        //正在被调用就将listener添加到待添加队列中,延时添加
        else
        {
            _toAddedListeners.push_back(listener);
        }
    #if CC_ENABLE_GC_FOR_NATIVE_OBJECTS
        auto sEngine = ScriptEngineManager::getInstance()->getScriptEngine();
        if (sEngine)
        {
            sEngine->retainScriptObject(this, listener);
        }
    #endif // CC_ENABLE_GC_FOR_NATIVE_OBJECTS
        //这里的listener是指针,如果不ratain会被释放
        listener->retain();
    }
    
    //实际执行添加监听器操作的函数 添加到_listenerMap  添加到_nodeListenersMap
    void EventDispatcher::forceAddEventListener(EventListener* listener)
    {
        EventListenerVector* listeners = nullptr;
        EventListener::ListenerID listenerID = listener->getListenerID();
        //从存储listenerMap中查找要添加监听器的ID
        auto itr = _listenerMap.find(listenerID);
        //如果没有找到,就新建一个监听器数组,将行新的listenerID和新建的监听器数组加入到listenerMap中
        if (itr == _listenerMap.end())
        {
            listeners = new (std::nothrow) EventListenerVector();
            _listenerMap.emplace(listenerID, listeners);
        }
        //找到了就获取对应的监听器数组
        else
        {
            listeners = itr->second;
        }
        
        //往监听器数组中添加新的监听器
        listeners->push_back(listener);
        
        //如果优先级是0,则添加脏标记为 场景图优先级
        if (listener->getFixedPriority() == 0)
        {
            setDirty(listenerID, DirtyFlag::SCENE_GRAPH_PRIORITY);
            
            auto node = listener->getAssociatedNode();
            CCASSERT(node != nullptr, "Invalid scene graph priority!");
            
            associateNodeAndEventListener(node, listener);
            
            if (!node->isRunning())
            {
                listener->setPaused(true);
            }
        }
        //否则添加脏标记为 自定义优先级
        else
        {
            setDirty(listenerID, DirtyFlag::FIXED_PRIORITY);
        }
    
    }
    
    //添加场景图优先级的监听器
    void EventDispatcher::addEventListenerWithSceneGraphPriority(EventListener* listener, Node* node)
    {
        CCASSERT(listener && node, "Invalid parameters.");
        CCASSERT(!listener->isRegistered(), "The listener has been registered.");
        
        if (!listener->checkAvailable())
            return;
        //设置节点和监听器关联、优先级为0、已注册
        listener->setAssociatedNode(node);
        listener->setFixedPriority(0);
        listener->setRegistered(true);
        
        //添加监听器到
        addEventListener(listener);
    }
    
    #if CC_NODE_DEBUG_VERIFY_EVENT_LISTENERS && COCOS2D_DEBUG > 0
    
    void EventDispatcher::debugCheckNodeHasNoEventListenersOnDestruction(Node* node)
    {
        // Check the listeners map
        for (const auto & keyValuePair : _listenerMap)
        {
            const EventListenerVector * eventListenerVector = keyValuePair.second;
            
            if (eventListenerVector)
            {
                if (eventListenerVector->getSceneGraphPriorityListeners())
                {
                    for (EventListener * listener : *eventListenerVector->getSceneGraphPriorityListeners())
                    {
                        CCASSERT(!listener ||
                                 listener->getAssociatedNode() != node,
                                 "Node should have no event listeners registered for it upon destruction!");
                    }
                }
            }
        }
        
        // Check the node listeners map
        for (const auto & keyValuePair : _nodeListenersMap)
        {
            CCASSERT(keyValuePair.first != node, "Node should have no event listeners registered for it upon destruction!");
            
            if (keyValuePair.second)
            {
                for (EventListener * listener : *keyValuePair.second)
                {
                    CCASSERT(listener->getAssociatedNode() != node,
                             "Node should have no event listeners registered for it upon destruction!");
                }
            }
        }
        
        // Check the node priority map
        for (const auto & keyValuePair : _nodePriorityMap)
        {
            CCASSERT(keyValuePair.first != node,
                     "Node should have no event listeners registered for it upon destruction!");
        }
        
        // Check the to be added list
        for (EventListener * listener : _toAddedListeners)
        {
            CCASSERT(listener->getAssociatedNode() != node,
                     "Node should have no event listeners registered for it upon destruction!");
        }
        
        // Check the dirty nodes set
        for (Node * dirtyNode : _dirtyNodes)
        {
            CCASSERT(dirtyNode != node,
                     "Node should have no event listeners registered for it upon destruction!");
        }
    }
    
    #endif  // #if CC_NODE_DEBUG_VERIFY_EVENT_LISTENERS && COCOS2D_DEBUG > 0
    
    
    //添加自定义优先级的监听器
    void EventDispatcher::addEventListenerWithFixedPriority(EventListener* listener, int fixedPriority)
    {
        CCASSERT(listener, "Invalid parameters.");
        CCASSERT(!listener->isRegistered(), "The listener has been registered.");
        CCASSERT(fixedPriority != 0, "0 priority is forbidden for fixed priority since it's used for scene graph based priority.");
        
        if (!listener->checkAvailable())
            return;
        
        //设置监听器的关联节点是空、设置优先级、已注册、没暂停
        listener->setAssociatedNode(nullptr);
        listener->setFixedPriority(fixedPriority);
        listener->setRegistered(true);
        listener->setPaused(false);
    
        addEventListener(listener);
    }
    
    //添加自定义监听器,默认优先级为1
    EventListenerCustom* EventDispatcher::addCustomEventListener(const std::string &eventName, const std::function<void(EventCustom*)>& callback)
    {
        EventListenerCustom *listener = EventListenerCustom::create(eventName, callback);
        addEventListenerWithFixedPriority(listener, 1);
        return listener;
    }
    
    //
    void EventDispatcher::removeEventListener(EventListener* listener)
    {
        if (listener == nullptr)
            return;
        
        if (std::find(_toRemovedListeners.begin(), _toRemovedListeners.end(), listener) != _toRemovedListeners.end())
        // just return if listener is in _toRemovedListeners to avoid remove listeners more than once
        // 如果监听器是在_toRemovedListeners中,会在update时删除,这里直接返回,避免了重复删除
            return;
    
        bool isFound = false;
        
        //定义从容器中移除监听器的匿名函数
        auto removeListenerInVector = [&](std::vector<EventListener*>* listeners){
            if (listeners == nullptr)
                return;
            
            //遍历监听器数组
            for (auto iter = listeners->begin(); iter != listeners->end(); ++iter)
            {
                auto l = *iter;
                if (l == listener)
                {
                    CC_SAFE_RETAIN(l);///< ratain住,不然会被释放掉
                    l->setRegistered(false); //取消注册
                    if (l->getAssociatedNode() != nullptr) ///<如果有关联的节点
                    {
                        dissociateNodeAndEventListener(l->getAssociatedNode(), l); ///<取消节点监听器的关联
                        l->setAssociatedNode(nullptr);  // nullptr out the node pointer so we don't have any dangling pointers to destroyed nodes.
                        ///<将监听器关联的节点属性置空
                    }
                    //如果没有在调用直接移除
                    if (_inDispatch == 0)
                    {
                        iter = listeners->erase(iter);
                        releaseListener(l);
                    }
                    //否则加到待删除数组中,延时删除
                    else
                    {
                        _toRemovedListeners.push_back(l);
                    }
                    //标记为已经移除
                    isFound = true;
                    break;
                }
            }
        };
        
        //遍历listenerMap
        for (auto iter = _listenerMap.begin(); iter != _listenerMap.end();)
        {
            auto listeners = iter->second; ///<获取监听器数组
            auto fixedPriorityListeners = listeners->getFixedPriorityListeners(); ///<获取自定义优先级监听器数组
            auto sceneGraphPriorityListeners = listeners->getSceneGraphPriorityListeners();///<获取场景图优先级的监听器数组
            removeListenerInVector(sceneGraphPriorityListeners); ///<从场景图优先级数组中移除
            //如果找到了(移除成功)
            if (isFound)
            {
                // fixed #4160: Dirty flag need to be updated after listeners were removed.
                //设置场景图优先级脏标记
                setDirty(listener->getListenerID(), DirtyFlag::SCENE_GRAPH_PRIORITY);
            }
            //没有在场景图优先级数组中找到要删除的
            else
            {
                //从自定义优先级监听器数组中查找
                removeListenerInVector(fixedPriorityListeners);
                //如果找到了就设置自定义优先级的脏标记
                if (isFound)
                {
                    setDirty(listener->getListenerID(), DirtyFlag::FIXED_PRIORITY);
                }
            }
            
    #if CC_NODE_DEBUG_VERIFY_EVENT_LISTENERS
            CCASSERT(_inDispatch != 0 ||
                     !sceneGraphPriorityListeners ||
                     std::count(sceneGraphPriorityListeners->begin(), sceneGraphPriorityListeners->end(), listener) == 0,
                     "Listener should be in no lists after this is done if we're not currently in dispatch mode.");
                
            CCASSERT(_inDispatch != 0 ||
                     !fixedPriorityListeners ||
                     std::count(fixedPriorityListeners->begin(), fixedPriorityListeners->end(), listener) == 0,
                     "Listener should be in no lists after this is done if we're not currently in dispatch mode.");
    #endif
            //如果删除指定监听器之后,监听器数组是空的了
            if (iter->second->empty())
            {
                //从优先级脏标记表中移除这个监听器
                _priorityDirtyFlagMap.erase(listener->getListenerID());
                //从监听器表中移除当前监听器ID和对应的监听器数组
                auto list = iter->second;
                iter = _listenerMap.erase(iter);
                CC_SAFE_DELETE(list);
            }
            //不是空的就往后遍历,如果是空的了,而且被删除了,就不用往后遍历了,迭代的当前的就是将要遍历到的
            else
            {
                ++iter;
            }
            
            //如果已经找到了,就直接break,不用再找了
            if (isFound)
                break;
        }
    
        //如果找到了,再release要移除的监听器
        if (isFound)
        {
            releaseListener(listener);
        }
        //如果没有找到,就遍历查找_toAddedListeners,如果有就暂停、release、移除
        //如果这里面也没有找到,也就是说已经没有这个监听器了
        else
        {
            for(auto iter = _toAddedListeners.begin(); iter != _toAddedListeners.end(); ++iter)
            {
                if (*iter == listener)
                {
                    listener->setRegistered(false);
                    releaseListener(listener);
                    _toAddedListeners.erase(iter);
                    break;
                }
            }
        }
    }
    
    //设置优先级
    void EventDispatcher::setPriority(EventListener* listener, int fixedPriority)
    {
        if (listener == nullptr)
            return;
        
        //遍历监听器表
        for (auto& iter : _listenerMap)
        {
            //获取当前监听器表中的 自定义优先级 监听器数组
            auto fixedPriorityListeners = iter.second->getFixedPriorityListeners();
            if (fixedPriorityListeners)
            {
                //查找 自定义优先级 监听器数组中是否存在这个形参的监听器
                auto found = std::find(fixedPriorityListeners->begin(), fixedPriorityListeners->end(), listener);
                //如果找到了
                if (found != fixedPriorityListeners->end())
                {
                    CCASSERT(listener->getAssociatedNode() == nullptr, "Can't set fixed priority with scene graph based listener.");
                    //并且优先级和现在想要设置的不同
                    if (listener->getFixedPriority() != fixedPriority)
                    {
                        //重新设置优先级
                        listener->setFixedPriority(fixedPriority);
                        //再设置自定义优先级脏标记
                        setDirty(listener->getListenerID(), DirtyFlag::FIXED_PRIORITY);
                    }
                    return;
                }
            }
            //为什么不遍历场景图优先级,是因为场景图优先级的优先级只能为0
        }
    }
    
    //分发事件
    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;
        //优先级小于0的监听器数组
        // priority < 0
        if (fixedPriorityListeners)
        {
            CCASSERT(listeners->getGt0Index() <= static_cast<ssize_t>(fixedPriorityListeners->size()), "Out of range exception!");
            
            //如果不是空的
            if (!fixedPriorityListeners->empty())
            {
                //遍历小于0的监听器,getGt0Index是获取小于0的监听器数量,在对小于0监听器排序的时候会设置
                for (; i < listeners->getGt0Index(); ++i)
                {
                    //遍历获取每一个优先级小于0的监听器
                    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;
                    }
                }
            }
        }
    }
    
    //分发触摸事件到监听器
    void EventDispatcher::dispatchTouchEventToListeners(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;
                    }
                }
            }
        }
        
        //获取当前运行的场景
        auto scene = Director::getInstance()->getRunningScene();
        if (scene && sceneGraphPriorityListeners)
        {
            if (!shouldStopPropagation)
            {
                // priority == 0, scene graph priority
                
                // first, get all enabled, unPaused and registered listeners
                //首先获取所有开启、不暂停、已注册的场景图优先级监听器数组,存在sceneListeners中
                std::vector<EventListener*> sceneListeners;
                for (auto& l : *sceneGraphPriorityListeners)
                {
                    if (l->isEnabled() && !l->isPaused() && l->isRegistered())
                    {
                        sceneListeners.push_back(l);
                    }
                }
                // second, for all camera call all listeners
                // get a copy of cameras, prevent it's been modified in listener callback
                // if camera's depth is greater, process it earlier
                auto cameras = scene->getCameras();
                for (auto rit = cameras.rbegin(), ritRend = cameras.rend(); rit != ritRend; ++rit)
                {
                    Camera* camera = *rit;
                    if (camera->isVisible() == false)
                    {
                        continue;
                    }
                    
                    Camera::_visitingCamera = camera;
                    auto cameraFlag = (unsigned short)camera->getCameraFlag();
                    for (auto& l : sceneListeners)
                    {
                        if (nullptr == l->getAssociatedNode() || 0 == (l->getAssociatedNode()->getCameraMask() & cameraFlag))
                        {
                            continue;
                        }
                        if (onEvent(l))
                        {
                            shouldStopPropagation = true;
                            break;
                        }
                    }
                    if (shouldStopPropagation)
                    {
                        break;
                    }
                }
                Camera::_visitingCamera = nullptr;
            }
        }
        
        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;
                    }
                }
            }
        }
    }
    
    void EventDispatcher::dispatchEvent(Event* event)
    {
        if (!_isEnabled)
            return;
        
        updateDirtyFlagForSceneGraph();
        
        DispatchGuard guard(_inDispatch);
        
        //如果是触摸事件,单独分发
        if (event->getType() == Event::Type::TOUCH)
        {
            dispatchTouchEvent(static_cast<EventTouch*>(event));
            return;
        }
        
        //获取监听器ID
        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())
        {
            auto listeners = iter->second;
            
            auto onEvent = [&event](EventListener* listener) -> bool{
                event->setCurrentTarget(listener->getAssociatedNode());
                listener->_onEvent(event);
                return event->isStopped();
            };
            
            (this->*pfnDispatchEventToListeners)(listeners, onEvent);
        }
        
        updateListeners(event);
    }
    
    void EventDispatcher::dispatchCustomEvent(const std::string &eventName, void *optionalUserData)
    {
        EventCustom ev(eventName);
        ev.setUserData(optionalUserData);
        dispatchEvent(&ev);
    }
    
    bool EventDispatcher::hasEventListener(const EventListener::ListenerID& listenerID) const
    {
        return getListeners(listenerID) != nullptr;
    }
    
    //分发触摸事件
    void EventDispatcher::dispatchTouchEvent(EventTouch* event)
    {
        //分别对两种
        sortEventListeners(EventListenerTouchOneByOne::LISTENER_ID);
        sortEventListeners(EventListenerTouchAllAtOnce::LISTENER_ID);
        
        //分别获取 单点监听器 和 多点监听器
        auto oneByOneListeners = getListeners(EventListenerTouchOneByOne::LISTENER_ID);
        auto allAtOnceListeners = getListeners(EventListenerTouchAllAtOnce::LISTENER_ID);
        
        // If there aren't any touch listeners, return directly.
        if (nullptr == oneByOneListeners && nullptr == allAtOnceListeners)
            return;
        
        bool isNeedsMutableSet = (oneByOneListeners && allAtOnceListeners);
        
        
        //为什么不直接对originalToucher操作?
        const std::vector<Touch*>& originalTouches = event->getTouches(); //获取原始的触摸数据
        std::vector<Touch*> mutableTouches(originalTouches.size()); //创建新的拷贝的数组
        std::copy(originalTouches.begin(), originalTouches.end(), mutableTouches.begin()); //拷贝
    
        //
        
        // process the target handlers 1st
        // 处理单点触摸
        if (oneByOneListeners)
        {
            //获取拷贝的触摸点数据的第一个
            auto mutableTouchesIter = mutableTouches.begin();
            
            //遍历触摸的原始数据
            for (auto& touches : originalTouches)
            {
                //吞没设为false,不同层次的也可以接收到触摸
                bool isSwallowed = false;
    
                //设置触摸事件的匿名函数
                auto onTouchEvent = [&](EventListener* l) -> bool { // Return true to break
                    //获取传递来的单点触摸监听器
                    EventListenerTouchOneByOne* listener = static_cast<EventListenerTouchOneByOne*>(l);
                    
                    //跳过没有注册的监听器
                    // Skip if the listener was removed.
                    if (!listener->_isRegistered)
                        return false;
                 
                    //设置当前target
                    event->setCurrentTarget(listener->_node);
                    
                    //设置是否已响应标记
                    bool isClaimed = false;
                    //
                    std::vector<Touch*>::iterator removedIter;
                    
                    //获取事件的触摸阶段
                    EventTouch::EventCode eventCode = event->getEventCode();
                    
                    //如果是开始阶段
                    if (eventCode == EventTouch::EventCode::BEGAN)
                    {
                        //并且监听器存在开始阶段的回调函数
                        if (listener->onTouchBegan)
                        {
                            //执行回调函数,并返回执行的结果
                            //可以在callback里面返回true or false,用来控制是否继续调用剩下的触摸步骤
                            isClaimed = listener->onTouchBegan(touches, event);
                            
                            //执行成功了并且已经注册了
                            if (isClaimed && listener->_isRegistered)
                            {
                                //加入到已响应触摸数组中
                                listener->_claimedTouches.push_back(touches);
                            }
                        }
                    }
                    //否则先判断是否有已响应的监听器、并查找是否已经响应过了
                    else if (listener->_claimedTouches.size() > 0
                             && ((removedIter = std::find(listener->_claimedTouches.begin(), listener->_claimedTouches.end(), touches)) != listener->_claimedTouches.end()))
                    {
                        //标记为已响应
                        isClaimed = true;
                        
                        //判断响应阶段类型
                        switch (eventCode)
                        {
                                //移动阶段
                            case EventTouch::EventCode::MOVED:
                                if (listener->onTouchMoved)
                                {
                                    listener->onTouchMoved(touches, event);
                                }
                                break;
                                //结束阶段
                            case EventTouch::EventCode::ENDED:
                                if (listener->onTouchEnded)
                                {
                                    listener->onTouchEnded(touches, event);
                                }
                                if (listener->_isRegistered)
                                {
                                    listener->_claimedTouches.erase(removedIter);
                                }
                                break;
                                //取消阶段
                            case EventTouch::EventCode::CANCELLED:
                                if (listener->onTouchCancelled)
                                {
                                    listener->onTouchCancelled(touches, event);
                                }
                                if (listener->_isRegistered)
                                {
                                    listener->_claimedTouches.erase(removedIter);
                                }
                                break;
                            default:
                                CCASSERT(false, "The eventcode is invalid.");
                                break;
                        }
                    }
                    
                    // If the event was stopped, return directly.
                    //如果事件暂停了,刷新监听器数组
                    if (event->isStopped())
                    {
                        updateListeners(event);
                        return true;
                    }
                    
                    CCASSERT(touches->getID() == (*mutableTouchesIter)->getID(),
                             "touches ID should be equal to mutableTouchesIter's ID.");
                    
                    //如果已经分发了、注册了、需要吞没
                    if (isClaimed && listener->_isRegistered && listener->_needSwallow)
                    {
                        //如果单点和多点都存在,就移除当前的触摸数据,吞没设为true
                        if (isNeedsMutableSet)
                        {
                            mutableTouchesIter = mutableTouches.erase(mutableTouchesIter);
                            isSwallowed = true;
                        }
                        return true;
                    }
                    
                    return false;
                };
                
                //分发单点触摸事件
                dispatchTouchEventToListeners(oneByOneListeners, onTouchEvent);
                //暂停直接返回
                if (event->isStopped())
                {
                    return;
                }
                
                //没有吞没就往后迭代
                if (!isSwallowed)
                    ++mutableTouchesIter;
            }
        }
        
        //
        // process standard handlers 2nd
        //
        //单点处理完之后,还存在多点触控,并且有触摸数据
        if (allAtOnceListeners && mutableTouches.size() > 0)
        {
            
            auto onTouchesEvent = [&](EventListener* l) -> bool{
                //获取多点监听器
                EventListenerTouchAllAtOnce* listener = static_cast<EventListenerTouchAllAtOnce*>(l);
                // Skip if the listener was removed.
                //没注册就返回
                if (!listener->_isRegistered)
                    return false;
                
                //设置当前的节点
                event->setCurrentTarget(listener->_node);
                
                //判断触摸阶段
                switch (event->getEventCode())
                {
                    case EventTouch::EventCode::BEGAN:
                        if (listener->onTouchesBegan)
                        {
                            listener->onTouchesBegan(mutableTouches, event);
                        }
                        break;
                    case EventTouch::EventCode::MOVED:
                        if (listener->onTouchesMoved)
                        {
                            listener->onTouchesMoved(mutableTouches, event);
                        }
                        break;
                    case EventTouch::EventCode::ENDED:
                        if (listener->onTouchesEnded)
                        {
                            listener->onTouchesEnded(mutableTouches, event);
                        }
                        break;
                    case EventTouch::EventCode::CANCELLED:
                        if (listener->onTouchesCancelled)
                        {
                            listener->onTouchesCancelled(mutableTouches, event);
                        }
                        break;
                    default:
                        CCASSERT(false, "The eventcode is invalid.");
                        break;
                }
                
                // If the event was stopped, return directly.
                if (event->isStopped())
                {
                    //刷新监听器
                    updateListeners(event);
                    return true;
                }
                
                return false;
            };
            
            //分发多点触摸事件
            dispatchTouchEventToListeners(allAtOnceListeners, onTouchesEvent);
            //如果是暂停了就返回
            if (event->isStopped())
            {
                return;
            }
        }
        
        //刷洗监听器数组
        updateListeners(event);
    }
    
    //刷新监听器数组
    //1、删除已移除的监听器
    //2、添加未添加的监听器
    void EventDispatcher::updateListeners(Event* event)
    {
        CCASSERT(_inDispatch > 0, "If program goes here, there should be event in dispatch.");
    
        if (_inDispatch > 1)
            return;
        
        //定义刷新监听器的匿名函数
        auto onUpdateListeners = [this](const EventListener::ListenerID& listenerID)
        {
            //在监听器表中找到listenerID对应的键值对
            auto listenersIter = _listenerMap.find(listenerID);
            if (listenersIter == _listenerMap.end())
                return;
    
            //获取listenerID对应的监听器数组
            auto listeners = listenersIter->second;
            
            //获取不同优先级的监听器数组
            auto fixedPriorityListeners = listeners->getFixedPriorityListeners();
            auto sceneGraphPriorityListeners = listeners->getSceneGraphPriorityListeners();
            
            //如果存在场景图优先级的监听器数组
            if (sceneGraphPriorityListeners)
            {
                //遍历监听器数组
                for (auto iter = sceneGraphPriorityListeners->begin(); iter != sceneGraphPriorityListeners->end();)
                {
                    auto l = *iter;
                    
                    //如果没有注册
                    //1、从listenerID对应的监听器数组中的场景图优先级数组中移除
                    //2、从toRemovedListeners中移除
                    //3、release释放
                    if (!l->isRegistered())
                    {
                        iter = sceneGraphPriorityListeners->erase(iter);
                        // if item in toRemove list, remove it from the list
                        auto matchIter = std::find(_toRemovedListeners.begin(), _toRemovedListeners.end(), l);
                        if (matchIter != _toRemovedListeners.end())
                            _toRemovedListeners.erase(matchIter);
                        releaseListener(l);
                    }
                    //否则遍历下一个
                    else
                    {
                        ++iter;
                    }
                }
            }
            
            //和场景图优先级监听器数组一样
            if (fixedPriorityListeners)
            {
                for (auto iter = fixedPriorityListeners->begin(); iter != fixedPriorityListeners->end();)
                {
                    auto l = *iter;
                    if (!l->isRegistered())
                    {
                        iter = fixedPriorityListeners->erase(iter);
                        // if item in toRemove list, remove it from the list
                        auto matchIter = std::find(_toRemovedListeners.begin(), _toRemovedListeners.end(), l);
                        if (matchIter != _toRemovedListeners.end())
                            _toRemovedListeners.erase(matchIter);
                        releaseListener(l);
                    }
                    else
                    {
                        ++iter;
                    }
                }
            }
            
            //如果删除完之后这两个优先级数组存在并且已经是空的了,就将数组clear(置空)
            if (sceneGraphPriorityListeners && sceneGraphPriorityListeners->empty())
            {
                listeners->clearSceneGraphListeners();
            }
    
            if (fixedPriorityListeners && fixedPriorityListeners->empty())
            {
                listeners->clearFixedListeners();
            }
        };
    
        //如果事件的类型是触摸类型
        if (event->getType() == Event::Type::TOUCH)
        {
            //分类别 单点和多点监听事件监听器
            onUpdateListeners(EventListenerTouchOneByOne::LISTENER_ID);
            onUpdateListeners(EventListenerTouchAllAtOnce::LISTENER_ID);
        }
        //除触摸类型外的事件监听器类型
        else
        {
            onUpdateListeners(__getListenerID(event));
        }
        
        CCASSERT(_inDispatch == 1, "_inDispatch should be 1 here.");
        
        //遍历监听器数组
        for (auto iter = _listenerMap.begin(); iter != _listenerMap.end();)
        {
            //如果没有listenerID对应的监听器数组是空的
            if (iter->second->empty())
            {
                _priorityDirtyFlagMap.erase(iter->first);//从ID优先级map中删除这个iter的ID
                delete iter->second; //删除ID对应的监听器数组,只删除指向内容,指针不删除
                iter = _listenerMap.erase(iter);//从listener中移除这个iter
            //删除之后不用往后递增是因为删除之后,iter已经指向下一个了
            }
            //如果不是空的,就遍历下一个
            else
            {
                ++iter;
            }
        }
        
        //如果_toAddedListeners不是空的
        if (!_toAddedListeners.empty())
        {
            //遍历、逐个添加
            for (auto& listener : _toAddedListeners)
            {
                forceAddEventListener(listener);
            }
            //添加完清空
            _toAddedListeners.clear();
        }
    
        //因为上面将未注册的监听器从_toRemovedListeners删除了,是因为在removeEventListenersForListenerID中把移除的监听器的isRegistered设为了false,如果这时_toRemovedListeners不是空,清理就行了,正常来说应该是空的了。
        if (!_toRemovedListeners.empty())
        {
            cleanToRemovedListeners();
        }
    }
    
    //刷新脏节点标记
    void EventDispatcher::updateDirtyFlagForSceneGraph()
    {
        
        if (!_dirtyNodes.empty())
        {
            //遍历脏节点容器
            for (auto& node : _dirtyNodes)
            {
                //从_nodeListenersMap中找到对应的键值对
                auto iter = _nodeListenersMap.find(node);
                //如果找到了
                if (iter != _nodeListenersMap.end())
                {
                    //遍历获取和节点绑定的监听器数组
                    for (auto& l : *iter->second)
                    {
                        //设置当前节点的脏标记为场景图优先级标记
                        setDirty(l->getListenerID(), DirtyFlag::SCENE_GRAPH_PRIORITY);
                    }
                }
            }
            
            //清理脏节点标记数组
            _dirtyNodes.clear();
        }
    }
    
    //对监听器数组排序
    void EventDispatcher::sortEventListeners(const EventListener::ListenerID& listenerID)
    {
        //初始化优先级脏标记
        DirtyFlag dirtyFlag = DirtyFlag::NONE;
        
        //从listenerID-优先级 map获取参数中的优先级
        auto dirtyIter = _priorityDirtyFlagMap.find(listenerID);
        //如果找到了
        if (dirtyIter != _priorityDirtyFlagMap.end())
        {
            //获取对应的优先级脏标记
            dirtyFlag = dirtyIter->second;
        }
        
        //优先级不是默认优先级
        if (dirtyFlag != DirtyFlag::NONE)
        {
            // Clear the dirty flag first, if `rootNode` is nullptr, then set its dirty flag of scene graph priority
            //先清理旧的脏标记
            dirtyIter->second = DirtyFlag::NONE;
    
            //如果是自定义的优先级
            if ((int)dirtyFlag & (int)DirtyFlag::FIXED_PRIORITY)
            {
                //排序,统计
                sortEventListenersOfFixedPriority(listenerID);
            }
            //如果是场景图的优先级
            if ((int)dirtyFlag & (int)DirtyFlag::SCENE_GRAPH_PRIORITY)
            {
                //获取当前场景
                auto rootNode = Director::getInstance()->getRunningScene();
                //获取到了
                if (rootNode)
                {
                    //排序场景图
                    sortEventListenersOfSceneGraphPriority(listenerID, rootNode);
                }
                else
                {
                    //刷新监听器的脏标记
                    dirtyIter->second = DirtyFlag::SCENE_GRAPH_PRIORITY;
                }
            }
        }
    }
    
    //对场景图优先级的监听器排序
    void EventDispatcher::sortEventListenersOfSceneGraphPriority(const EventListener::ListenerID& listenerID, Node* rootNode)
    {
        //获取listenerID对应的监听器数组
        auto listeners = getListeners(listenerID);
        
        if (listeners == nullptr)
            return;
        //获取监听器数组中的场景图优先级数组
        auto sceneGraphListeners = listeners->getSceneGraphPriorityListeners();
        
        if (sceneGraphListeners == nullptr)
            return;
        
        //初始化节点优先级个数
        // Reset priority index
        _nodePriorityIndex = 0;
        _nodePriorityMap.clear();
    
        //遍历节点
        visitTarget(rootNode, true);
        
        // After sort: priority < 0, > 0
        std::stable_sort(sceneGraphListeners->begin(), sceneGraphListeners->end(), [this](const EventListener* l1, const EventListener* l2) {
            return _nodePriorityMap[l1->getAssociatedNode()] > _nodePriorityMap[l2->getAssociatedNode()];
        });
        
    #if DUMP_LISTENER_ITEM_PRIORITY_INFO
        log("-----------------------------------");
        for (auto& l : *sceneGraphListeners)
        {
            log("listener priority: node ([%s]%p), priority (%d)", typeid(*l->_node).name(), l->_node, _nodePriorityMap[l->_node]);
        }
    #endif
    }
    
    //对自定义优先级的监听器排序
    void EventDispatcher::sortEventListenersOfFixedPriority(const EventListener::ListenerID& listenerID)
    {
        auto listeners = getListeners(listenerID);
    
        if (listeners == nullptr)
            return;
        
        auto fixedListeners = listeners->getFixedPriorityListeners();
        if (fixedListeners == nullptr)
            return;
        
        // After sort: priority < 0, > 0
        //排序
        std::stable_sort(fixedListeners->begin(), fixedListeners->end(), [](const EventListener* l1, const EventListener* l2) {
            return l1->getFixedPriority() < l2->getFixedPriority();
        });
        
        // FIXME: Should use binary search
        int index = 0;
        //统计优先级小于0的监听器个数
        for (auto& listener : *fixedListeners)
        {
            if (listener->getFixedPriority() >= 0)
                break;
            ++index;
        }
        
        //设置优先级小于0的监听器个数
        listeners->setGt0Index(index);
        
    #if DUMP_LISTENER_ITEM_PRIORITY_INFO
        log("-----------------------------------");
        
        for (auto& l : *fixedListeners)
        {
            log("listener priority: node (%p), fixed (%d)", l->_node, l->_fixedPriority);
        }    
    #endif
        
    }
    
    //获取listenerID对应的监听器数组
    EventDispatcher::EventListenerVector* EventDispatcher::getListeners(const EventListener::ListenerID& listenerID) const
    {
        auto iter = _listenerMap.find(listenerID);
        if (iter != _listenerMap.end())
        {
            return iter->second;
        }
        
        return nullptr;
    }
    
    //通过listenerID移除对应的监听器数组
    void EventDispatcher::removeEventListenersForListenerID(const EventListener::ListenerID& listenerID)
    {
        //先获取listenerID对应的监听器数组
        auto listenerItemIter = _listenerMap.find(listenerID);
        //如果找到了
        if (listenerItemIter != _listenerMap.end())
        {
            auto listeners = listenerItemIter->second; //获取listenerID对应的监听器数组
            //获取不同优先级的监听器数组
            auto fixedPriorityListeners = listeners->getFixedPriorityListeners();
            auto sceneGraphPriorityListeners = listeners->getSceneGraphPriorityListeners();
            
            //定义移除监听器的匿名函数
            auto removeAllListenersInVector = [&](std::vector<EventListener*>* listenerVector){
                if (listenerVector == nullptr)
                    return;
                
                for (auto iter = listenerVector->begin(); iter != listenerVector->end();)
                {
                    auto l = *iter;
                    l->setRegistered(false);
                    if (l->getAssociatedNode() != nullptr)
                    {
                        dissociateNodeAndEventListener(l->getAssociatedNode(), l);
                        l->setAssociatedNode(nullptr);  // nullptr out the node pointer so we don't have any dangling pointers to destroyed nodes.
                    }
                    
                    if (_inDispatch == 0)
                    {
                        iter = listenerVector->erase(iter);
                        releaseListener(l);
                    }
                    else
                    {
                        ++iter;
                    }
                }
            };
            
            //分别移除不同优先级的监听器
            removeAllListenersInVector(sceneGraphPriorityListeners);
            removeAllListenersInVector(fixedPriorityListeners);
            
            // Remove the dirty flag according the 'listenerID'.
            // No need to check whether the dispatcher is dispatching event.
            _priorityDirtyFlagMap.erase(listenerID);
            
            //如果没有在调用
            if (!_inDispatch)
            {
                //清理监听器数组
                listeners->clear();
                //删除指向的对象
                delete listeners;
                //移除当前监听器数组
                _listenerMap.erase(listenerItemIter);
            }
        }
        
        //遍历待添加数组
        for (auto iter = _toAddedListeners.begin(); iter != _toAddedListeners.end();)
        {
            //如果找到了和要移除的监听器ID相同的
            if ((*iter)->getListenerID() == listenerID)
            {
                (*iter)->setRegistered(false);  //注册设为false
                releaseListener(*iter); //release监听器
                iter = _toAddedListeners.erase(iter); //从待添加数组中移除
            }
            else
                //这里++是为了往后递归,上面为什么不往后递归是因为移除之后,数组后面的元素就往前挪了
            {
                ++iter;
            }
        }
    }
    
    //按不同的监听器类型移除,即listenerID
    void EventDispatcher::removeEventListenersForType(EventListener::Type listenerType)
    {
        if (listenerType == EventListener::Type::TOUCH_ONE_BY_ONE)
        {
            removeEventListenersForListenerID(EventListenerTouchOneByOne::LISTENER_ID);
        }
        else if (listenerType == EventListener::Type::TOUCH_ALL_AT_ONCE)
        {
            removeEventListenersForListenerID(EventListenerTouchAllAtOnce::LISTENER_ID);
        }
        else if (listenerType == EventListener::Type::MOUSE)
        {
            removeEventListenersForListenerID(EventListenerMouse::LISTENER_ID);
        }
        else if (listenerType == EventListener::Type::ACCELERATION)
        {
            removeEventListenersForListenerID(EventListenerAcceleration::LISTENER_ID);
        }
        else if (listenerType == EventListener::Type::KEYBOARD)
        {
            removeEventListenersForListenerID(EventListenerKeyboard::LISTENER_ID);
        }
        else
        {
            CCASSERT(false, "Invalid listener type!");
        }
    }
    
    //移除自定义的监听器
    void EventDispatcher::removeCustomEventListeners(const std::string& customEventName)
    {
        removeEventListenersForListenerID(customEventName);
    }
    
    //移除所有的监听器
    void EventDispatcher::removeAllEventListeners()
    {
        
        bool cleanMap = true;
        std::vector<EventListener::ListenerID> types;
        types.reserve(_listenerMap.size());
        
        //遍历监听器map
        for (const auto& e : _listenerMap)
        {
            //查找自定义监听器中是否相同的ID
            if (_internalCustomListenerIDs.find(e.first) != _internalCustomListenerIDs.end())
            {
                cleanMap = false;
            }
            //加入到types中
            else
            {
                types.push_back(e.first);
            }
        }
    
        //循环listenerMap中存在的listenerID
        for (const auto& type : types)
        {
            //逐个移除
            removeEventListenersForListenerID(type);
        }
        
        //没有在调度,并且没有相同ID的自定义监听器
        if (!_inDispatch && cleanMap)
        {
            //清理监听器Map
            _listenerMap.clear();
        }
    }
    
    //设置开启
    void EventDispatcher::setEnabled(bool isEnabled)
    {
        _isEnabled = isEnabled;
    }
    
    //返回是否开启
    bool EventDispatcher::isEnabled() const
    {
        return _isEnabled;
    }
    
    //设置节点脏标记(监听器优先级)
    void EventDispatcher::setDirtyForNode(Node* node)
    {
        // Mark the node dirty only when there is an eventlistener associated with it.
        //当有节点和关联的监听器时才会标记
        if (_nodeListenersMap.find(node) != _nodeListenersMap.end())
        {
            //添加进脏节点数组
            _dirtyNodes.insert(node);
        }
    
        // Also set the dirty flag for node's children
        const auto& children = node->getChildren();
        for (const auto& child : children)
        {
            setDirtyForNode(child);
        }
    }
    
    void EventDispatcher::setDirty(const EventListener::ListenerID& listenerID, DirtyFlag flag)
    {    
        auto iter = _priorityDirtyFlagMap.find(listenerID);
        if (iter == _priorityDirtyFlagMap.end())
        {
            _priorityDirtyFlagMap.emplace(listenerID, flag);
        }
        else
        {
            int ret = (int)flag | (int)iter->second;
            iter->second = (DirtyFlag) ret;
        }
    }
    
    //清理待移除监听器数组
    void EventDispatcher::cleanToRemovedListeners()
    {
        //遍历待移除监听器数组
        for (auto& l : _toRemovedListeners)
        {
            //查找待移除监听器数组中监听器ID在listener中对应的元素
            auto listenersIter = _listenerMap.find(l->getListenerID());
            //如果没找到
            if (listenersIter == _listenerMap.end())
            {
                //释放
                releaseListener(l);
                continue;
            }
    
            bool find = false;   //标记为 未找到
            auto listeners = listenersIter->second;  //获取监听器ID对应的监听器数组
            //获取不同优先级的监听器数组
            auto fixedPriorityListeners = listeners->getFixedPriorityListeners();
            auto sceneGraphPriorityListeners = listeners->getSceneGraphPriorityListeners();
    
            if (sceneGraphPriorityListeners)
            {
                //查找监听器l
                auto machedIter = std::find(sceneGraphPriorityListeners->begin(), sceneGraphPriorityListeners->end(), l);
                //如果找到了
                if (machedIter != sceneGraphPriorityListeners->end())
                {
                    find = true; //标记为 找到了
                    releaseListener(l); //释放l
                    sceneGraphPriorityListeners->erase(machedIter); //从场景图优先级数组中也删除
                }
            }
            //过程同上
            if (fixedPriorityListeners)
            {
                auto machedIter = std::find(fixedPriorityListeners->begin(), fixedPriorityListeners->end(), l);
                if (machedIter != fixedPriorityListeners->end())
                {
                    find = true;
                    releaseListener(l);
                    fixedPriorityListeners->erase(machedIter);
                }
            }
    
            //如果删掉了并且两个优先级的监听器数组都是空的,就清理一下(指针指向置空)
            if (find)
            {
                if (sceneGraphPriorityListeners && sceneGraphPriorityListeners->empty())
                {
                    listeners->clearSceneGraphListeners();
                }
    
                if (fixedPriorityListeners && fixedPriorityListeners->empty())
                {
                    listeners->clearFixedListeners();
                }
            }
            //没找到 release监听器l
            else
                CC_SAFE_RELEASE(l);
        }
    
        //清理待移除数组
        _toRemovedListeners.clear();
    }
    
    //release接口
    void EventDispatcher::releaseListener(EventListener* listener)
    {
    #if CC_ENABLE_GC_FOR_NATIVE_OBJECTS
        auto sEngine = ScriptEngineManager::getInstance()->getScriptEngine();
        if (listener && sEngine)
        {
            sEngine->releaseScriptObject(this, listener);
        }
    #endif // CC_ENABLE_GC_FOR_NATIVE_OBJECTS
        CC_SAFE_RELEASE(listener);
    }
    
    NS_CC_END
    
    
  • 相关阅读:
    模块二 GO语言进阶技术-panic函数、recover函数以及defer语句(上)
    模块二 GO语言进阶技术-错误处理(下)
    模块二 GO语言进阶技术-错误处理(上)
    模块二 GO语言进阶技术-if语句、for语句和switch语句
    模块二 GO语言进阶技术-GO语句及其执行规则(下)
    模块二 GO语言进阶技术-go语句及其执行规则(上)
    模块二 GO语言进阶技术-关于指针的有限操作
    模块二 GO语言进阶技术-接口类型的合理运用
    模块二 GO语言进阶技术-结构体及其方法的使用法门
    模块二 GO语言进阶技术-使用函数的正确姿势
  • 原文地址:https://www.cnblogs.com/sakuraneo/p/11992048.html
Copyright © 2020-2023  润新知