Transition.cancel does NOT cancel onComplete events

Latest public build 2189, have found that transition.cancel does not cancel the onComplete part of the active transition that has been cancelled. 

The doco says

Important

If you remove or clear a transitioning object from memory, and the transition has an onComplete event, the listener will still be invoked even though the object no longer exists on the screen. Other transition events may even crash the program if the object has been prematurely removed. Thus, it’s good practice to cancel all transitions on a specific object before removing it. Passing the object reference to transition.cancel() is useful for this purpose.

In a wider scope, you may consider using transition.cancel() with no params to cancel  all  transitions before exiting a Storyboard scene or clearing a module.

Calling transition.cancel(object) or even transition.cancel() still results in the onComplete events of the transitions from firing once the time specified elapses. 

I have attached an example project that reproduces the issue. I came across this when hiding an overlay and found the onComplete event of a looping sequence of transitions would still fire after the transition.cancel was called and the scene destroyed. I distilled it down to a very simple example which starts a transition, calls hide overlay and then crashes when the onComplete event still fires after scene destroy due to my attempt to access the disposed object. 

Will post as a bug report but also posted here just incase im missing something and we dont get any feedback from bug reports, 

Cheers

Your example is creating and destroying the tween within the same run-loop which is causing Corona to get confused.

Hiding the overlay like this solves the issue:

print("and trigger the overlay to hide") timer.performWithDelay( 1, function() composer.hideOverlay() end)

I’m not saying that it should be like that, but it’s a workaround.

(BTW. I know that this is just an example, but you’re code isn’t adding the display objects to the scene group)

@Ingemar - Ill try that work around in my actual game, however i dont actually call composer.hideOverlay from the same spot in my game, i just put in there in the example to easily show the same thing. 

Also, all the display objects are added to the scene group, see bold/underline below. 

function scene:create( event )

    local group = self.view

    print(“Create the objects for our test”)

    local obj = display.newRect( group , 0, 0, 512, 512)

    obj:setFillColor( 100, 200, 100, 0.5 )

    lineObj = display.newRect(group, 0, 0, 16, 256);      lineObj.alpha = 0

end

Ugh… that’s what happens when I skim too fast, sorry :-/

Your right, triggering the hideOverlay from a timer seems to resolve the issue. I will use this in the meantime as a workaround, but ideally this should be fixed. In my actually app where I found the problem I call hideOverlay on the touch event of a button, as i imagine most people probably do.

I’d recommend submitting your project as a bug report so that CoronaLabs can prioritize and schedule a fix, and then posting the case number here.

Already done, case number is 32746

 

Your example is creating and destroying the tween within the same run-loop which is causing Corona to get confused.

Hiding the overlay like this solves the issue:

print("and trigger the overlay to hide") timer.performWithDelay( 1, function() composer.hideOverlay() end)

I’m not saying that it should be like that, but it’s a workaround.

(BTW. I know that this is just an example, but you’re code isn’t adding the display objects to the scene group)

@Ingemar - Ill try that work around in my actual game, however i dont actually call composer.hideOverlay from the same spot in my game, i just put in there in the example to easily show the same thing. 

Also, all the display objects are added to the scene group, see bold/underline below. 

function scene:create( event )

    local group = self.view

    print(“Create the objects for our test”)

    local obj = display.newRect( group , 0, 0, 512, 512)

    obj:setFillColor( 100, 200, 100, 0.5 )

    lineObj = display.newRect(group, 0, 0, 16, 256);      lineObj.alpha = 0

end

Ugh… that’s what happens when I skim too fast, sorry :-/

Your right, triggering the hideOverlay from a timer seems to resolve the issue. I will use this in the meantime as a workaround, but ideally this should be fixed. In my actually app where I found the problem I call hideOverlay on the touch event of a button, as i imagine most people probably do.

I’d recommend submitting your project as a bug report so that CoronaLabs can prioritize and schedule a fix, and then posting the case number here.

Already done, case number is 32746