首先我要说明的是两个非常非常重要的变量。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。
- size_t EventDispatcher::EventListenerVector::size() const
- {
- //vector内部的size大小是两个list的和
- size_t ret = 0;
- if (_sceneGraphListeners)
- ret += _sceneGraphListeners->size();
- if (_fixedListeners)
- ret += _fixedListeners->size();
- return ret;
- }
- void EventDispatcher::EventListenerVector::push_back(EventListener* listener)
- {
- //查看listener的priority,如果为0,加入sceneGraphList,否则加入fixedList
- if (listener->getFixedPriority() == 0)
- {
- if (_sceneGraphListeners == nullptr)
- {
- _sceneGraphListeners = new 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);
- }
- }
上面两个函数是与一般Vector不一样的地方,需要注意的地方我已经标注了注释。
3.2 Add操作
既然是一个类似于Manager的类,那就先从Add操作开始吧。
三种事件的添加方式:
3.2.1 sceneGraph类
- void EventDispatcher::addEventListenerWithSceneGraphPriority(EventListener* listener, Node* node)
- {
- CCASSERT(listener && node, "Invalid parameters.");
- CCASSERT(!listener->isRegistered(), "The listener has been registered.");
- //检查Listener可用性
- if (!listener->checkAvailable())
- return;
- //设置listener相关属性
- listener->setAssociatedNode(node);
- listener->setFixedPriority(0);
- listener->setRegistered(true);
- addEventListener(listener);
- }
3.2.2 fixed类
- void EventDispatcher::addEventListenerWithFixedPriority(EventListener* listener, int fixedPriority)
- {
- CCASSERT(listener, "Invalid parameters.");
- //一个事件只能被注册一次
- CCASSERT(!listener->isRegistered(), "The listener has been registered.");
- //Fixed类型的事件优先级不能是0
- 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);
- }
3.2.3 custom类
- EventListenerCustom* EventDispatcher::addCustomEventListener(const std::string &eventName, const std::function<void(EventCustom*)>& callback)
- {
- //custom类的事件添加是通过eventName 和 eventcallBack来进行添加的
- EventListenerCustom *listener = EventListenerCustom::create(eventName, callback);
- //custom的事件优先级被默认为1
- addEventListenerWithFixedPriority(listener, 1);
- return listener;
- }
可以看出,添加函数最后都用到了一个函数addEventListener,下面对其进行剖析(这个函数又用到了其他函数,又,又,又。。。。。。)
3.2.4 addEventListener
- void EventDispatcher::addEventListener(EventListener* listener)
- {
- //如果当前Dispatcher正在进行事件Dispatch,则放到toAddList中。
- if (_inDispatch == 0)
- {
- forceAddEventListener(listener);
- }
- else
- {
- // std::vector
- _toAddedListeners.push_back(listener);
- }
- listener->retain();
- }
3.2.5 forceAddEventListener
- void EventDispatcher::forceAddEventListener(EventListener* listener)
- {
- EventListenerVector* listeners = nullptr;
- EventListener::ListenerID listenerID = listener->getListenerID();
- //找到该类eventlistener的vector,此处的vector是EventVector
- auto itr = _listenerMap.find(listenerID);
- //如果没有找到,则需要向map中添加一个pair
- if (itr == _listenerMap.end())
- {
- listeners = new EventListenerVector();
- _listenerMap.insert(std::make_pair(listenerID, listeners));
- }
- else
- {
- listeners = itr->second;
- }
- //将该类别listenerpush_back进去(这个函数调用的是EventVector的pushback哦)
- listeners->push_back(listener);
- //如果优先级是0,则设置为graph。
- if (listener->getFixedPriority() == 0)
- {
- //设置该listenerID的DirtyFlag
- //(setDirty函数可以这样理解,每个ListenerID都有特定的dirtyFlag,每次进行add操作后,都要更新该ID的flag)
- setDirty(listenerID, DirtyFlag::SCENE_GRAPH_PRIORITY);
- //如果是sceneGraph类的事件,则需要处理两个方面:
- //1.将node 与event 关联
- //2.如果该node是运行中的,则需要恢复其事件(因为默认的sceneGraph listener的状态时pause)
- //增加该listener与node的关联
- auto node = listener->getAssociatedNode();
- CCASSERT(node != nullptr, "Invalid scene graph priority!");
- associateNodeAndEventListener(node, listener);
- //恢复node的运行状态
- if (node->isRunning())
- {
- resumeEventListenersForTarget(node);
- }
- }
- else
- {
- setDirty(listenerID, DirtyFlag::FIXED_PRIORITY);
- }
- }
3.2.6associateNodeAndEventListener
- void EventDispatcher::associateNodeAndEventListener(Node* node, EventListener* listener)
- {
- //将listener与node关联,先从map中找到与该node相关的listener vector
- std::vector<EventListener*>* listeners = nullptr;
- auto found = _nodeListenersMap.find(node);
- if (found != _nodeListenersMap.end())
- {
- listeners = found->second;
- }
- else
- {
- listeners = new std::vector<EventListener*>();
- _nodeListenersMap.insert(std::make_pair(node, listeners));
- }
- //vector内添加该listener,这里的vector 是std::vector
- listeners->push_back(listener);
- }
3.2.7 removeEventListenersForTarget
- void EventDispatcher::resumeEventListenersForTarget(Node* target, bool recursive/* = false */)
- {
- //恢复Node的运行状态
- auto listenerIter = _nodeListenersMap.find(target);
- if (listenerIter != _nodeListenersMap.end())
- {
- auto listeners = listenerIter->second;
- for (auto& l : *listeners)
- {
- l->setPaused(false);
- }
- }
- // toAdd List中也要进行恢复
- for (auto& listener : _toAddedListeners)
- {
- if (listener->getAssociatedNode() == target)
- {
- listener->setPaused(false);
- }
- }
- //将该Node 与 node的child 都放到dirtyNode中,来记录与event相关的node
- setDirtyForNode(target);
- if (recursive)
- {
- const auto& children = target->getChildren();
- for (const auto& child : children)
- {
- resumeEventListenersForTarget(child, true);
- }
- }
- }
3.3 Remove
看完了Add,当然要讲remove
3.3.1 removeEventListener
- void EventDispatcher::removeEventListener(EventListener* listener)
- {
- //说在前面,移除一个事件的代价比较大,如果没有必要,请不要无故移除事件。
- //删除一个listener的步骤:
- if (listener == nullptr)
- return;
- bool isFound = false;
- //lambda函数,函数从std::vector<EventListener*>* listeners 中移除该listener
- 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)
- {
- //找到后的处理方法,标记状态位,并处理关联Node
- CC_SAFE_RETAIN(l);
- l->setRegistered(false);
- if (l->getAssociatedNode() != nullptr)
- {
- dissociateNodeAndEventListener(l->getAssociatedNode(), l);
- l->setAssociatedNode(nullptr); // NULL out the node pointer so we don't have any dangling pointers to destroyed nodes.
- }
- //当前没有在分发事件 则直接从listeners中移除该listener(因为标记了状态未,如果此时在分发事件,则会等结束后再移除)
- if (_inDispatch == 0)
- {
- listeners->erase(iter);
- CC_SAFE_RELEASE(l);
- }
- isFound = true;
- break;
- }
- }
- };
- for (auto iter = _listenerMap.begin(); iter != _listenerMap.end();)
- {
- //从listenersmap 中遍历所有,拿出所有的vector
- auto listeners = iter->second;
- auto fixedPriorityListeners = listeners->getFixedPriorityListeners();
- auto sceneGraphPriorityListeners = listeners->getSceneGraphPriorityListeners();
- //从graphList中寻找。找到后需要更新该listenerID的dirty flag。
- removeListenerInVector(sceneGraphPriorityListeners);
- if (isFound)
- {
- // fixed #4160: Dirty flag need to be updated after listeners were removed.
- setDirty(listener->getListenerID(), DirtyFlag::SCENE_GRAPH_PRIORITY);
- }
- //从fixedList中寻找
- else
- {
- removeListenerInVector(fixedPriorityListeners);
- if (isFound)
- {
- setDirty(listener->getListenerID(), DirtyFlag::FIXED_PRIORITY);
- }
- }
- //如果vector在删除后是空的,则需要移除该vector,并且将相应的listenerID从_priorityDirtyFlagMap中移除。
- if (iter->second->empty())
- {
- _priorityDirtyFlagMap.erase(listener->getListenerID());
- auto list = iter->second;
- iter = _listenerMap.erase(iter);
- CC_SAFE_DELETE(list);
- }
- else
- {
- ++iter;
- }
- if (isFound)
- break;
- }
- if (isFound)
- {
- CC_SAFE_RELEASE(listener);
- }
- //如果在上述过程中未找到,则从toAddList中寻找
- else
- {
- for(auto iter = _toAddedListeners.begin(); iter != _toAddedListeners.end(); ++iter)
- {
- if (*iter == listener)
- {
- listener->setRegistered(false);
- listener->release();
- _toAddedListeners.erase(iter);
- break;
- }
- }
- }
- }
3.3.2 removeEventListenersForListenerID
- void EventDispatcher::removeEventListenersForListenerID(const EventListener::ListenerID& listenerID)
- {
- auto listenerItemIter = _listenerMap.find(listenerID);
- if (listenerItemIter != _listenerMap.end())
- {
- auto listeners = listenerItemIter->second;
- auto fixedPriorityListeners = listeners->getFixedPriorityListeners();
- auto sceneGraphPriorityListeners = listeners->getSceneGraphPriorityListeners();
- //啊哦 又是一个lambda函数,将std::vector<EventListener*>* listenerVector中的Listener全部移除
- auto removeAllListenersInVector = [&](std::vector<EventListener*>* listenerVector){
- if (listenerVector == nullptr)
- return;
- for (auto iter = listenerVector->begin(); iter != listenerVector->end();)
- {
- //设置要删除的listener状态,清空与其相关的node信息
- auto l = *iter;
- l->setRegistered(false);
- if (l->getAssociatedNode() != nullptr)
- {
- dissociateNodeAndEventListener(l->getAssociatedNode(), l);
- l->setAssociatedNode(nullptr); // NULL out the node pointer so we don't have any dangling pointers to destroyed nodes.
- }
- if (_inDispatch == 0)
- {
- iter = listenerVector->erase(iter);
- CC_SAFE_RELEASE(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);
- }
- }
- //toAddList 的清理,真可怜,还没来得及进入家门就要被扫地出门了么。。。。
- for (auto iter = _toAddedListeners.begin(); iter != _toAddedListeners.end();)
- {
- if ((*iter)->getListenerID() == listenerID)
- {
- (*iter)->setRegistered(false);
- (*iter)->release();
- iter = _toAddedListeners.erase(iter);
- }
- else
- {
- ++iter;
- }
- }
- }
与其相关的两个remove函数
- 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);
- }
3.3.3 removeAllEventListeners
- void EventDispatcher::removeAllEventListeners()
- {
- bool cleanMap = true;
- std::vector<EventListener::ListenerID> types(_listenerMap.size());
- for (const auto& e : _listenerMap)
- {
- if (_internalCustomListenerIDs.find(e.first) != _internalCustomListenerIDs.end())
- {
- cleanMap = false;
- }
- else
- {
- types.push_back(e.first);
- }
- }
- for (const auto& type : types)
- {
- removeEventListenersForListenerID(type);
- }
- if (!_inDispatch && cleanMap)
- {
- _listenerMap.clear();
- }
- }
最新回复 (0)