removing transition.to

how to remove the transition.to (line 39-48) so that it won’t give memory leaks?
As you can see the function animCloud( ) purpose is to make the cloud image running on top of the screen from right to left nonstop.

Can someone teach me how to remove it when we are leaving this current scene and go to next one (when menuPlayBtn is pressed/touched).

Thank you

[code]

– mainmenu.lua
local storyboard = require( “storyboard” )
local scene = storyboard.newScene()

– BEGINNING OF YOUR IMPLEMENTATION

local function onSceneTouch( self, event )
if event.phase == “began” then
storyboard.gotoScene( “gamescene”, “slideUp”, 800 )
return true
end
end

– Called when the scene’s view does not exist:
function scene:createScene( event )
local menuGroup = self.view

mainBg = display.newImageRect(“images/menubg.png”, 820, 960);
mainBg.x = _W/2;
mainBg.y = _H/2;
mainTitle = display.newImageRect(“images/title.png”, 624, 278);
mainTitle.x = _W/2;
mainTitle.y = _H/2 - 200;
mainCity = display.newImageRect(“images/city.png”, 1640, 450);
mainCity:setReferencePoint(display.BottomLeftReferencePoint);
mainCity.x = -40;
mainCity.y = 918;
mainCloud = display.newImageRect(“images/clouds.png”, 1640, 250);
mainCloud:setReferencePoint(display.TopLeftReferencePoint);
mainCloud.x = -40;
mainCloud.y = 0;

menuPlayBtn = display.newImageRect(“images/play.png”, 126, 50);
menuPlayBtn.x = _W/2 + 10;
menuPlayBtn.y = 580;
menuPlayBtn.touch = onSceneTouch;

function animCloud()
mainCloud.x = -40;
mainCloud.y = 0;
local anim;
anim = transition.to(mainCloud, {
time = 100000,
x = -40 - 820,
y = 0,
onComplete = animCloud})
end

animCloud();

menuGroup:insert(mainBg);
menuGroup:insert(mainTitle);
menuGroup:insert(mainCity);
menuGroup:insert(mainCloud);
menuGroup:insert(menuPlayBtn);

end

– Called immediately after scene has moved onscreen:
function scene:enterScene( event )
local group = self.view
menuPlayBtn:addEventListener(“touch”, menuPlayBtn);
end

– Called when scene is about to move offscreen:
function scene:exitScene( event )
local group = self.view

menuPlayBtn:removeEventListener(“touch”, menuPlayBtn)
end
– Called prior to the removal of scene’s “view” (display group)
function scene:destroyScene( event )
local group = self.view
menuPlayBtn:removeEventListener(“touch”, menuPlayBtn)
end


– END OF YOUR IMPLEMENTATION

scene:addEventListener( “createScene”, scene )
scene:addEventListener( “enterScene”, scene )
scene:addEventListener( “exitScene”, scene )
scene:addEventListener( “destroyScene”, scene )

return scene
[/code] [import]uid: 31508 topic_id: 32211 reply_id: 332211[/import]

I think I would use a timer to call that function repeatedly, rather than having the transition effectively calling itself - which would make it recursive and therefore use increasing amounts of memory (each iteration would never get garbage collected because it never actually ends.)

  1. Remove line 47: [lua]onComplete=animCloud[/lua]
  2. Add after line 50: [lua]local animCloudTimer = timer.performWithDelay(100000, animCloud, 0)[/lua]

Oh fyi, you don’t need ‘;’ at the end of every line, only between multiple statements on single lines. [import]uid: 8271 topic_id: 32211 reply_id: 128249[/import]

Thank you,
your code works.

Now how to do the removing of the transition when scene changed?
Do we also have to nil the animCloudTimer at exitScene? [import]uid: 31508 topic_id: 32211 reply_id: 128251[/import]

As long as you have a reference to the [lua]animCloudTimer[/lua] value, you can call [lua]transition.cancel( animCloudTimer ); animCloudTimer = nil;[/lua] and the transition will be cancelled and it’s memory object removed. [import]uid: 8271 topic_id: 32211 reply_id: 128257[/import]

What about the variable anim inside the function? That’s where the real transition.to .

And where should I put the transition.cancel(animCloudTimer) ?
I tried putting it under the exitScene but give error “attempt to index a nil value”. [import]uid: 31508 topic_id: 32211 reply_id: 128259[/import]

Yes, [lua]anim[/lua] does the same thing as my [lua]animCloudTimer[/lua] value.

