How to pass additional arguments / parameters to an event listener

Is it possible to pass other parameters, in addition to the event, to an event listener?
May I please have an example?

Thanks! [import]uid: 4621 topic_id: 1600 reply_id: 301600[/import]

you can if you do for example

timer.performWithDelay(200, listenerFunction);  

The example above could be also called this way

timer.performWithDelay(200, function() listenerFunction(arg1, arg2, arg3); end);  

hope this helps.
[import]uid: 6317 topic_id: 1600 reply_id: 4609[/import]

I appreciate your reply. I am still confused though.

Here is my specific example where I need to apply this.

I’d like to pass an argument to the buttonHandlerScreen1 event handler in the onPress line of the ui.newButton code block.

Thanks!

[lua]local buttonHandlerScreen1 = function ( event )
if not screen1.isVisible then
screen1.isVisible = true
screen2.isVisible = false
screen3.isVisible = false
transition.from(screen1, {time=500, alpha=0})
end
end

local buttonImageScreen1 = ui.newButton{
default = “up.png”,
over = “over.png”,
onPress = buttonHandlerScreen1,
id = “buttonImageScreen1”
}[/lua] [import]uid: 4621 topic_id: 1600 reply_id: 4645[/import]

You can’t pass any parameters but you could call a specific listener that could call another function with a parameter. Not sure if that helps. [import]uid: 7559 topic_id: 1600 reply_id: 5338[/import]

Without specifically passing a parameter, in the case where multiple objects use the same listener, is there any way to check which object triggered the listener?

I thought “target” could take care of that, but for target always returns a different value, which pretty much rules out the idea that “target” is the object which triggered the listener. [import]uid: 4920 topic_id: 1600 reply_id: 5403[/import]

How do you create the eventlistener (code)? I use a lot of transition.to commands with an OnComplete listener and there target is the object the event is dealing with. [import]uid: 5712 topic_id: 1600 reply_id: 5412[/import]

You can always add your own parameter to the button object and read it in your Listener routine.

buttonImageScreen1.parm1 = "my own value"  

-Tom [import]uid: 7559 topic_id: 1600 reply_id: 5420[/import]

Oh, didn’t know you could add parameters to display objects. That’s brilliant. thanks! [import]uid: 4920 topic_id: 1600 reply_id: 5425[/import]

in answer to the subject, just as another self contained example for reference

[lua]local function spawnBall(event)

print("spawnBall: "… event.source.something)

end

local function newBall(someVal)

local randomPosition = 100 + math.random(200)
print("newBall: "…randomPosition)

local t2 = timer.performWithDelay(2000, spawnBall, 1)

– note t2 will be equal to event.source in the call back
t2.something = someVal…", "…randomPosition

end

newBall(“blah”)
newBall(“whatever”)[/lua] [import]uid: 6645 topic_id: 1600 reply_id: 11264[/import]

It seems like source is nil! Is there any other way to access additional parameters I added to the displayObject? So that I can tell which object calls the listener.

[code]
local function listener(event)
print (“event.source.caller”,event.source.caller) – *********always get nil*********
if( phase == “moved” ) then
– do something
end
return true
end

– put image in place
for i, names in ipairs(image_names) do
i = i-1
local img = display.newImageRect( names, img_size, img_size )

img:setReferencePoint(display.TopLeftReferencePoint)
img.x = side_space + img_space*(i%4) + img_size*(i%4)
img.y = side_space + img_space*math.floor(i/4) + img_size*math.floor(i/4)
scrollView:insert(img)

img.caller = i – pass a parameter to the listener via “caller”
img:addEventListener( “touch”, listener )
end
[/code] [import]uid: 35267 topic_id: 1600 reply_id: 23611[/import]

in that situation isnt it?

[lua]local function listener(self,event)[/lua]

can’t remember, but worth a try
[import]uid: 6645 topic_id: 1600 reply_id: 23631[/import]

You can access the image object with event.target.

[code]
local function listener(event)
print (“event.target.caller”,event.target.caller)
if( event.phase == “moved” ) then
– do something
end
return true
end

[/code] [import]uid: 7559 topic_id: 1600 reply_id: 23745[/import]

