Skip to content

Commit 88094f0

Browse files
committed
Include protected node objects when creating node priority map for event dispatcher.
1 parent f564852 commit 88094f0

File tree

6 files changed

+134
-57
lines changed

6 files changed

+134
-57
lines changed

core/2d/CCNode.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1164,6 +1164,49 @@ void Node::resetChild(Node* child, bool cleanup)
11641164
child->setParent(nullptr);
11651165
}
11661166

1167+
void Node::fillGlobalZNodeMap(std::unordered_map<float, std::vector<Node*>>& map,
1168+
const std::function<bool(Node*)>& addNodePredicate)
1169+
{
1170+
sortAllChildren();
1171+
1172+
int i = 0;
1173+
const auto childrenCount = _children.size();
1174+
1175+
if (childrenCount > 0)
1176+
{
1177+
Node* child = nullptr;
1178+
// visit children zOrder < 0
1179+
for (; i < childrenCount; i++)
1180+
{
1181+
child = _children.at(i);
1182+
1183+
if (child && child->getLocalZOrder() < 0)
1184+
child->fillGlobalZNodeMap(map, addNodePredicate);
1185+
else
1186+
break;
1187+
}
1188+
1189+
if (addNodePredicate(this))
1190+
{
1191+
map[this->getGlobalZOrder()].emplace_back(this);
1192+
}
1193+
1194+
for (; i < childrenCount; i++)
1195+
{
1196+
child = _children.at(i);
1197+
if (child)
1198+
child->fillGlobalZNodeMap(map, addNodePredicate);
1199+
}
1200+
}
1201+
else
1202+
{
1203+
if (addNodePredicate(this))
1204+
{
1205+
map[this->getGlobalZOrder()].emplace_back(this);
1206+
}
1207+
}
1208+
}
1209+
11671210
void Node::detachChild(Node* child, ssize_t childIndex, bool cleanup)
11681211
{
11691212
if (_childrenIndexer)

core/2d/CCNode.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1839,6 +1839,14 @@ class AX_DLL Node : public Ref
18391839
*/
18401840
void resetChild(Node* child, bool cleanup);
18411841

1842+
1843+
/*
1844+
* Adds child nodes to an unordered map based on their global Z values and a predicate to
1845+
* decide if those nodes should be added
1846+
*/
1847+
virtual void fillGlobalZNodeMap(std::unordered_map<float, std::vector<Node*>>& map,
1848+
const std::function<bool(Node*)>& addNodePredicate);
1849+
18421850
// Nodes should be created using create();
18431851
Node();
18441852
virtual ~Node();

core/2d/CCProtectedNode.cpp

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,4 +439,67 @@ void ProtectedNode::setGlobalZOrder(float globalZOrder)
439439
child->setGlobalZOrder(globalZOrder);
440440
}
441441

442+
void ProtectedNode::fillGlobalZNodeMap(std::unordered_map<float, std::vector<Node*>>& map,
443+
const std::function<bool(Node*)>& nodeTest)
444+
{
445+
sortAllChildren();
446+
sortAllProtectedChildren();
447+
448+
const auto childrenCount = _children.size();
449+
const auto protectedChildrenCount = _protectedChildren.size();
450+
451+
if (childrenCount > 0 || protectedChildrenCount > 0)
452+
{
453+
Node* child = nullptr;
454+
// visit children zOrder < 0
455+
int childIndex = 0;
456+
int protectedIndex = 0;
457+
for (; childIndex < childrenCount; childIndex++)
458+
{
459+
child = _children.at(childIndex);
460+
461+
if (child && child->getLocalZOrder() < 0)
462+
child->fillGlobalZNodeMap(map, nodeTest);
463+
else
464+
break;
465+
}
466+
467+
for (; protectedIndex < protectedChildrenCount; protectedIndex++)
468+
{
469+
child = _protectedChildren.at(protectedIndex);
470+
471+
if (child && child->getLocalZOrder() < 0)
472+
child->fillGlobalZNodeMap(map, nodeTest);
473+
else
474+
break;
475+
}
476+
477+
if (nodeTest(this))
478+
{
479+
map[this->getGlobalZOrder()].emplace_back(this);
480+
}
481+
482+
for (; childIndex < childrenCount; childIndex++)
483+
{
484+
child = _children.at(childIndex);
485+
if (child)
486+
child->fillGlobalZNodeMap(map, nodeTest);
487+
}
488+
489+
for (; protectedIndex < protectedChildrenCount; protectedIndex++)
490+
{
491+
child = _protectedChildren.at(protectedIndex);
492+
if (child)
493+
child->fillGlobalZNodeMap(map, nodeTest);
494+
}
495+
}
496+
else
497+
{
498+
if (nodeTest(this))
499+
{
500+
map[this->getGlobalZOrder()].emplace_back(this);
501+
}
502+
}
503+
}
504+
442505
NS_AX_END

