NobleEngine
NobleEngine copied to clipboard
Defer Noble.transition to update loop
Before it was possible to call transition at times when it was not safe to do so, such as in input handlers. It would sometimes work, but then sometimes crash the playdate. It was possible to call a transition multiple times resulting in a bonk.
So instead, make the transition function enqueue the transition until the next game loop, and also take care of making sure that other calls are ignored until the transition is completed.
This should allow transition to be called anywhere, even during button presses that otherwise would require a lot of boilerplate flag setting and checking.t
In general, times where transitions are unsafe to call are times when input handlers are always nil
and/or the only possible method calls are scene callbacks, so I don't know how realistically unsafe it actually is, but I think it does make sense to defer it to an update call.
I'll have to review this PR more thoroughly when I have time, but first impressions is that it is a reasonable solution to a well-defined, if uncommon problem.
I was running into transition problems all the time. I thought I could call it inside a AButtonDown callback and in sprite collisions, but it'd crash the playdate complealty or fire off several transitions and then I'd get the bonk.
Then I started having those places only set a boolean flag, and process it in the scene's update function, which was then a lot of repetitive code everywhere I wanted to do a transition.
Umm, that shouldn't be happening even without adding extra checks. But, your experience is evidence enough that it's worth making this change.
My guess is that I was holding down the button for a few cycles and it'd get fired off each time. Or the two srpites kept touching for more than one cycle so the collision was happening several times. I didn't track it down though compelaty, so I'm not sure
I finally found time to review and pull this. I made a few changes to conform to the Noble Engine's code style, and I re-incorporated Noble.isTransitioning
to work with this improved feature (the engine now throws warn()
instead of error()
because calling Noble.transition()
multiple times no longer breaks things, but it's still not advised).
Thanks again for adding this feature to the engine. Great work!!