SSK2 - Removing listeners

Sorry if this is a silly question, but it’s about the easy listener function in the display factories.

I’m going to use your example code here for ease.

local function onEnterFrame( self ) self.x = self.x + 1 if( self.x \>= right ) then self.x = right ignore( "enterFrame", self ) self.enterFrame = nil end end newCircle( nil, left, centerY, { enterFrame = onEnterFrame } )

Now obviously, when the object reaches the end the listener is removed.  What I would like to know is if the circle is hit by a bullet before it reaches the end and the circle removed using display.remove, do I have to ignore the listener first before removing the display object, or is it done automatically when the object is removed?

This is not a silly question.  It is actually a common stumbling block for folks using Runtime listeners.
 
First, remember that listen is SSK2 shorthand for Runtime:addEventListener. i.e. We are talking about Runtime listeners here.
 
Second, Runtime listeners are NOT automatically removed in any situation.
 
Third, to answer your specific question…
 
SSK2 provides some ways to handle this:
 
Best Method (take advantage of finalize event):

local tmp = newCircle( nil, left, centerY, { enterFrame = onEnterFrame } ) function tmp.finalize( self ) ignore( "enterFrame", self ) end tmp:addEventListener( "finalize" )

Can also be written like this:

local function finalize( self ) -- If any of these listeners is attached to the object stop and remove them. ignoreList( { "enterFrame", "accelerometer", "onTwoTouchLeft", "myEvent" } , self ) end local tmp = newCircle( nil, left, centerY, { enterFrame = onEnterFrame, finalize = finalize } )

Second Best, use the autoIgnore() helper:

local function onEnterFrame( self ) -- Abort if the object was deleted AND remove the listener if( autoIgnore("enterFrame",self) ) then return end self.x = self.x + 1 if( self.x \>= right ) then self.x = right ignore( "enterFrame", self ) self.enterFrame = nil end end newCircle( nil, left, centerY, { enterFrame = onEnterFrame } ) 

This is a bit lazy and has a hidden cost since the code executes every frame.  Nontheless, I use this methodlogy often when I know there are only a few of these objects.

There is third (more advanced) way SSK2 helps you if you have a number of Runtime and custom listeners attached to an object:

local tmp = newCircle( nil, left, centerY, { enterFrame = onEnterFrame } ) function tmp.finalize( self ) -- If any of these listeners is attached to the object stop and remove them. ignoreList( { "enterFrame", "accelerometer", "onTwoTouchLeft", "myEvent" } , self ) end tmp:addEventListener( "finalize" )

I created this helper to keep my code legible and because I’m even too lazy to do this:

local tmp = newCircle( nil, left, centerY, { enterFrame = onEnterFrame } ) function tmp.finalize( self ) ignore( "enterFrame", self ) ignore( "accelerometer", self ) ignore( "onTwoTouchLeft", self ) ignore( "myEvent", self ) end tmp:addEventListener( "finalize" )

Brilliant.  Thanks Ed that clears things up for me (pun intended).

Before you go though, on a similar note, is it also necessary to remove physics bodies?

Nope.  Physics bodies are removed automatically when you delete the object they are attached to.

Sweet.  Thank you.

This is not a silly question.  It is actually a common stumbling block for folks using Runtime listeners.
 
First, remember that listen is SSK2 shorthand for Runtime:addEventListener. i.e. We are talking about Runtime listeners here.
 
Second, Runtime listeners are NOT automatically removed in any situation.
 
Third, to answer your specific question…
 
SSK2 provides some ways to handle this:
 
Best Method (take advantage of finalize event):

local tmp = newCircle( nil, left, centerY, { enterFrame = onEnterFrame } ) function tmp.finalize( self ) ignore( "enterFrame", self ) end tmp:addEventListener( "finalize" )

Can also be written like this:

local function finalize( self ) -- If any of these listeners is attached to the object stop and remove them. ignoreList( { "enterFrame", "accelerometer", "onTwoTouchLeft", "myEvent" } , self ) end local tmp = newCircle( nil, left, centerY, { enterFrame = onEnterFrame, finalize = finalize } )

Second Best, use the autoIgnore() helper:

local function onEnterFrame( self ) -- Abort if the object was deleted AND remove the listener if( autoIgnore("enterFrame",self) ) then return end self.x = self.x + 1 if( self.x \>= right ) then self.x = right ignore( "enterFrame", self ) self.enterFrame = nil end end newCircle( nil, left, centerY, { enterFrame = onEnterFrame } ) 

This is a bit lazy and has a hidden cost since the code executes every frame.  Nontheless, I use this methodlogy often when I know there are only a few of these objects.

There is third (more advanced) way SSK2 helps you if you have a number of Runtime and custom listeners attached to an object:

local tmp = newCircle( nil, left, centerY, { enterFrame = onEnterFrame } ) function tmp.finalize( self ) -- If any of these listeners is attached to the object stop and remove them. ignoreList( { "enterFrame", "accelerometer", "onTwoTouchLeft", "myEvent" } , self ) end tmp:addEventListener( "finalize" )

I created this helper to keep my code legible and because I’m even too lazy to do this:

local tmp = newCircle( nil, left, centerY, { enterFrame = onEnterFrame } ) function tmp.finalize( self ) ignore( "enterFrame", self ) ignore( "accelerometer", self ) ignore( "onTwoTouchLeft", self ) ignore( "myEvent", self ) end tmp:addEventListener( "finalize" )

Brilliant.  Thanks Ed that clears things up for me (pun intended).

Before you go though, on a similar note, is it also necessary to remove physics bodies?

Nope.  Physics bodies are removed automatically when you delete the object they are attached to.

Sweet.  Thank you.