I found myself having to redraw the scene right where i am but cocos2d doesn't offer this functionality yet. So i made a change to CCDirector's main loop and extracted a public drawScene method out of it that can be called anytime.
//
// main loop
//
- (void) mainLoop
{
/* calculate "global" dt */
[self calculateDeltaTime];
if( ! isPaused_ )
[[CCScheduler sharedScheduler] tick: dt];
/* to avoid flickr, nextScene MUST be here: after tick and before draw */
if( nextScene )
[self setNextScene];
[self drawScene];
}
-(void) drawScene
{
/* clear window */
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
[self applyLandscape];
/* draw the scene */
[runningScene_ visit];
if( displayFPS )
[self showFPS];
glPopMatrix();
/* swap buffers */
[openGLView_ swapBuffers];
}
I'm not aware of any side effects. The only real change to the code flow i made is to call glClear after the tick and nextScene calls, something that ought not make any difference unless in either of those functions something is drawn to the screen.
I need drawScene in cases where i start a CPU intensive task but have to update the screen before that, for example to remove a dialog box from the screen. So instead of using [self schedule ...] with a short interval and waiting for the selector to be called, i call directly [[CCDirector sharedDirector] drawScene]; and start computing. I also had to use this right in the init method of a scene, for example when the new scene is loaded it should already draw itself because it does some heavy initialization and that would cause the old screen still to be shown.