void EventDispatcher::cleanToRemovedListeners() { for (auto& l : _toRemovedListeners) { auto listenersIter = _listenerMap.find(l->getListenerID()); if (listenersIter == _listenerMap.end()) { releaseListener(l); continue; } bool find = false; auto listeners = listenersIter->second; auto fixedPriorityListeners = listeners->getFixedPriorityListeners(); auto sceneGraphPriorityListeners = listeners->getSceneGraphPriorityListeners(); if (sceneGraphPriorityListeners) { auto machedIter = std::find(sceneGraphPriorityListeners->begin(), sceneGraphPriorityListeners->end(), l); if (machedIter != sceneGraphPriorityListeners->end()) { find = true; releaseListener(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(); } } else CC_SAFE_RELEASE(l); } _toRemovedListeners.clear(); }
void EventDispatcher::EventListenerVector::clear() { clearSceneGraphListeners(); clearFixedListeners(); }
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) { auto listenersIter = _listenerMap.find(listenerID); if (listenersIter == _listenerMap.end()) return; 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; 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; } } } 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();) { if (iter->second->empty()) { _priorityDirtyFlagMap.erase(iter->first); delete iter->second; iter = _listenerMap.erase(iter); } else { ++iter; } } if (!_toAddedListeners.empty()) { for (auto& listener : _toAddedListeners) { forceAddEventListener(listener); } _toAddedListeners.clear(); } if (!_toRemovedListeners.empty()) { cleanToRemovedListeners(); } }
void EventDispatcher::updateListeners(Event* event) { auto onUpdateListeners = [this](const EventListener::ListenerID& listenerID) { auto listenersIter = _listeners.find(listenerID); if (listenersIter == _listeners.end()) return; 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; if (!l->isRegistered()) { iter = sceneGraphPriorityListeners->erase(iter); l->release(); } else { ++iter; } } } if (fixedPriorityListeners) { for (auto iter = fixedPriorityListeners->begin(); iter != fixedPriorityListeners->end();) { auto l = *iter; if (!l->isRegistered()) { iter = fixedPriorityListeners->erase(iter); l->release(); } else { ++iter; } } } if (sceneGraphPriorityListeners && sceneGraphPriorityListeners->empty()) { listeners->clearSceneGraphListeners(); } if (fixedPriorityListeners && fixedPriorityListeners->empty()) { listeners->clearFixedListeners(); } if (listenersIter->second->empty()) { _priorityDirtyFlagMap.erase(listenersIter->first); delete listenersIter->second; _listeners.erase(listenersIter); } }; if (event->getType() == Event::Type::TOUCH) { onUpdateListeners(EventListenerTouchOneByOne::LISTENER_ID); onUpdateListeners(EventListenerTouchAllAtOnce::LISTENER_ID); } else { onUpdateListeners(__getListenerID(event)); } if (!_toAddedListeners.empty()) { for (auto& listener : _toAddedListeners) { forceAddEventListener(listener); } _toAddedListeners.clear(); } }