How to get object that got the Runtime event?

Hi,

I added runtime listener for one of my objects, so when I get “enterFrame” event, it will invoke a funciton I specified and that works fine.

Question is, how can I get the owner of that function? In other words, the object, which is table in case of Lua, that this function is attached to?

Thanks.

local test = {} test.myName = "Bob" test.enterFrame = function (self, event)    print( self.myName) -- Self is the object that got the event end Runtime:addEventListener( "enterFrame", test ) 

That was great, thanks man.

One more thing, I’m using Storyboard and was wondering that if I should manually remove objects with Runtime event listeners when I want to transit between Storyboard scenes and removing whatever was inside previous scene?

@Aidin,

Yes, the general rule of thumb is, “remove Runtime event listeners” yourself.

One easy way to do this is as follows:

function removeAllListeners(obj) obj.\_functionListeners = nil obj.\_tableListeners = nil end removeAllEventListener( Runtime ) 

From this great blog post: http://www.ludicroussoftware.com/blog/2011/08/24/remove-all-listeners/

Thanks man,

This code actually removes ALL Runtime event listeners, right? So I can add as many Runtime event listeners as I want and just call this once in like ExitScene, correct?

Thanks.

Actually I’m going to have to disagree with Ed on this one.  While the technique is valid, “all” means **ALL**.  This will kill any suspend/resume events, key events, and memory warning events you may have defined in your main.lua.  Any runtime events used by widgets or storyboard itself or any used by 3rd party modules that you may not be aware of will also be removed this way.  Any listener that’s on the Runtime will be removed regardless of who put it there.

I use a simple technique.   I add them in enterScene() and I copy them to exitScene() and just change the “add” to “remove” in the name.

@Adiin (and all future readers) 

If you’re still following this thread, Rob has a valid point.  In fact, I also follow the same method (add in create(), willenter(), or enter(), remove in exit(), didexit(), or remove()).  Why?  As Rob aptly states, the method I showed doesn’t care what it removes.  It just gets rid of everything.  This may be fine if you know exactly what you’re doing, but otherwise could cause you lots of grief.

@Rob,

Thanks for the followup!

-Ed

PS - I also wrote a small library some time ago (part of SSK) called gem (global event manager).  I wrote gem to allow me to register Runtime event listeners that were grouped by ‘name’.  Then, later I could remove all listeners in that ‘named’ set with a single call to my library.

If you had SSK in your project gem would look like this when used:

local function onEnterFrame( event ) end local function onTouch( event ) end ssk.gem:add( "enterFrame", onEnterFrame, "Level1Listener" ) ssk.gem:add( "touch", onTouch, "Level1Listener" ) .. .. -- Later I could remove all listeners in the set 'Level1Listener' like this: ssk.gem:removeGroup( "Level1Listener") 

Thanks for the useful tip.

Thanks Ed,

Of course I do follow topics that I make!

Problem I have with the approach Rob, may the force be with him, and you suggested is that I attach my Runtime events in my c’tor functions of my tables, so I don’t know how to remove listeners from them.

Example:

I have this code in “new” function of my HUD class:

Runtime:addEventListener("ScoreChanged", scoreChangeEventHandler)

So when it receives this event, it would handle it. But as you can see, I don’t have, or don’t know, how to remove this function listener in my extiScene.

I know there are some magical thing with Lua and Corona that IIRC if you name your event handler as event name or something and then just register your table object, it would automatically call that function, but I’m not sure if it’s true or either this works here.

Please advice.

Thanks, I wanted to try your SSK code sometime ago but could not figure it out due to documentations.
 

@Aidin,

  1. Download and require this file in main.lua: RuntimeExtension.lua

  2. Try this code: 

    require “RuntimeExtension” local function onEnterFrameA( event )     print(“A”, event.time) end local function onEnterFrameB( event )     print(“B”, event.time) end Runtime:addEventListenerGroup( “enterFrame”, onEnterFrameA, “TestGroup” ) Runtime:addEventListenerGroup( “enterFrame”, onEnterFrameB, “TestGroup” ) timer.performWithDelay( 1000, function() Runtime:removeGroup( “TestGroup” ) end ) 

See what I’ve done?  I added a new function to Runtime that allows you to ‘group’ your runtime events.  Then, using the second function (removeGroup()) you can remove the events in a named group all at once.

Cheers,

Ed

local test = {} test.myName = "Bob" test.enterFrame = function (self, event)    print( self.myName) -- Self is the object that got the event end Runtime:addEventListener( "enterFrame", test ) 

That was great, thanks man.

One more thing, I’m using Storyboard and was wondering that if I should manually remove objects with Runtime event listeners when I want to transit between Storyboard scenes and removing whatever was inside previous scene?

@Aidin,

Yes, the general rule of thumb is, “remove Runtime event listeners” yourself.

One easy way to do this is as follows:

function removeAllListeners(obj) obj.\_functionListeners = nil obj.\_tableListeners = nil end removeAllEventListener( Runtime ) 

From this great blog post: http://www.ludicroussoftware.com/blog/2011/08/24/remove-all-listeners/