core/2d/CCProtectedNode.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,10 @@ class AX_DLL ProtectedNode : public Node
188188
virtual void disableCascadeOpacity() override;
189189
virtual void setCameraMask(unsigned short mask, bool applyChildren = true) override;
190190
virtual void setGlobalZOrder(float globalZOrder) override;
191+
192+
void fillGlobalZNodeMap(std::unordered_map<float, std::vector<Node*>>& map,
193+
const std::function<bool(Node*)>& addNodePredicate) override;
194+
191195
ProtectedNode();
192196
virtual ~ProtectedNode();
193197

core/base/CCEventDispatcher.cpp

Lines changed: 15 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -211,72 +211,31 @@ EventDispatcher::~EventDispatcher()
211211
removeAllEventListeners();
212212
}
213213

214-
void EventDispatcher::visitTarget(Node* node, bool isRootNode)
214+
void EventDispatcher::fillNodePriorityMap(Node* rootNode)
215215
{
216-
node->sortAllChildren();
216+
rootNode->fillGlobalZNodeMap(
217+
_globalZOrderNodeMap, [this](Node* n) -> bool { return _nodeListenersMap.find(n) != _nodeListenersMap.end(); });
217218

218-
int i = 0;
219-
auto& children = node->getChildren();
219+
std::vector<float> globalZOrders;
220+
globalZOrders.reserve(_globalZOrderNodeMap.size());
220221

221-
auto childrenCount = children.size();
222-
223-
if (childrenCount > 0)
222+
for (const auto& e : _globalZOrderNodeMap)
224223
{
225-
Node* child = nullptr;
226-
// visit children zOrder < 0
227-
for (; i < childrenCount; i++)
228-
{
229-
child = children.at(i);
224+
globalZOrders.emplace_back(e.first);
225+
}
230226

231-
if (child && child->getLocalZOrder() < 0)
232-
visitTarget(child, false);
233-
else
234-
break;
235-
}
227+
std::stable_sort(globalZOrders.begin(), globalZOrders.end(),
228+
[](const float a, const float b) { return a < b; });
236229

237-
if (_nodeListenersMap.find(node) != _nodeListenersMap.end())
238-
{
239-
_globalZOrderNodeMap[node->getGlobalZOrder()].emplace_back(node);
240-
}
241-
242-
for (; i < childrenCount; i++)
243-
{
244-
child = children.at(i);
245-
if (child)
246-
visitTarget(child, false);
247-
}
248-
}
249-
else
230+
for (const auto& globalZ : globalZOrders)
250231
{
251-
if (_nodeListenersMap.find(node) != _nodeListenersMap.end())
232+
for (const auto& n : _globalZOrderNodeMap[globalZ])
252233
{
253-
_globalZOrderNodeMap[node->getGlobalZOrder()].emplace_back(node);
234+
_nodePriorityMap[n] = ++_nodePriorityIndex;
254235
}
255236
}
256237

257-
if (isRootNode)
258-
{
259-
std::vector<float> globalZOrders;
260-
globalZOrders.reserve(_globalZOrderNodeMap.size());
261-
262-
for (const auto& e : _globalZOrderNodeMap)
263-
{
264-
globalZOrders.emplace_back(e.first);
265-
}
266-
267-
std::stable_sort(globalZOrders.begin(), globalZOrders.end(),
268-
[](const float a, const float b) { return a < b; });
269-
270-
for (const auto& globalZ : globalZOrders)
271-
{
272-
for (const auto& n : _globalZOrderNodeMap[globalZ])
273-
{
274-
_nodePriorityMap[n] = ++_nodePriorityIndex;
275-
}
276-
}
277-
278-
_globalZOrderNodeMap.clear();
279-
}
238+
_globalZOrderNodeMap.clear();
280239
}
281240

282241
void EventDispatcher::pauseEventListenersForTarget(Node* target, bool recursive /* = false */)
@@ -1317,7 +1276,7 @@ void EventDispatcher::sortEventListenersOfSceneGraphPriority(std::string_view li
13171276
_nodePriorityIndex = 0;
13181277
_nodePriorityMap.clear();
13191278

1320-
visitTarget(rootNode, true);
1279+
fillNodePriorityMap(rootNode);
13211280

13221281
// After sort: priority < 0, > 0
13231282
std::stable_sort(sceneGraphListeners->begin(), sceneGraphListeners->end(),

core/base/CCEventDispatcher.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ class AX_DLL EventDispatcher : public Ref
315315

316316
/** Walks though scene graph to get the draw order for each node, it's called before sorting event listener with
317317
* scene graph priority */
318-
void visitTarget(Node* node, bool isRootNode);
318+
void fillNodePriorityMap(Node* rootNode);
319319

320320
/** Remove all listeners in _toRemoveListeners list and cleanup */
321321
void cleanToRemovedListeners();

0 commit comments

Comments
 (0)