Don't understand Gamepad sample code


On this page

There is this code

local controller = { device="", displayName="" }

local function setDevice( device, displayName )

    -- Set current controller
    controller["device"] = device
    controller["displayName"] = displayName

    -- Remove event listeners
    Runtime:removeEventListener( "axis", onAxisEvent )
    Runtime:removeEventListener( "key", onKeyEvent )

local function onKeyEvent( event )
    setDevice( event.device, event.device.displayName )

local function onAxisEvent( event )
    if ( math.abs(event.normalizedValue) > 0.5 ) then
        setDevice( event.device, event.device.displayName )

Runtime:addEventListener( "axis", onAxisEvent )
Runtime:addEventListener( "key", onKeyEvent )

I do not understand what the removeEventListener call should do and what is it for :thinking:

I first thought that this would remove the events once the gamepad is detected, but the setDevice function is called each time the controller is used!
finally, I wonder if it is really useful for something. I wonder if the function removeEventListener really does something (in this precise case).

Any explanation ?

The only function for that code is to detect a device’s input, be it key or axis event.

The moment that it has received either input, it will store the device that the input came from. Once it knows what device the input came from, then there’s no more need to listen for events and so the event listeners are removed.

This is what I thought, but I added a

print ('Used controller:', displayName)

and the print occured many times. The removeEventListener function is useless! In any case it does not remove the listener in this case !

I’ve test with the 8bitdo SN30

I found the funny problem !

Runtime:removeEventListener( "axis", onKeyEvent )

can’t work’s because the function onKeyEvent is decladed later in the script

If you put the removeEventListener into the function

local function onKeyEvent( event )
    setDevice( event.device, event.device.displayName )
    Runtime:removeEventListener( "key", onKeyEvent )

That’s working as expected !

Lua has plenty of surprises in store :crazy_face:

Yeah, Lua is single pass, so all local variables need to be (forward) declared above whatever needs to access it.

So, as you found out, the reason why that example wasn’t working is a simple scope error.