Display object losing the addEventListener function

In my storyboard createScene function I am adding a series of nested display groups, at the heart of which is a group of images. Once the enterScene function is called I can no longer add event listener functions (in this case for the ‘tap’ event) to the images because the addEventListener function throws an exception and appears to be nil as a value of the object table.

Is this a known issue, are there caveats to using the storyboard api and display groups and event handlers or should I post my code? (It is quite long, has many related files and I would most likely end up posting my entire app, which I’m loathed to do right now.)

Thanks,

Matt. [import]uid: 8271 topic_id: 21118 reply_id: 321118[/import]

Right, illness and lack of sleep are the enemy of the coder, so here’s the solution. It’s not actually a storyboard problem but a function reference issue…

The code follows and you don’t need to be able to run it, because I was assuming that the function ‘addEventListener’ was suddenly no longer available on the display object (a png) but in fact it was the function I was referencing as the event handler which could not be asserted (which means ‘found’ by the runtime).

The broken version was this:

[lua]scene.levelselect = function( event )
print( event )
end

– Called immediately after scene has moved onscreen:
function scene:enterScene( event )
local group = self.view

local sectiongroup = group[storyboard.selectedsection]
for i=1, sectiongroup.numChildren do
local levelgroup = sectiongroup[i]
levelgroup.icon:addEventListener( “tap”, scene.selectlevel )
end
end[/lua]
The working version is this:

[lua]function scene:levelselect( event )
print( event )
end

– Called immediately after scene has moved onscreen:
function scene:enterScene( event )
local group = self.view

local sectiongroup = group[storyboard.selectedsection]
for i=1, sectiongroup.numChildren do
local levelgroup = sectiongroup[i]
levelgroup.icon:addEventListener( “tap”, self.levelselect )
end
end[/lua]
[import]uid: 8271 topic_id: 21118 reply_id: 83532[/import]

One problem left remaining with this implementation is that the parameter argument received by the levelselect function is always nil.

Could anyone tell me why please?

My only solution at present is to make the function local and not a member of the scene object, which I really don’t feel is OO enough for my tastes.

Matt. [import]uid: 8271 topic_id: 21118 reply_id: 83646[/import]

True!

Your solution work for me.

Dunno Matt, seems that levelselect is a private function that gets called on tap.  As a private function, it should be okay as a local.  I don’t have much experience setting up event handlers that way.  Normally for object  handlers you do:

object.tap = levelselect

object:addEventListener(“tap”, object)

But it seems to me that you’re trying to add a method that belongs to the scene object to an icon object.  Hopefully someone with a bit more OOP background can sort this out for you.  I suspect though that it’s an issue with the self.levelselect vs. self:levelselect.  In your function def the first parameter is really “self” but it’s hidden.  By using self.levelselect the dispatcher might not be passing self in as your function expects.

Crikey, totally forgot about this thread.

I think I hit the same problem recently, but it is more about the scope of the listener function. If the function is attached to the object with ‘.’ and not ‘:’ the first parameter, of course, should be ‘self’.

I’d forgotten this and then resolved a similar, storyboard-related, problem today.

Hi Matt,

It looks like there’s actually just a typo in the original version of your code.  The non-working snippet you pasted in your second post defined the function as scene.levelselect, but it attempted to add the listener as scene.selectlevel (‘select’ and ‘level’ are reversed).  I’d think the code would run fine without the typo.

  • Andrew

Yup, that’s a good point too.

True!

Your solution work for me.

Dunno Matt, seems that levelselect is a private function that gets called on tap.  As a private function, it should be okay as a local.  I don’t have much experience setting up event handlers that way.  Normally for object  handlers you do:

object.tap = levelselect

object:addEventListener(“tap”, object)

But it seems to me that you’re trying to add a method that belongs to the scene object to an icon object.  Hopefully someone with a bit more OOP background can sort this out for you.  I suspect though that it’s an issue with the self.levelselect vs. self:levelselect.  In your function def the first parameter is really “self” but it’s hidden.  By using self.levelselect the dispatcher might not be passing self in as your function expects.

Crikey, totally forgot about this thread.

I think I hit the same problem recently, but it is more about the scope of the listener function. If the function is attached to the object with ‘.’ and not ‘:’ the first parameter, of course, should be ‘self’.

I’d forgotten this and then resolved a similar, storyboard-related, problem today.

Hi Matt,

It looks like there’s actually just a typo in the original version of your code.  The non-working snippet you pasted in your second post defined the function as scene.levelselect, but it attempted to add the listener as scene.selectlevel (‘select’ and ‘level’ are reversed).  I’d think the code would run fine without the typo.

  • Andrew

Yup, that’s a good point too.