Composer bug: Cannot reload scene more than once. (2259)

Reported as issue #: 32049

Basically, if you need to rebuild a scene - that is, call scene:create -  you can only reload once. Attempting to do so again causes Corona to be unable to find the scene (although you’re “in it”.) So if you’re trying to use any sort of localization in your project, either revert to storyboard or consider building a blank (empty) screen to transition to. (It’s risky to add more code but not sure how to ship otherwise.)

Does that mean this doesn’t work?

composer.gotoScene(composer.getSceneName("current"));

No, that works, but in your example the code will only call scene:show(), not scene:create().

If you attempt that code but remove the scene at some point so-as to make sure scene:create() is called, it only works once. On your second try (or any try thereafter) this code results in scene not found:

local name = composer.getSceneName("current") composer.gotoScene(name)

I had to deal with this bug fast because I had to ship an app. My workaround was your exactly the one you have suggested - empty screen to transition to.

I am so glad I never bothered to go to Composer… New & improved Storyboard hah. It will take another 6 months to get Composer as stable as storyboard was/is and by then I bet they will introduce the new iteration… Maestro?  :wink:

I like composer. In general it just cleaned up a lot of little things with storyboard logic. No more purge/remove nonsense, and will/did logic makes more sense than didEnter/willExit/etc. Hopefully this issue gets resolved soon.

I confirmed this bug using 2 scenes to test between (using build 2248):

_ Note: this issue does not occur with storyboard (i tested w/ same scenario)_
 

-- on test1 scene, add to a function composer.removeScene("test2") composer.gotoScene("test2") -- on test2 scene, add to a function composer.removeScene("test1") composer.gotoScene("test1")

One fix i found however, was adding a timer between gotoScene… e.g.

composer.removeScene("test1") timer.performWithDelay(100,function() composer.gotoScene("test1") end)

Or, don’t put code inside scene:create() – put your create code inside functions that are called from inside scene:create().

That way when you want to reload a scene you don’t actually reload – you just call the create code functions again.

Jay

That’s not a bad idea, per se, but is probably an order of magnitude more complicated because:

a) Your code must be sufficiently encapsulated to call outside of createScene, and

b) You would need to write detection code so that your program knows whether to ‘reload’ content within enterScene. So basically do exactly what createScene already does.

The blank scene solution is short (<15 lines), simple, and works well for most cases.

@richard the best solution would be corona fixing it =P

+1. 

Hah, definitely. Fixing that and the hide:did phase would be great.

>.< reverted to storyboard!

Welcome back!  :slight_smile:

I also found that adding a delay fixed the issue for me.

timer.performWithDelay(1,function()
composer.gotoScene(“mainscene”)
end)

Otherwise I’ve found that composer works better than Storyboard.

in which way?

Storyboard events were sometimes firing in an incorrect order (or not at all) causing the app logic to fail.

Composer doesn’t have that problem.

So far I have only seen the issue that the OP has mentioned, but I got around that my issuing the gotoScene() with a 1ms delay as I mentioned above.

That timing fix is very familiar; I wonder if that’s an old regression bug. Anyway, there is an issue with some transition effects (so far I’ve noticed fromX) where the original scene gets dumped before the transition (mixing up will/did somehow, at least visually) but on the whole it has been much cleaner to deal with.

Does that mean this doesn’t work?

composer.gotoScene(composer.getSceneName("current"));

No, that works, but in your example the code will only call scene:show(), not scene:create().

If you attempt that code but remove the scene at some point so-as to make sure scene:create() is called, it only works once. On your second try (or any try thereafter) this code results in scene not found:

local name = composer.getSceneName("current") composer.gotoScene(name)