timers: listener(event) => event.source = the timer
transitions: listener(obj) => obj = the transitioned object
touch: listener(event) => event.target = the object touched

so…

for timers: [lua]
local function timerComplete(event)

print(event.source.something) – “whatever”

end

local t1=timer.performWithDelay(100, timerComplete)
t1.something=“whatever”[/lua]

for transitions: [lua]local function transitionComplete(obj)
print(obj.something) – “whatever”
end

transition.to(myObject, {time=500, delay=2500, alpha=1.0, onComplete=transitionComplete })
myObject.something=“whatever”[/lua]

[import]uid: 6645 topic_id: 1600 reply_id: 23770[/import]

@jmp909,

You are correct and we should document the event properties.

One note on touch. The event.target will be nil if there is no object associated with the touch event. Having only a global touch listener will return nil when touching a display object.
[import]uid: 7559 topic_id: 1600 reply_id: 23812[/import]

Ok, i got it now :slight_smile: Thanks for your time Tom. [import]uid: 35267 topic_id: 1600 reply_id: 24039[/import]

BTW, the OP’s question was answered by jwwtaker. [import]uid: 3953 topic_id: 1600 reply_id: 24091[/import]

@MarkHenry, If you are talking about passing other parameters to the Listener function from timer, transition, or touch calls, it won’t work unless you attach the parameters to object itself (as I mentioned previously). Any parameters within the Listener call (as in jwwtaker’s example) is ignored. [import]uid: 7559 topic_id: 1600 reply_id: 24096[/import]

@Tom. You’re right, of course. The example was incomplete, and I assumed the syntax:

Runtime:addEventListener(“touch”, function() return myFunc(params) end)

Handy for some callbacks, but not appropriate for the OP’s purpose.

And while adding a property to the event target is usually simpler, this way can be handy sometimes (at least it was for me):

local function listener(a, b) return function(event) print(event.name, event.phase, a, b) endendRuntime:addEventListener("touch", listener(1, 3))Runtime:addEventListener("tap", listener(5, 7))[/code] [import]uid: 3953 topic_id: 1600 reply_id: 24151[/import]

i don’t know if that’s a good idea. (I read anonymous functions trash the garbage colletor to some extent). I can’t say for sure though. i guess if it works and doesnt cause problems then its ok for a workaround

will check it out anyway. hadn’t thought of doing it like that

thanks
j [import]uid: 6645 topic_id: 1600 reply_id: 24155[/import]

@MarkHenryC, you get extra points for your clever design. :slight_smile:

For those following at home your solution is not passing parameters to the Listener function, but creating multiple versions of the Listener with local variables containing different values (1,3 and 5,7).

The reason the Runtime:addEventListener uses the listener function without the parenthesizes is because it needs the address of the function and not executing the function. If you add the parenthesizes it will call the listener at the time it sees the Runtime code and use the return value as the code address to be called when the event is triggered. In your example the listener gets called but it returns the address of an anonymous function and the use of Lua “closure” generates two local variables that hold the listener parameters (a and b).

Here is how the code would look if it written without the anonymous function generation:

local function listener1(event)  
 local a = 1  
 local b = 3  
 print(event.name, event.phase, a, b)  
end  
  
local function listener2(event)  
 local a = 5  
 local b = 7  
 print(event.name, event.phase, a, b)  
end  
  
Runtime:addEventListener("touch", listener1)  
Runtime:addEventListener("tap", listener2)  

This may work for a few events but your solution is better if you are creating many events. I believe the anonymous function would be garbage collected when the Runtime event is removed.

The other way to add unique parameters to each object that can be accessed in the Listener, is adding them directly to the object. The only different is you need to create object events instead of using the global Runtime event.

[code]
– Assume obj1 and obj2 are objects.

local function listener(event)
local a = event.target.a
local b = event.target.b
print(event.name, event.phase, a, b)
end

obj1:addEventListener(“touch”, listener)
obj1.a = 1
obj1.b = 3

obj2:addEventListener(“touch”, listener)
obj2.a = 5
obj2.b = 7
[/code] [import]uid: 7559 topic_id: 1600 reply_id: 24245[/import]