EventDispatch機制
來源:程序員人生 發布時間:2014-11-18 08:43:31 閱讀次數:3205次
cocos2dx 3.x中的事件機制原理:
通過訪問Node的全局Zorder來排列優先級。
_globalZOrderNodeMap[node->getGlobalZOrder()].push_back(node);
_globalZOrderNodeMap 作為迭代的容器,最后處理根節點排序的結果(會清算掉當前寄存的節點),真正有效的數據時排列好的:_nodePriorityMap。
首先遍歷Scene下的所有子Layer(Node*),把子節點中比當前Layer優先級數值小的寄存在_nodePriorityMap,接著清除子Layer中比當前Layer優先級小的節點,然后把當前節點放入_globalZOrderNodeMap 。
每一個Node都有1個sortChildren操作,排列出來的就是根據Zorder,只要先處理比當前Layer深度優先的(Zorder),再處應當前layer,和小于或等于的Children――全部原理就跟2叉樹中序遍歷比較類似,判定條件是Zorder。
oid EventDispatcher::visitTarget(Node* node, bool isRootNode)
{
int i = 0;
auto& children = node->getChildren();
auto childrenCount = children.size();
if(childrenCount > 0)
{
Node* child = nullptr;
// visit children zOrder < 0
for( ; i < childrenCount; i++ )
{
child = children.at(i);
if ( child && child->getLocalZOrder() < 0 )
visitTarget(child, false);
else
break;
}
if (_nodeListenersMap.find(node) != _nodeListenersMap.end())
{
_globalZOrderNodeMap[node->getGlobalZOrder()].push_back(node);
}
for( ; i < childrenCount; i++ )
{
child = children.at(i);
if (child)
visitTarget(child, false);
}
}
else
{
if (_nodeListenersMap.find(node) != _nodeListenersMap.end())
{
_globalZOrderNodeMap[node->getGlobalZOrder()].push_back(node);
}
}
//遞歸的所有進程中只有根節點進入(Scene),事件的派發級是根據<span style="font-family: Arial, Helvetica, sans-serif;">_nodePriorityMap中的結果去派發</span>
if (isRootNode)
{
std::vector<float> globalZOrders;
globalZOrders.reserve(_globalZOrderNodeMap.size());
for (const auto& e : _globalZOrderNodeMap)
{
globalZOrders.push_back(e.first);
}
std::sort(globalZOrders.begin(), globalZOrders.end(), [](const float a, const float b){
return a < b;
});
for (const auto& globalZ : globalZOrders)
{
for (const auto& n : _globalZOrderNodeMap[globalZ])
{
_nodePriorityMap[n] = ++_nodePriorityIndex;
}
}
_globalZOrderNodeMap.clear();
}
}
_nodePriorityIndex 為SceneGraphPriority控制量,最后組合成從0到N不重復的數字隊列,去標示每一個Node,所有的Node具有不同的優先級。
生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