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

从零开始のcocos2dx生活(六)EventDispatcher的更多相关文章

  1. 从零开始のcocos2dx生活(七)ParticleSystem

    CCParticleSystem是用来设置粒子效果的类 1.粒子分为两种模式:重力模式 和 半径模式 重力模式独占属性: gravity 重力方向,Vec2类型,可以分别指定不同方向的重力大小 spe ...

  2. 从零开始のcocos2dx生活(二)Node

    节点 Node 文章目录 节点 Node 前言 变量初始化 创建一个节点对象 获取节点依赖的计数器 获取节点的描述(获取节点的Tag) 节点的局部层顺序值(LocalZOrder) 设置节点的Loca ...

  3. 从零开始のcocos2dx生活(十一)TableView

    目录 简述 主要变量 主要方法 setVerticalFillOrder reloadData cellAtIndex updateCellAtIndex insertCellAtIndex remo ...

  4. 从零开始のcocos2dx生活(十)ScrollView

    目录 简介 基础变量 ScrollViewDelegate Direction _dragging _container _touchMoved _bounceable _touchLength 方法 ...

  5. 从零开始のcocos2dx生活(九)CCBReader

    NodeLoaderLibrary是用来存储节点加载器类型的类,通过registerDefaultNodeLoaders()可以注册所有默认类型的加载器 在CocosBuilder的使用手册中: 1. ...

  6. 从零开始のcocos2dx生活(八)ParticleSystemQuad

    https://learnopengl-cn.github.io/01%20Getting%20started/04%20Hello%20Triangle/#_1 写的真的非常好-最近没时间拜读,只看 ...

  7. 从零开始のcocos2dx生活(一)内存管理

    cocos中所有的对象都是继承自Ref基类,Ref的职责就是对对象进行引用计数管理 内存管理中最重要的是三个方法retain().release().autorelease() 在cocos中创建对象 ...

  8. 从零开始のcocos2dx生活(五)ActionEase

    文章目录 sineEaseIn sineEaseOut sineEaseInOut expoEaseIn expoEaseOut expoEaseInOut easeIn easeOut easeIn ...

  9. 从零开始のcocos2dx生活(四)ActionManager

    文章目录 初始化构造函数 析构函数 删除哈希元素 分配存放动作对象的空间 通过索引移除动作 暂停动作 恢复动作 暂停所有的动作 恢复所有的动作 添加动作 移除所有的动作 移除target中的所有动作 ...

随机推荐

  1. Gym - 101480K_K - Kernel Knights (DFS)

    题意:有两队骑士各n人,每位骑士会挑战对方队伍的某一个位骑士. (可能相同) 要求找以一个区间s: 集合S中的骑士不会互相挑战. 每个集合外的骑士必定会被集合S内的某个骑士挑战. 题解:讲真被题目绕懵 ...

  2. C++构造函数和文件组织

    构造你的函数 在 main() 上方声明函数,并在 main 下方定义函数 在 main() 上方同时声明并定义函数. 随着 C++ 程序变得越来越复杂,你可能需要将代码分成多个文件.分开保存函数定义 ...

  3. 实时计算轻松上手,阿里云DataWorks Stream Studio正式发布

    Stream Studio是DataWorks旗下重磅推出的全新子产品.已于2019年4月18日正式对外开放使用.Stream Studi是一站式流计算开发平台,基于阿里巴巴实时计算引擎Flink构建 ...

  4. hdu 3832 Earth Hour(最短路变形)

    Earth Hour Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 125536/65536 K (Java/Others)Total ...

  5. @noi.ac - 441@ 你天天努力

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 你天天努力,还是比不上小牛,因为小牛在家中套路.于是你决定去拜访 ...

  6. wamp环境搭建(Apache2.4.34+PHP7.2.7+MySQL5.5.60)

    1 添加环境变量 1.1 添加Apache bin目录 1.2 添加PHP目录 2 配置Apache 2.1 修改conf/httpd.conf 将第38行SRVROOT值修改为当前Apache文件夹 ...

  7. 2018-8-10-WPF-使用-VisualStudio-2017-项目文件

    title author date CreateTime categories WPF 使用 VisualStudio 2017 项目文件 lindexi 2018-08-10 19:16:53 +0 ...

  8. 洛谷 1131 [ZJOI2007] 时态同步

    题目描述 小Q在电子工艺实习课上学习焊接电路板.一块电路板由若干个元件组成,我们不妨称之为节点,并将其用数字1,2,3….进行标号.电路板的各个节点由若干不相交的导线相连接,且对于电路板的任何两个节点 ...

  9. H3C 帧中继协议栈

  10. PHP用正则批量替换Img中src内容,用正则表达式获取图片路径实现缩略图功能

    PHP用正则批量替换Img中src内容,用正则表达式获取图片路径实现缩略图功能 网上很多正则表达式只能获取或者替换一个img的src内容,或者只能替换固定的字符串,要动态替换多个图片内容的试了几个小时 ...