Thanks man,

This code actually removes ALL Runtime event listeners, right? So I can add as many Runtime event listeners as I want and just call this once in like ExitScene, correct?

Thanks.

Actually I’m going to have to disagree with Ed on this one.  While the technique is valid, “all” means **ALL**.  This will kill any suspend/resume events, key events, and memory warning events you may have defined in your main.lua.  Any runtime events used by widgets or storyboard itself or any used by 3rd party modules that you may not be aware of will also be removed this way.  Any listener that’s on the Runtime will be removed regardless of who put it there.

I use a simple technique.   I add them in enterScene() and I copy them to exitScene() and just change the “add” to “remove” in the name.

@Adiin (and all future readers) 

If you’re still following this thread, Rob has a valid point.  In fact, I also follow the same method (add in create(), willenter(), or enter(), remove in exit(), didexit(), or remove()).  Why?  As Rob aptly states, the method I showed doesn’t care what it removes.  It just gets rid of everything.  This may be fine if you know exactly what you’re doing, but otherwise could cause you lots of grief.

@Rob,

Thanks for the followup!

-Ed

PS - I also wrote a small library some time ago (part of SSK) called gem (global event manager).  I wrote gem to allow me to register Runtime event listeners that were grouped by ‘name’.  Then, later I could remove all listeners in that ‘named’ set with a single call to my library.

If you had SSK in your project gem would look like this when used:

local function onEnterFrame( event ) end local function onTouch( event ) end ssk.gem:add( "enterFrame", onEnterFrame, "Level1Listener" ) ssk.gem:add( "touch", onTouch, "Level1Listener" ) .. .. -- Later I could remove all listeners in the set 'Level1Listener' like this: ssk.gem:removeGroup( "Level1Listener") 

Thanks for the useful tip.

Thanks Ed,

Of course I do follow topics that I make!

Problem I have with the approach Rob, may the force be with him, and you suggested is that I attach my Runtime events in my c’tor functions of my tables, so I don’t know how to remove listeners from them.

Example:

I have this code in “new” function of my HUD class:

Runtime:addEventListener("ScoreChanged", scoreChangeEventHandler)

So when it receives this event, it would handle it. But as you can see, I don’t have, or don’t know, how to remove this function listener in my extiScene.

I know there are some magical thing with Lua and Corona that IIRC if you name your event handler as event name or something and then just register your table object, it would automatically call that function, but I’m not sure if it’s true or either this works here.

Please advice.

Thanks, I wanted to try your SSK code sometime ago but could not figure it out due to documentations.
 

@Aidin,

  1. Download and require this file in main.lua: RuntimeExtension.lua

  2. Try this code: 

    require “RuntimeExtension” local function onEnterFrameA( event )     print(“A”, event.time) end local function onEnterFrameB( event )     print(“B”, event.time) end Runtime:addEventListenerGroup( “enterFrame”, onEnterFrameA, “TestGroup” ) Runtime:addEventListenerGroup( “enterFrame”, onEnterFrameB, “TestGroup” ) timer.performWithDelay( 1000, function() Runtime:removeGroup( “TestGroup” ) end ) 

See what I’ve done?  I added a new function to Runtime that allows you to ‘group’ your runtime events.  Then, using the second function (removeGroup()) you can remove the events in a named group all at once.

Cheers,

Ed

I never remember to remove eventlisteners, so I use this code:

local eventListenerStash = {} -- Create a table to store the "listeners" local function addListener(obj, whattype, func) obj:addEventListener( whattype, func ) table.insert( eventListenerStash, #eventListenerStash + 1, {obj, whattype, func} ) end

When I want to add eventlisteners I do this:

addListener(Runtime, "enterFrame", myListener)

When I want to remove the eventlisteners I use (on scene:hide):

local function destroyEventListeners() print( "Destroying listeners") for i = #eventListenerStash, 1, -1 do eventListenerStash[i][1]:removeEventListener( eventListenerStash[i][2], eventListenerStash[i][3] ) eventListenerStash[i] = nil table.remove(eventListenerStash, i) end end destroyEventListeners()

This way I just have to add the listeners and they will be removed automatically.

It works for me :wink:

-Tom

I never remember to remove eventlisteners, so I use this code:

local eventListenerStash = {} -- Create a table to store the "listeners" local function addListener(obj, whattype, func) obj:addEventListener( whattype, func ) table.insert( eventListenerStash, #eventListenerStash + 1, {obj, whattype, func} ) end

When I want to add eventlisteners I do this:

addListener(Runtime, "enterFrame", myListener)

When I want to remove the eventlisteners I use (on scene:hide):

local function destroyEventListeners() print( "Destroying listeners") for i = #eventListenerStash, 1, -1 do eventListenerStash[i][1]:removeEventListener( eventListenerStash[i][2], eventListenerStash[i][3] ) eventListenerStash[i] = nil table.remove(eventListenerStash, i) end end destroyEventListeners()

This way I just have to add the listeners and they will be removed automatically.

It works for me :wink:

-Tom