For cancelling the transition, you need to make sure that the [lua]animCloudTimer[/lua] value is available throughout the scene. I suggest replacing lines 39 to 50:
[lua] function animCloud()
mainCloud.x = -40;
mainCloud.y = 0;
scene.animCloud = transition.to(mainCloud, {
time = 100000,
x = -40 - 820,
y = 0 )
end

animCloud()
scene.animCloudTimer = timer.performWithDelay(100000, animCloud, 0)[/lua]

And follow it with:
[lua]function scene:exitScene( event )
local group = self.view

transition.cancel( scene.animCloud )
scene.animCloud = nil

timer.cancel( scene.animCloudTimer )
scene.animCloudTimer = nil

menuPlayBtn:removeEventListener(“touch”, menuPlayBtn)
end[/lua] [import]uid: 8271 topic_id: 32211 reply_id: 128262[/import]

Thank you very much.
Let me give it a try :slight_smile:

Thanks again ! [import]uid: 31508 topic_id: 32211 reply_id: 128263[/import]

Your codes above didn’t work.
The cloud only move few pixels then stop.

I change into this

 function animCloud()  
 mainCloud.x = -40;  
 mainCloud.y = 0;  
 --local anim;  
 scene.animCloud = transition.to(mainCloud, {  
 time = 10000,  
 x = -40 - 820,  
 y = 0,  
 onComplete = function()  
 transition.cancel(scene.animCloud);  
 scene.animCloud = nil;  
 end  
 })  
 end  
 timer.cancel(scene.animCloudTimer);  
 scene.animCloudTimer = nil;  
 menuPlayBtn:removeEventListener("touch", menuPlayBtn)  

and it works.

Do you think it will remove the transition.to properly and avoid anymore memory leaks? [import]uid: 31508 topic_id: 32211 reply_id: 128264[/import]

…wait…

I did try your code for 2nd time,
it works !

Don’t know what I did wrong at the first time.

My next question:
what do you think of my method of using the onComplete to remove the transition.to?
[import]uid: 31508 topic_id: 32211 reply_id: 128265[/import]

Honestly, I think it’s terrible. You’re trying to remove the transition from within itself. This is bad practice and a bad instance.

I can’t say why my code didn’t work for you the first time round, but I’m sure if you copied it correctly it will work.

What you want is to create something which calls the function handling animation. Keep this separate from the code which manages creating and destroying the timer itself. I believe what I wrote provides this, but the core concept is to know where your timer and transition references are.

You only need the timer object because you also need to cancel that when you cancel the transition, but otherwise they are not tightly linked. [import]uid: 8271 topic_id: 32211 reply_id: 128269[/import]

Thank you very much :slight_smile:

I learn a lot today. [import]uid: 31508 topic_id: 32211 reply_id: 128270[/import]

I think I would use a timer to call that function repeatedly, rather than having the transition effectively calling itself - which would make it recursive and therefore use increasing amounts of memory (each iteration would never get garbage collected because it never actually ends.)

  1. Remove line 47: [lua]onComplete=animCloud[/lua]
  2. Add after line 50: [lua]local animCloudTimer = timer.performWithDelay(100000, animCloud, 0)[/lua]

Oh fyi, you don’t need ‘;’ at the end of every line, only between multiple statements on single lines. [import]uid: 8271 topic_id: 32211 reply_id: 128249[/import]

Thank you,
your code works.

Now how to do the removing of the transition when scene changed?
Do we also have to nil the animCloudTimer at exitScene? [import]uid: 31508 topic_id: 32211 reply_id: 128251[/import]

As long as you have a reference to the [lua]animCloudTimer[/lua] value, you can call [lua]transition.cancel( animCloudTimer ); animCloudTimer = nil;[/lua] and the transition will be cancelled and it’s memory object removed. [import]uid: 8271 topic_id: 32211 reply_id: 128257[/import]

What about the variable anim inside the function? That’s where the real transition.to .

And where should I put the transition.cancel(animCloudTimer) ?
I tried putting it under the exitScene but give error “attempt to index a nil value”. [import]uid: 31508 topic_id: 32211 reply_id: 128259[/import]

Yes, [lua]anim[/lua] does the same thing as my [lua]animCloudTimer[/lua] value.

For cancelling the transition, you need to make sure that the [lua]animCloudTimer[/lua] value is available throughout the scene. I suggest replacing lines 39 to 50:
[lua] function animCloud()
mainCloud.x = -40;
mainCloud.y = 0;
scene.animCloud = transition.to(mainCloud, {
time = 100000,
x = -40 - 820,
y = 0 )
end

animCloud()
scene.animCloudTimer = timer.performWithDelay(100000, animCloud, 0)[/lua]

And follow it with:
[lua]function scene:exitScene( event )
local group = self.view

transition.cancel( scene.animCloud )
scene.animCloud = nil

timer.cancel( scene.animCloudTimer )
scene.animCloudTimer = nil

menuPlayBtn:removeEventListener(“touch”, menuPlayBtn)
end[/lua] [import]uid: 8271 topic_id: 32211 reply_id: 128262[/import]

Thank you very much.
Let me give it a try :slight_smile:

Thanks again ! [import]uid: 31508 topic_id: 32211 reply_id: 128263[/import]

Your codes above didn’t work.
The cloud only move few pixels then stop.

I change into this

 function animCloud()  
 mainCloud.x = -40;  
 mainCloud.y = 0;  
 --local anim;  
 scene.animCloud = transition.to(mainCloud, {  
 time = 10000,  
 x = -40 - 820,  
 y = 0,  
 onComplete = function()  
 transition.cancel(scene.animCloud);  
 scene.animCloud = nil;  
 end  
 })  
 end  
 timer.cancel(scene.animCloudTimer);  
 scene.animCloudTimer = nil;  
 menuPlayBtn:removeEventListener("touch", menuPlayBtn)  

and it works.

Do you think it will remove the transition.to properly and avoid anymore memory leaks? [import]uid: 31508 topic_id: 32211 reply_id: 128264[/import]

…wait…

I did try your code for 2nd time,
it works !

Don’t know what I did wrong at the first time.

My next question:
what do you think of my method of using the onComplete to remove the transition.to?
[import]uid: 31508 topic_id: 32211 reply_id: 128265[/import]

Honestly, I think it’s terrible. You’re trying to remove the transition from within itself. This is bad practice and a bad instance.

I can’t say why my code didn’t work for you the first time round, but I’m sure if you copied it correctly it will work.

What you want is to create something which calls the function handling animation. Keep this separate from the code which manages creating and destroying the timer itself. I believe what I wrote provides this, but the core concept is to know where your timer and transition references are.

You only need the timer object because you also need to cancel that when you cancel the transition, but otherwise they are not tightly linked. [import]uid: 8271 topic_id: 32211 reply_id: 128269[/import]