Runtime:removeEventListener messes up the game :(

When i try to add the Runtime:removeEventListener the game stops working, why is this happening and how to fix it ? Ps: sorry if the code is a bit messy i am new to this…

function scene:exitScene(event)  
 Runtime:removeEventListener("touch", touchScreen)  
 Runtime:removeEventListener("enterFrame", badc1)  
 Runtime:removeEventListener("collision", onCollision)  
end  

game.lua

[code]display.setStatusBar( display.HiddenStatusBar )

_W = display.contentWidth; --Returns Screen Width
_H = display.contentHeight; --Returns Screen Height
local cloudTable = {} – Set up cloud table
– requires
local physics = require “physics”
physics.start()

local storyboard = require (“storyboard”)
local scene = storyboard.newScene()

– storyboard functions

function scene:createScene(event)
local screenGroup = self.view

background = display.newImage(‘bg.png’)
greenfieldhangar = display.newImage(“greenfieldhangar1.png”)
greenfieldhangar:setReferencePoint(display.BottomLeftReferencePoint)
greenfieldhangar.y = 520
transition.to(greenfieldhangar, {time = 9000, x = 0, y = 700})

Helicopter = display.newImage(“Helicopter.png”)
Helicopter.x = 150
Helicopter.y = 200
–Helicopter: setReferencePoint(display.BottomLeftReferencePoint)
–transition.to(Helicopter, {time = 3000, x = 99, y = 300})
physics.addBody(Helicopter, “dynamic”, {densit=.1, bounce=0.1, friction=.2, radius=45})

badc1 = display.newImage(“Bad1.png”)
badc1.x = 300
badc1.y = 50
badc1.speed = math.random (2,6)
badc1.initY = badc1.y
badc1.amp = math.random (20,100)
badc1.angle = math.random (1,360)
physics.addBody(badc1, “static”, {densit=.1, bounce=0.1, friction=.2, radius=45})

end

function movebadc1(self,event)
if self.x < -50 then
self.x =300
self.y = 300
self.speed = math.random (2,6)
self.initY = self.y
self.amp = math.random (20,100)
self.angle = math.random (1,360)

else
self.x = self.x - self.speed
self.angle = self.angle + .1
self.y = self.amp * math.sin(self.angle)+self.initY
end
end

function activateHelicopters(self,event)
self:applyForce(0, -1.5, self.x, self.y)
–print(“run”)
end
function touchScreen(event)
–print(“touch”)
if event.phase == “began” then
Helicopter.enterFrame = activateHelicopters
Runtime:addEventListener(“enterFrame”, Helicopter)
end

if event.phase == “ended” then
Runtime:removeEventListener(“enterFrame”, Helicopter)
end

end

function onCollision(event)
if event.phase == “began” then
–print(“collide!!”)
storyboard.gotoScene(“restart”)
end
end

function scene:enterScene(event)

Runtime:addEventListener(“touch”, touchScreen)
badc1.enterFrame = movebadc1
Runtime:addEventListener(“enterFrame”, badc1)
Runtime:addEventListener(“collision”, onCollision)

end

function scene:exitScene(event)
end

function scene:destroyScene(event)

end

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

return scene
[/code]

Regards Kevin [import]uid: 225288 topic_id: 35798 reply_id: 335798[/import]

I ran into the same problem when I was learning Storyboard. Hopefully a Corona staffmember can weight in, but the only way I found to resolve the issue of removing Runtime listeners is to add in a variable to listen to when the scene is left which removes that Runtime listener. For example:
 

local function moveCamera() if Game.isPlaying == true then -- do something if Game.isPlaying == false then Runtime:removeEventListener("enterFrame", moveCamera) end Runtime:addEventListener("enterFrame", moveCamera)

Maybe there’s a better way to do it, but I haven’t found it. [import]uid: 135394 topic_id: 35798 reply_id: 142399[/import]

Thanks ajaxzon!!!
[import]uid: 225288 topic_id: 35798 reply_id: 142416[/import]

Can you be a bit more specific by what you mean “it stops working”? Are you getting an error? [import]uid: 199310 topic_id: 35798 reply_id: 142433[/import]

Hi Rob,
I managed to fix it with ajaxzon’s advise.
[import]uid: 225288 topic_id: 35798 reply_id: 142480[/import]

@Rob, the issue that is being experienced here is that, attempting to remove a Runtime event listener by the same method you would remove another event listener (on ExitScene, DestroyScene, etc.) does not work. Meaning, the Runtime listener keeps running! I posted about this a few months ago but never heard from anyone, so I assumed it was working as designed. The workaround I found was the above. Should we be able to remove Runtime listeners in scene changes when using Storyboard? Let us know. Thanks! [import]uid: 135394 topic_id: 35798 reply_id: 142482[/import]

I bet I know what the problem is. It’s kind of complex but here goes.

When you do:

Runtime:addEventListener("enterFrame", moveCamera)  

What you really are doing is something like this:

Runtime:addEventListener("enterFrame", 0x10294837)  

Which is the address of where that function lives. That address gets registered in the list of event handlers that need serviced.

If you do in createScene()

 local function moveCamera()  
 ...  
 end  

The variable moveCamera is scoped to that function only and when you try to remove it later in exitScene, what is actually done is:

Runtime:addEventListener("enterFrame", 0)  

since exitScene doesn’t know what “moveCamera” is. Moving that function out of createScene and into the module’s chunk would fix that too.

[import]uid: 199310 topic_id: 35798 reply_id: 142557[/import]

@Rob, so you’re saying that any Runtime function should be running outside of the scene functions? So simple… we should have thought of that! Thanks Rob! [import]uid: 135394 topic_id: 35798 reply_id: 142560[/import]

Or at least scope the variable/function name outside the storyboard functions. [import]uid: 199310 topic_id: 35798 reply_id: 142565[/import]

I ran into the same problem when I was learning Storyboard. Hopefully a Corona staffmember can weight in, but the only way I found to resolve the issue of removing Runtime listeners is to add in a variable to listen to when the scene is left which removes that Runtime listener. For example:
 

local function moveCamera() if Game.isPlaying == true then -- do something if Game.isPlaying == false then Runtime:removeEventListener("enterFrame", moveCamera) end Runtime:addEventListener("enterFrame", moveCamera)

Maybe there’s a better way to do it, but I haven’t found it. [import]uid: 135394 topic_id: 35798 reply_id: 142399[/import]

Thanks ajaxzon!!!
[import]uid: 225288 topic_id: 35798 reply_id: 142416[/import]

Can you be a bit more specific by what you mean “it stops working”? Are you getting an error? [import]uid: 199310 topic_id: 35798 reply_id: 142433[/import]

Hi Rob,
I managed to fix it with ajaxzon’s advise.
[import]uid: 225288 topic_id: 35798 reply_id: 142480[/import]

@Rob, the issue that is being experienced here is that, attempting to remove a Runtime event listener by the same method you would remove another event listener (on ExitScene, DestroyScene, etc.) does not work. Meaning, the Runtime listener keeps running! I posted about this a few months ago but never heard from anyone, so I assumed it was working as designed. The workaround I found was the above. Should we be able to remove Runtime listeners in scene changes when using Storyboard? Let us know. Thanks! [import]uid: 135394 topic_id: 35798 reply_id: 142482[/import]

I bet I know what the problem is. It’s kind of complex but here goes.

When you do:

Runtime:addEventListener("enterFrame", moveCamera)  

What you really are doing is something like this:

Runtime:addEventListener("enterFrame", 0x10294837)  

Which is the address of where that function lives. That address gets registered in the list of event handlers that need serviced.

If you do in createScene()

 local function moveCamera()  
 ...  
 end  

The variable moveCamera is scoped to that function only and when you try to remove it later in exitScene, what is actually done is:

Runtime:addEventListener("enterFrame", 0)  

since exitScene doesn’t know what “moveCamera” is. Moving that function out of createScene and into the module’s chunk would fix that too.

[import]uid: 199310 topic_id: 35798 reply_id: 142557[/import]

@Rob, so you’re saying that any Runtime function should be running outside of the scene functions? So simple… we should have thought of that! Thanks Rob! [import]uid: 135394 topic_id: 35798 reply_id: 142560[/import]

Or at least scope the variable/function name outside the storyboard functions. [import]uid: 199310 topic_id: 35798 reply_id: 142565[/import]

If you scope local functions outside of the storyboard functions then what happens to them after scene changes? Should they be removed manually or are they cleared through a remove scene call? Coming from director I’ve never been completely clear about how storyboard handles cleaning.

Code outside of createScene, enterScene, etc. is part of the module.  That module stays in memory (but is not reloaded on re-entry) unless the module gets unloaded.   This is not a memory leak and unless you have a really big table of data, not even a real memory concern. 

Thank you Rob, very fast response.