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

View File

@ -204,7 +204,7 @@ public:
// 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.
* Don't call it if there is already a running scene.
*
@ -212,27 +212,33 @@ public:
*/
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.
* Try to avoid big stacks of pushed scenes to reduce memory allocation.
* ONLY call it if there is a running scene.
*/
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.
* 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.
*/
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.
* 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.
* Internally it will call `popToSceneStackLevel(1)`
*/
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.
* ONLY call it if there is a running scene.
*/

View File

@ -171,13 +171,13 @@ bool SceneTestLayer3::init()
{
CCSize s = CCDirector::sharedDirector()->getWinSize();
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 *item2 = CCMenuItemFont::create("Touch to popToRootScene", this, menu_selector(SceneTestLayer3::item2Clicked));
CCMenu *menu = CCMenu::create(item0, item1, item2, NULL);
this->addChild(menu);
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 *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);
this->addChild(menu);
menu->alignItemsVertically();
this->schedule(schedule_selector(SceneTestLayer3::testDealloc));
@ -215,6 +215,11 @@ void SceneTestLayer3::item2Clicked(CCObject* pSender)
CCDirector::sharedDirector()->popToRootScene();
}
void SceneTestLayer3::item3Clicked(CCObject* pSender)
{
CCDirector::sharedDirector()->popToSceneStackLevel(2);
}
void SceneTestScene::runThisTest()
{
CCLayer* pLayer = new SceneTestLayer1();

View File

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