Corona transition.to fires onComplete twice

Hello

I’ve got this simple function:

&nbsp; &nbsp; myObject.switchMove = function(time, x, y, callback) &nbsp; &nbsp; &nbsp; &nbsp; local i = 0 &nbsp; &nbsp; &nbsp; &nbsp; local localCallback = callback &nbsp; &nbsp; &nbsp; &nbsp; local function switchMoveComplete(target) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; i = i + 1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; assert(i \< 2, "DAMN YOU GUYS!") &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if p.switchMoveTransition then &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; transition.cancel(p.switchMoveTransition) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; p.switchMoveTransition = nil &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if localCallback then localCallback(target) end &nbsp; &nbsp; &nbsp; &nbsp; end &nbsp; &nbsp; &nbsp; &nbsp; p.switchMoveTransition = transition.to(myObject, { time = time, x = x, y = y, transition = easing.inOutQuad, onComplete = switchMoveComplete }) &nbsp; &nbsp; end &nbsp;

As you can see, each time switchMove function is called, a new instance of variable i is created and initiated with 0. A new instance of function switchMoveComplete is created, so there’s no way it’s called from anywhere else than from the transition itself.

Now… after 2 weeks of intensive testing, I just got assertion error “DAMN YOU GUYS!” coming from this line.

Can anyone explain how this could happen, in a different way than by onComplete firing twice?

And no… localCallback does not call switchMove function again.

Which Corona build are you on?

2187

I put this assert in there many versions ago, we are experiencing similar issues since transitions 2.0, but it’s a first time I cannot find any other explanation.

I believe the new public release / daily build 2189 resolves the transition issues, can you confirm?

Oh god no.

2189 screws things up even more!

Right now I got loads of errors after switching to 2189 - display objects try to be removed twice etc. Everything because of onComplete.

Hi @krystian6,

Please post some new and updated code which is showing/proving these issues. So far we don’t have anybody else reporting these, so it’s hard to judge what may be occurring internally.

Thanks,

Brent

@krystian6:

Since you use some variables for which i can’t predict specific behavior ( like p, target ), i stripped down your example a bit:

local function doSomething ( time, x, y, callback ) local i = 0 local localCallback = callback local myObject = display.newRect( 100, 100, 50, 50 ) local t local function switchMoveComplete(target) i = i + 1 assert(i \< 2, "DAMN YOU GUYS!") if t then transition.cancel( t ) t = nil end --if localCallback then localCallback(target) end end t = transition.to(myObject, { time = time, x = x, y = y, transition = easing.inOutQuad, onComplete = switchMoveComplete }) end doSomething( 100, 200, 200 )

That runs ok in the latest daily ( public release ). Please either provide a more complete example or file a bug report with a more complete example, i’m almost sure there’s something else in your code that triggers the error.

Thanks in advance,

alex

Hello guys,

I am using the new daily build now, and I will post my findings when I have something concrete.

The variables coming in don’t affect the example code.

p is just a table, target… oh come on :wink: that’s what’s coming from transition onComplete call :wink:

Everywhere in my code, whenever I create a transition I have to assign the transition reference somewhere and cancel explicitly the transition in onComplete. That’s why this error was so suspicious, because it happened even though transition was cancelled.

Anyway… It took a while to trigger this assertion before, I doubt it will happen anytime soon.

Another report.

I’ve updated to  2014.2197

Here’s a code:

    

-- current used in a function below is a display object lg.sendItemToUpgrade = function(event) &nbsp;local rect = display.newRect(pepper.x, pepper.y, 30, 30) &nbsp; &nbsp; &nbsp; &nbsp; local i = 1 &nbsp; &nbsp; &nbsp; &nbsp; local function upgradeSimilarItems() &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; i = i + 1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; assert(i \< 3, "HA :D") &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; rect:removeSelf() &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; rect = nil &nbsp; &nbsp; &nbsp; &nbsp; end &nbsp; &nbsp; &nbsp; &nbsp; transition.to(rect, { time = properties.speedRectangle, x = current.x, y = current.y, onComplete = upgradeSimilarItems, transition = easing.inQuad }) &nbsp; &nbsp; end &nbsp;

And I just got:

Runtime error /Users/krystian/projects/***.lua:199: HA :smiley:

I think the onComplete issue didn’t go away.

EDIT:

removed to much code, rect is created every time function is called

Krystian,

The new code you posted clears the waters a bit. 

First, a slightly modified version that does not take an event as param, and which works ok:

local function sendItemToUpgrade( object ) local i = 1 local function upgradeSimilarItems() i = i + 1 assert(i \< 3, "HA :D") object:removeSelf() object = nil end transition.to(object, { time = 100, x = object.x + 100, y = object.y + 100, onComplete = upgradeSimilarItems, transition = easing.inQuad }) end local obj = display.newRect( 100, 100, 50, 50 ) sendItemToUpgrade( obj )

In your case, i believe the culprit is that your function executes in all the event phases, thus triggering multiple transitions that happen in the same timeframe ( and that’s why you don’t see any visual difference ), and of course executing the onComplete function multiple times. 

Could that be the case?

Thanks,

alex

Alex, I’m using event dispatcher to communicate with my special effects layer, where this code comes from.

As you can see in my edit, the object used in transition is created within the function.

Ok, then i would kindly ask you to either create a reproducible case and file it in a bug report, or provide more code that exposes how the event is being dispatched, by which objects, etc. I’m having trouble reproducing this, even with your updated code.

Thanks,

alex 

Hello guys,

I ve converted Octopuzzle (now also on Ouya) to graphics 2.0. All seems to run fine at first. But  after a few minutes, when I started clicking on the game, I noticed some sprites acting wierd. The complete function of the transition was called twice and then even more and more. My memory-usage was also increasing.

This is the code:

print("addNewLogo") obj.newlogo = display.newImage("attention.png") obj.newlogo.tween1 = function() collectgarbage(); print("tween1", "MemUsage: " .. collectgarbage("count"), "TexMem: &nbsp; " .. system.getInfo( "textureMemoryUsed" ) / 1000000 ); obj.newlogo.tween = transition.to(obj.newlogo, { rotation = 20\*math.random() -10, xScale = .8, yScale = .8, time = 900 + math.random()\*200, transition = easing.inOutQuad, onComplete = obj.newlogo.tween2}); end obj.newlogo.tween2 = function() print("tween2"); obj.newlogo.tween = transition.to(obj.newlogo, { rotation = 20\*math.random() -10, xScale = 1.3, yScale = 1.3, time = 900 + math.random()\*200, transition = easing.inOutQuad, onComplete = obj.newlogo.tween1}); end &nbsp; &nbsp; &nbsp; &nbsp; obj.newlogo.tween1()

All other references to obj.newlogo & obj.newlogo.tween are disabled. When I copy paste the code in an empty main.lua everything works fine. Octopuzzle is a large project with lots of animations and transitions. When I print everytime the newlogo.tween is called I get this:

simoutput.jpg

The memory usage keeps increasing and the game becomes slower and slower resulting in a complete crash/freeze…  :frowning:  In the simulator and on the Ipad mini. I m using the latest daily build of Corona on windows.

Hey madmulti,

Please at least post the complete code that leads you to the output image you pasted.

Thanks,

alex

Hi Alex, I ve added the print functions in the code in my post.

I also noticed that clicking the game accelerates the multiplying of the complete calls. When I don’t click; the complete-function is beeing called twice, but it takes a longer time for the function to multiply, resulting in a crash / freeze of the whole game.

Thanx for looking into this!

Hi madmulti,

Thanks for the completions. Looking into this now.

alex

I ve reconstructed the bug.

Canceling a transition in the transitions onComplete function sometimes causes other transitions to fire onComplete multiple times.

Code example with images:

http://demo.madmultimedia.nl/octo/wierdTransitions.zip

Sometimes it takes a couple of seconds to kick in.  

local octo = display.newImage("octo.png") octo.x = 100 octo.y = 100 octo.clearRotTween = function() &nbsp; &nbsp; transition.cancel(octo.rotTween) end local rotOcto = function() &nbsp; &nbsp; octo.rotTween = transition.to( octo, { &nbsp;time = 40, rotation = math.random()\*360, onComplete = octo.clearRotTween } )&nbsp; &nbsp; end timer.performWithDelay( 100, rotOcto, 0) -- ------------------------------------- local newLogo= display.newImage("new.png") newLogo.x = 300 newLogo.y = 300 newLogo.tween1 = function() &nbsp; &nbsp; collectgarbage() &nbsp;&nbsp;&nbsp;&nbsp;print("tween1", "MemUsage: " .. collectgarbage("count"), &nbsp;system.getInfo( "textureMemoryUsed" ) / 1000000 ); &nbsp; &nbsp; newLogo.curTween = transition.to(newLogo, { rotation = 20\*math.random() -10, xScale = 1, yScale = 1, time = 900 + math.random()\*200, transition = easing.inOutQuad, onComplete = newLogo.tween2}) end newLogo.tween2 = function() &nbsp;&nbsp;&nbsp;&nbsp;print("tween2"); &nbsp; &nbsp; newLogo.curTween = transition.to(newLogo, { rotation = 20\*math.random() -10, xScale = 3, yScale = 3, time = 900 + math.random()\*200, transition = easing.inOutQuad, onComplete = newLogo.tween1}) end newLogo.tween1() &nbsp;

Ah, perfect. Thanks for this!!!

alex

Hey madmulti,

The issue should be fixed in 2014.2221. Can you please confirm?

Thanks,

alex

Edit: actually the .cancel call has some issues. I just ran more tests based on your code, and something is not ok. Looking deeper.

alex

Ah, i did some more digging and got a complete answer to this. If you define your tween as a variable instead of a object property, it works ok…

local tween

local function cleanTween()

       transition.cancel(tween)

end

local rotOcto = function()

    tween = transition.to( octo, {  time = 40, rotation = math.random()*360, onComplete = cleanTween } )    

end

If you use your approach, with the tween being part of the object table, the cancel call cancels transitions it should not.

So please use this solution as a workaround, and i’ll fix the behavior for tweens that are defined inside a LUA table.

Thanks,

alex