Skip to content

Commit 523b231

Browse files
author
pandamicro
committed
Flat recursive call using stack for onEnter/onExit/cleanup etc
1 parent 0bda54c commit 523b231

File tree

9 files changed

+137
-190
lines changed

9 files changed

+137
-190
lines changed

cocos2d/clipping-nodes/CCClippingNode.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ cc.ClippingNode = cc.Node.extend(/** @lends cc.ClippingNode# */{
9191
onEnter: function () {
9292
cc.Node.prototype.onEnter.call(this);
9393
if (this._stencil)
94-
this._stencil.onEnter();
94+
this._stencil._performRecursive(cc.Node._stateCallbackType.onEnter);
9595
},
9696

9797
/**
@@ -105,7 +105,7 @@ cc.ClippingNode = cc.Node.extend(/** @lends cc.ClippingNode# */{
105105
onEnterTransitionDidFinish: function () {
106106
cc.Node.prototype.onEnterTransitionDidFinish.call(this);
107107
if (this._stencil)
108-
this._stencil.onEnterTransitionDidFinish();
108+
this._stencil._performRecursive(cc.Node._stateCallbackType.onEnterTransitionDidFinish);
109109
},
110110

111111
/**
@@ -117,7 +117,7 @@ cc.ClippingNode = cc.Node.extend(/** @lends cc.ClippingNode# */{
117117
* @function
118118
*/
119119
onExitTransitionDidStart: function () {
120-
this._stencil.onExitTransitionDidStart();
120+
this._stencil._performRecursive(cc.Node._stateCallbackType.onExitTransitionDidStart);
121121
cc.Node.prototype.onExitTransitionDidStart.call(this);
122122
},
123123

@@ -131,7 +131,7 @@ cc.ClippingNode = cc.Node.extend(/** @lends cc.ClippingNode# */{
131131
* @function
132132
*/
133133
onExit: function () {
134-
this._stencil.onExit();
134+
this._stencil._performRecursive(cc.Node._stateCallbackType.onExit);
135135
cc.Node.prototype.onExit.call(this);
136136
},
137137

cocos2d/core/CCDirector.js

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -400,9 +400,9 @@ cc.Director = cc.Class.extend(/** @lends cc.Director# */{
400400
// They are needed in case the director is run again
401401

402402
if (this._runningScene) {
403-
this._runningScene.onExitTransitionDidStart();
404-
this._runningScene.onExit();
405-
this._runningScene.cleanup();
403+
this._runningScene._performRecursive(cc.Node._stateCallbackType.onExitTransitionDidStart);
404+
this._runningScene._performRecursive(cc.Node._stateCallbackType.onExit);
405+
this._runningScene._performRecursive(cc.Node._stateCallbackType.cleanup);
406406
}
407407

408408
this._runningScene = null;
@@ -537,23 +537,23 @@ cc.Director = cc.Class.extend(/** @lends cc.Director# */{
537537
if (!newIsTransition) {
538538
var locRunningScene = this._runningScene;
539539
if (locRunningScene) {
540-
locRunningScene.onExitTransitionDidStart();
541-
locRunningScene.onExit();
540+
locRunningScene._performRecursive(cc.Node._stateCallbackType.onExitTransitionDidStart);
541+
locRunningScene._performRecursive(cc.Node._stateCallbackType.onExit);
542542
}
543543

544544
// issue #709. the root node (scene) should receive the cleanup message too
545545
// otherwise it might be leaked.
546546
if (this._sendCleanupToScene && locRunningScene)
547-
locRunningScene.cleanup();
547+
locRunningScene._performRecursive(cc.Node._stateCallbackType.cleanup);
548548
}
549549

550550
this._runningScene = this._nextScene;
551551
cc.renderer.childrenOrderDirty = true;
552552

553553
this._nextScene = null;
554554
if ((!runningIsTransition) && (this._runningScene !== null)) {
555-
this._runningScene.onEnter();
556-
this._runningScene.onEnterTransitionDidFinish();
555+
this._runningScene._performRecursive(cc.Node._stateCallbackType.onEnter);
556+
this._runningScene._performRecursive(cc.Node._stateCallbackType.onEnterTransitionDidFinish);
557557
}
558558
},
559559

@@ -563,16 +563,16 @@ cc.Director = cc.Class.extend(/** @lends cc.Director# */{
563563
*/
564564
setNotificationNode: function (node) {
565565
cc.renderer.childrenOrderDirty = true;
566-
if(this._notificationNode){
567-
this._notificationNode.onExitTransitionDidStart();
568-
this._notificationNode.onExit();
569-
this._notificationNode.cleanup();
566+
if (this._notificationNode) {
567+
this._notificationNode._performRecursive(cc.Node._stateCallbackType.onExitTransitionDidStart);
568+
this._notificationNode._performRecursive(cc.Node._stateCallbackType.onExit);
569+
this._notificationNode._performRecursive(cc.Node._stateCallbackType.cleanup);
570570
}
571571
this._notificationNode = node;
572-
if(!node)
572+
if (!node)
573573
return;
574-
this._notificationNode.onEnter();
575-
this._notificationNode.onEnterTransitionDidFinish();
574+
this._notificationNode._performRecursive(cc.Node._stateCallbackType.onEnter);
575+
this._notificationNode._performRecursive(cc.Node._stateCallbackType.onEnterTransitionDidFinish);
576576
},
577577

578578
/**
@@ -748,10 +748,10 @@ cc.Director = cc.Class.extend(/** @lends cc.Director# */{
748748
while (c > level) {
749749
var current = locScenesStack.pop();
750750
if (current.running) {
751-
current.onExitTransitionDidStart();
752-
current.onExit();
751+
current._performRecursive(cc.Node._stateCallbackType.onExitTransitionDidStart);
752+
current._performRecursive(cc.Node._stateCallbackType.onExit);
753753
}
754-
current.cleanup();
754+
current._performRecursive(cc.Node._stateCallbackType.cleanup);
755755
c--;
756756
}
757757
this._nextScene = locScenesStack[locScenesStack.length - 1];

cocos2d/core/base-nodes/CCNode.js

Lines changed: 87 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -216,68 +216,6 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
216216
return true;
217217
},
218218

219-
_arrayMakeObjectsPerformSelector: function (array, callbackType) {
220-
if (!array || array.length === 0)
221-
return;
222-
223-
var i, len = array.length, node;
224-
var nodeCallbackType = cc.Node._stateCallbackType;
225-
switch (callbackType) {
226-
case nodeCallbackType.onEnter:
227-
for (i = 0; i < len; i++) {
228-
node = array[i];
229-
if (node)
230-
node.onEnter();
231-
}
232-
break;
233-
case nodeCallbackType.onExit:
234-
for (i = 0; i < len; i++) {
235-
node = array[i];
236-
if (node)
237-
node.onExit();
238-
}
239-
break;
240-
case nodeCallbackType.onEnterTransitionDidFinish:
241-
for (i = 0; i < len; i++) {
242-
node = array[i];
243-
if (node)
244-
node.onEnterTransitionDidFinish();
245-
}
246-
break;
247-
case nodeCallbackType.cleanup:
248-
for (i = 0; i < len; i++) {
249-
node = array[i];
250-
if (node)
251-
node.cleanup();
252-
}
253-
break;
254-
case nodeCallbackType.updateTransform:
255-
for (i = 0; i < len; i++) {
256-
node = array[i];
257-
if (node)
258-
node.updateTransform();
259-
}
260-
break;
261-
case nodeCallbackType.onExitTransitionDidStart:
262-
for (i = 0; i < len; i++) {
263-
node = array[i];
264-
if (node)
265-
node.onExitTransitionDidStart();
266-
}
267-
break;
268-
case nodeCallbackType.sortAllChildren:
269-
for (i = 0; i < len; i++) {
270-
node = array[i];
271-
if (node)
272-
node.sortAllChildren();
273-
}
274-
break;
275-
default :
276-
cc.assert(0, cc._LogInfos.Node__arrayMakeObjectsPerformSelector);
277-
break;
278-
}
279-
},
280-
281219
/**
282220
* <p>Properties configuration function </br>
283221
* All properties in attrs will be set to the node, </br>
@@ -1177,9 +1115,6 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
11771115

11781116
// event
11791117
cc.eventManager.removeListeners(this);
1180-
1181-
// timers
1182-
this._arrayMakeObjectsPerformSelector(this._children, cc.Node._stateCallbackType.cleanup);
11831118
},
11841119

11851120
// composition: GET
@@ -1264,10 +1199,10 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
12641199
child.setOrderOfArrival(cc.s_globalOrderOfArrival++);
12651200

12661201
if (this._running) {
1267-
child.onEnter();
1202+
child._performRecursive(cc.Node._stateCallbackType.onEnter);
12681203
// prevent onEnterTransitionDidFinish to be called twice when a node is added in onEnter
12691204
if (this._isTransitionFinished)
1270-
child.onEnterTransitionDidFinish();
1205+
child._performRecursive(cc.Node._stateCallbackType.onEnterTransitionDidFinish);
12711206
}
12721207
child._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.transformDirty);
12731208
if (this._cascadeColorEnabled)
@@ -1370,13 +1305,13 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
13701305
var node = __children[i];
13711306
if (node) {
13721307
if (this._running) {
1373-
node.onExitTransitionDidStart();
1374-
node.onExit();
1308+
node._performRecursive(cc.Node._stateCallbackType.onExitTransitionDidStart);
1309+
node._performRecursive(cc.Node._stateCallbackType.onExit);
13751310
}
13761311

13771312
// If you don't do cleanup, the node's actions will not get removed and the
13781313
if (cleanup)
1379-
node.cleanup();
1314+
node._performRecursive(cc.Node._stateCallbackType.cleanup);
13801315

13811316
// set parent nil at the end
13821317
node.parent = null;
@@ -1393,13 +1328,13 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
13931328
// -1st do onExit
13941329
// -2nd cleanup
13951330
if (this._running) {
1396-
child.onExitTransitionDidStart();
1397-
child.onExit();
1331+
child._performRecursive(cc.Node._stateCallbackType.onExitTransitionDidStart);
1332+
child._performRecursive(cc.Node._stateCallbackType.onExit);
13981333
}
13991334

14001335
// If you don't do cleanup, the child's actions will not get removed and the
14011336
if (doCleanup)
1402-
child.cleanup();
1337+
child._performRecursive(cc.Node._stateCallbackType.cleanup);
14031338

14041339
// set parent nil at the end
14051340
child.parent = null;
@@ -1501,10 +1436,72 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
15011436
onEnter: function () {
15021437
this._isTransitionFinished = false;
15031438
this._running = true;//should be running before resumeSchedule
1504-
this._arrayMakeObjectsPerformSelector(this._children, cc.Node._stateCallbackType.onEnter);
15051439
this.resume();
15061440
},
15071441

1442+
_performRecursive: function (callbackType) {
1443+
var nodeCallbackType = cc.Node._stateCallbackType;
1444+
if (callbackType >= nodeCallbackType.max) {
1445+
return;
1446+
}
1447+
1448+
var index = 0;
1449+
var children, child, curr, i, len;
1450+
var stack = cc.Node._performStacks[cc.Node._performing];
1451+
if (!stack) {
1452+
stack = [];
1453+
cc.Node._performStacks.push(stack);
1454+
}
1455+
stack.length = 0;
1456+
cc.Node._performing++;
1457+
curr = stack[0] = this;
1458+
while (curr) {
1459+
// Walk through children
1460+
children = curr._children;
1461+
if (children && children.length > 0) {
1462+
for (i = 0, len = children.length; i < len; ++i) {
1463+
child = children[i];
1464+
stack.push(child);
1465+
}
1466+
}
1467+
children = curr._protectedChildren;
1468+
if (children && children.length > 0) {
1469+
for (i = 0, len = children.length; i < len; ++i) {
1470+
child = children[i];
1471+
stack.push(child);
1472+
}
1473+
}
1474+
1475+
index++;
1476+
curr = stack[index];
1477+
}
1478+
for (i = stack.length - 1; i >= 0; --i) {
1479+
curr = stack[i];
1480+
stack[i] = null;
1481+
if (!curr) continue;
1482+
1483+
// Perform actual action
1484+
switch (callbackType) {
1485+
case nodeCallbackType.onEnter:
1486+
curr.onEnter();
1487+
break;
1488+
case nodeCallbackType.onExit:
1489+
curr.onExit();
1490+
break;
1491+
case nodeCallbackType.onEnterTransitionDidFinish:
1492+
curr.onEnterTransitionDidFinish();
1493+
break;
1494+
case nodeCallbackType.cleanup:
1495+
curr.cleanup();
1496+
break;
1497+
case nodeCallbackType.onExitTransitionDidStart:
1498+
curr.onExitTransitionDidStart();
1499+
break;
1500+
}
1501+
}
1502+
cc.Node._performing--;
1503+
},
1504+
15081505
/**
15091506
* <p>
15101507
* Event callback that is invoked when the CCNode enters in the 'stage'. <br/>
@@ -1515,7 +1512,6 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
15151512
*/
15161513
onEnterTransitionDidFinish: function () {
15171514
this._isTransitionFinished = true;
1518-
this._arrayMakeObjectsPerformSelector(this._children, cc.Node._stateCallbackType.onEnterTransitionDidFinish);
15191515
},
15201516

15211517
/**
@@ -1525,7 +1521,6 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
15251521
* @function
15261522
*/
15271523
onExitTransitionDidStart: function () {
1528-
this._arrayMakeObjectsPerformSelector(this._children, cc.Node._stateCallbackType.onExitTransitionDidStart);
15291524
},
15301525

15311526
/**
@@ -1540,7 +1535,6 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
15401535
onExit: function () {
15411536
this._running = false;
15421537
this.pause();
1543-
this._arrayMakeObjectsPerformSelector(this._children, cc.Node._stateCallbackType.onExit);
15441538
this.removeAllComponents();
15451539
},
15461540

@@ -2011,8 +2005,12 @@ cc.Node = cc.Class.extend(/** @lends cc.Node# */{
20112005
* @function
20122006
*/
20132007
updateTransform: function () {
2014-
// Recursively iterate over children
2015-
this._arrayMakeObjectsPerformSelector(this._children, cc.Node._stateCallbackType.updateTransform);
2008+
var children = this._children, node;
2009+
for (var i = 0; i < children.length; i++) {
2010+
varnode = children[i];
2011+
if (node)
2012+
node.updateTransform();
2013+
}
20162014
},
20172015

20182016
/**
@@ -2541,7 +2539,16 @@ cc.Node.create = function () {
25412539
return new cc.Node();
25422540
};
25432541

2544-
cc.Node._stateCallbackType = {onEnter: 1, onExit: 2, cleanup: 3, onEnterTransitionDidFinish: 4, updateTransform: 5, onExitTransitionDidStart: 6, sortAllChildren: 7};
2542+
cc.Node._stateCallbackType = {
2543+
onEnter: 1,
2544+
onExit: 2,
2545+
cleanup: 3,
2546+
onEnterTransitionDidFinish: 4,
2547+
onExitTransitionDidStart: 5,
2548+
max: 6
2549+
};
2550+
cc.Node._performStacks = [[]];
2551+
cc.Node._performing = 0;
25452552

25462553
cc.assert(cc.isFunction(cc._tmp.PrototypeCCNode), cc._LogInfos.MissingFile, "BaseNodesPropertyDefine.js");
25472554
cc._tmp.PrototypeCCNode();

cocos2d/particle/CCParticleBatchNode.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -477,8 +477,8 @@ cc.ParticleBatchNode = cc.Node.extend(/** @lends cc.ParticleBatchNode# */{
477477
child._setLocalZOrder(z);
478478
child.parent = this;
479479
if (this._running) {
480-
child.onEnter();
481-
child.onEnterTransitionDidFinish();
480+
child._performRecursive(cc.Node._stateCallbackType.onEnter);
481+
child._performRecursive(cc.Node._stateCallbackType.onEnterTransitionDidFinish);
482482
}
483483
return pos;
484484
},

0 commit comments

Comments
 (0)