Add CCDirector::popToSceneStackLevel(int level)

This replicates a change made to cocos2d-iphone in the following commit:
59c5272bff

The cocos2d-iphone change was originally discussed in the following pull request:
http://github.com/cocos2d/cocos2d-x/pull/2210
This commit is contained in:
Darragh Coy 2013-04-30 23:33:22 +01:00
parent 60e4730122
commit 212feb8d8c
4 changed files with 57 additions and 34 deletions

View File

@ -578,33 +578,44 @@ void CCDirector::popScene(void)
} }
void CCDirector::popToRootScene(void) void CCDirector::popToRootScene(void)
{
popToSceneStackLevel(1);
}
void CCDirector::popToSceneStackLevel(int level)
{ {
CCAssert(m_pRunningScene != NULL, "A running Scene is needed"); CCAssert(m_pRunningScene != NULL, "A running Scene is needed");
unsigned int c = m_pobScenesStack->count(); unsigned int c = m_pobScenesStack->count();
if (c == 1) // level 0? -> end
if (level == 0)
{ {
m_pobScenesStack->removeLastObject(); end();
this->end(); return;
} }
else
{ // current level or lower -> nothing
while (c > 1) if (level >= c)
return;
// pop stack until reaching desired level
while (c > level)
{ {
CCScene *current = (CCScene*)m_pobScenesStack->lastObject(); CCScene *current = (CCScene*)m_pobScenesStack->lastObject();
if( current->isRunning() )
if (current->isRunning())
{ {
current->onExitTransitionDidStart(); current->onExitTransitionDidStart();
current->onExit(); current->onExit();
} }
current->cleanup();
current->cleanup();
m_pobScenesStack->removeLastObject(); m_pobScenesStack->removeLastObject();
c--; c--;
} }
m_pNextScene = (CCScene*)m_pobScenesStack->lastObject(); m_pNextScene = (CCScene*)m_pobScenesStack->lastObject();
m_bSendCleanupToScene = false; m_bSendCleanupToScene = false;
}
} }
void CCDirector::end() void CCDirector::end()

View File

@ -204,7 +204,7 @@ public:
// Scene Management // Scene Management
/**Enters the Director's main loop with the given Scene. /** Enters the Director's main loop with the given Scene.
* Call it to run only your FIRST scene. * Call it to run only your FIRST scene.
* Don't call it if there is already a running scene. * Don't call it if there is already a running scene.
* *
@ -212,27 +212,33 @@ public:
*/ */
void runWithScene(CCScene *pScene); void runWithScene(CCScene *pScene);
/**Suspends the execution of the running scene, pushing it on the stack of suspended scenes. /** Suspends the execution of the running scene, pushing it on the stack of suspended scenes.
* The new scene will be executed. * The new scene will be executed.
* Try to avoid big stacks of pushed scenes to reduce memory allocation. * Try to avoid big stacks of pushed scenes to reduce memory allocation.
* ONLY call it if there is a running scene. * ONLY call it if there is a running scene.
*/ */
void pushScene(CCScene *pScene); void pushScene(CCScene *pScene);
/**Pops out a scene from the queue. /** Pops out a scene from the queue.
* This scene will replace the running one. * This scene will replace the running one.
* The running scene will be deleted. If there are no more scenes in the stack the execution is terminated. * The running scene will be deleted. If there are no more scenes in the stack the execution is terminated.
* ONLY call it if there is a running scene. * ONLY call it if there is a running scene.
*/ */
void popScene(void); void popScene(void);
/**Pops out all scenes from the queue until the root scene in the queue. /** Pops out all scenes from the queue until the root scene in the queue.
* This scene will replace the running one. * This scene will replace the running one.
* The running scene will be deleted. If there are no more scenes in the stack the execution is terminated. * Internally it will call `popToSceneStackLevel(1)`
* ONLY call it if there is a running scene.
*/ */
void popToRootScene(void); void popToRootScene(void);
/** Pops out all scenes from the queue until it reaches `level`.
If level is 0, it will end the director.
If level is 1, it will pop all scenes until it reaches to root scene.
If level is <= than the current stack level, it won't do anything.
*/
void popToSceneStackLevel(int level);
/** Replaces the running scene with a new one. The running scene is terminated. /** Replaces the running scene with a new one. The running scene is terminated.
* ONLY call it if there is a running scene. * ONLY call it if there is a running scene.
*/ */

View File

@ -174,9 +174,9 @@ bool SceneTestLayer3::init()
CCMenuItemFont *item0 = CCMenuItemFont::create("Touch to pushScene (self)", this, menu_selector(SceneTestLayer3::item0Clicked)); CCMenuItemFont *item0 = CCMenuItemFont::create("Touch to pushScene (self)", this, menu_selector(SceneTestLayer3::item0Clicked));
CCMenuItemFont *item1 = CCMenuItemFont::create("Touch to popScene", this, menu_selector(SceneTestLayer3::item1Clicked)); CCMenuItemFont *item1 = CCMenuItemFont::create("Touch to popScene", this, menu_selector(SceneTestLayer3::item1Clicked));
CCMenuItemFont *item2 = CCMenuItemFont::create("Touch to popToRootScene", this, menu_selector(SceneTestLayer3::item2Clicked)); CCMenuItemFont *item2 = CCMenuItemFont::create("Touch to popToRootScene", this, menu_selector(SceneTestLayer3::item2Clicked));
CCMenuItemFont *item3 = CCMenuItemFont::create("Touch to popToSceneStackLevel(2)", this, menu_selector(SceneTestLayer3::item3Clicked));
CCMenu *menu = CCMenu::create(item0, item1, item2, item3, NULL);
CCMenu *menu = CCMenu::create(item0, item1, item2, NULL);
this->addChild(menu); this->addChild(menu);
menu->alignItemsVertically(); menu->alignItemsVertically();
@ -215,6 +215,11 @@ void SceneTestLayer3::item2Clicked(CCObject* pSender)
CCDirector::sharedDirector()->popToRootScene(); CCDirector::sharedDirector()->popToRootScene();
} }
void SceneTestLayer3::item3Clicked(CCObject* pSender)
{
CCDirector::sharedDirector()->popToSceneStackLevel(2);
}
void SceneTestScene::runThisTest() void SceneTestScene::runThisTest()
{ {
CCLayer* pLayer = new SceneTestLayer1(); CCLayer* pLayer = new SceneTestLayer1();

View File

@ -44,6 +44,7 @@ public:
void item0Clicked(CCObject* pSender); void item0Clicked(CCObject* pSender);
void item1Clicked(CCObject* pSender); void item1Clicked(CCObject* pSender);
void item2Clicked(CCObject* pSender); void item2Clicked(CCObject* pSender);
void item3Clicked(CCObject* pSender);
CREATE_FUNC(SceneTestLayer3) CREATE_FUNC(SceneTestLayer3)
} ; } ;