Event handlers - inside or outside the function?

I have a question I haven’t been able to figure out by reading the forums, documentation, and looking through sample code. Let’s say I want a function to create an object (like a game character). I expect to create a lot of these. I’ve seen it done this way:

[lua]function createCharacter(params)

local myCharacter = display.newImage(“character.png”)
– create the character, add physics, set status, insert in groups, etc.

function myCharacter:touch(event) – for some reason this gives an error when it’s local. Maybe it’s destroyed when function ends?
– handle touch event, there could be a lot in here, calling other functions, etc.
return true
end

function myCharacter:collision(event)
– handle collision event, there could be a lot in here, calling other functions, etc.
return true
end

myCharacter:addEventListener( “touch”, myCharacter )
myCharacter:addEventListener( “collision”, myCharacter )

return myCharacter

end[/lua]

But this gets messy, because my touch and collision event handlers are long and complex. And does this create a different copy of the collision and touch handlers every time I call createCharacter?

If I put the touch and collision event handlers outside the function like this:

[lua]local function myCharacterTouchHandler(self,event)
– handle touch event, there could be a lot in here, calling other functions, etc.
return true
end

local function myCharacterCollisionHandler(self,event)
– handle collision event, there could be a lot in here, calling other functions, etc.
return true
end

function createCharacter(params)

local myCharacter = display.newImage(“character.png”)
– add physics, set status, insert in groups, etc.

myCharacter.touch = myCharacterTouchHandler
myCharacter:addEventListener( “touch”, myCharacterTouchHandler )
– I notice this also works: myCharacter:addEventListener( “touch”, myCharacter )

myCharacter.collision = myCharacterCollisionHandler
myCharacter:addEventListener( “collision”, myCharacterCollisionHandler)

return myCharacter

end[/lua]

Is the second way the “right” way to handle this, when you’re running the createCharacter multiple times?
[import]uid: 49372 topic_id: 9162 reply_id: 309162[/import]

I’m actually interested in this too. I have an opinion (which is likely wrong) so Ill wait till someone more knowledgeable replys… but great question s2alexan. [import]uid: 37036 topic_id: 9162 reply_id: 33448[/import]

“Does this create a different copy of the collision and touch handlers every time I call createCharacter? Is the second way the “right” way to handle this?”
Yes and yes.

In your first version, you’re creating a new function every time. This actually a very good feature of Lua when used properly. Google “lua closures” to read about it.
The second version creates only two functions.
Watch out about what you read/get from the forum/code exchange. A lot of people give advice/code without fully understanding what they are writing. Always try to understand a concept/technique before using it.
Even the heavily-used Director class by Ricardo is not all mighty. I actually don’t use it as I prefer my own version.

Anyway, you shouldn’t just trust my words and see it by yourself:
[lua]function createCharacter1(params)

local myCharacter = display.newGroup()
– create the character, add physics, set status, insert in groups, etc.

function myCharacter:touch(event) – for some reason this gives an error when it’s local. Maybe it’s destroyed when function ends?
– handle touch event, there could be a lot in here, calling other functions, etc.
return true
end

function myCharacter:collision(event)
– handle collision event, there could be a lot in here, calling other functions, etc.
return true
end

myCharacter:addEventListener( “touch”, myCharacter )
myCharacter:addEventListener( “collision”, myCharacter )

return myCharacter

end

local a = createCharacter1()
local b = createCharacter1()
local c = createCharacter1()

print( “Version 1:” )
print (a.touch)
print (b.touch)
print (c.touch)
local function myCharacterTouchHandler(self,event)
– handle touch event, there could be a lot in here, calling other functions, etc.
return true
end

local function myCharacterCollisionHandler(self,event)
– handle collision event, there could be a lot in here, calling other functions, etc.
return true
end

function createCharacter2(params)

local myCharacter = display.newGroup()
– add physics, set status, insert in groups, etc.

myCharacter.touch = myCharacterTouchHandler
myCharacter:addEventListener( “touch”, myCharacterTouchHandler )
– I notice this also works: myCharacter:addEventListener( “touch”, myCharacter )

myCharacter.collision = myCharacterCollisionHandler
myCharacter:addEventListener( “collision”, myCharacterCollisionHandler)

return myCharacter

end
local d = createCharacter2()
local e = createCharacter2()
local f = createCharacter2()

print( “\nVersion 2:” )
print (d.touch)
print (e.touch)
print (f.touch)[/lua]

[import]uid: 51516 topic_id: 9162 reply_id: 33465[/import]

Thanks for the detailed reply - especially the bit about understanding the code before using it. There’s a lot of stuff out there that “works”, but I’m always a bit suspicious if I don’t know HOW it works.

I’m going to read up on lua closures, seems like a powerful feature.

And I did try the code - I had no idea each function had an actual ID, learned something else today too! [import]uid: 49372 topic_id: 9162 reply_id: 33501[/import]

Well, functions are first-class values in Lua. Meaning they behave like any other value. Creating a function using the standard syntax:
[lua]local function myFunc()
end[/lua]

is just syntactic sugar for this:
[lua]local myFunc = function()
end[/lua]

As you can see, myFunc is NOT the function, just a variable holding a reference to that particular function. That’s why you can do in both cases:
[lua]local sameFunc = myFunc
sameFunc()[/lua] [import]uid: 51516 topic_id: 9162 reply_id: 33548[/import]