Managing Your Runtime Listeners

Proper event listener management is something that is crucial to every app created with the Corona SDK. Failure to monitor and remove unused listeners can bog your app down, and in many cases, cause it to crash. The bigger your app gets, the harder it is to keep track of just what listeners you’ve added, and when you’re ready to remove all of the listeners you’ve added, there’s always that nagging question in the back of your head that asks, are you SURE you got all of them??

For that very reason, I created a couple functions that you can add to your main.lua file that should help you manage your Runtime listeners (because event listeners attached to objects are automatically removed when you remove the object, per the latest Corona release).

So remember, the code I’m about to give you only applies to “Runtime” event listeners, which include but are not limited to things like (just examples):

Runtime:addEventListener( "touch", myObject )
Runtime:addEventListener( "enterFrame", onScreenUpdate )
Runtime:addEventListener( "system", onSystemEvent )
-- etc. etc.

And here it is:

listenersTable = {}

--
-- runtimeListener(): use instead to add or remove new "Runtime" listeners
--

runtimeListener = function( addRemove, eventType, listenerFunction )
    local aR = addRemove or "add"
    local theType = eventType or "enterFrame"
    local theFunc = listenerFunction

    if aR == "add" then
        Runtime:addEventListener( theType, theFunc )

        local newItem = { theType, theFunc }
        table.insert( listenersTable, newItem )

    elseif aR == "remove" then
        Runtime:removeEventListener( theType, theFunc )

        -- Since we are going to be removing from the same table we are iterating,
        -- iterate backwards to avoid conflicts:
        for i=#listenersTable,1,-1 do
            if listenersTable[i][1] == theType then
                table.remove( listenersTable, i )
            end
        end
    end
end

--
-- removeRuntimeListeners(): remove all listeners added with runtimeListener() function.
--

removeRuntimeListeners = function()

    -- Since we are going to be removing from the same table we are iterating,
    -- iterate backwards to avoid conflicts:
    for i=#listenersTable,1,-1 do
        Runtime:removeEventListener( listenersTable[i][1], listenersTable[i][2] )
        table.remove( listenersTable, i )
    end

    listenersTable = {}
end

So, whenever you want to add a new Runtime event listener, instead of using the conventional:

Runtime:addEventListener...

Instead, use the runtimeListener() function like so:

runtimeListener( "add", "touch", onScreenTouch )
runtimeListener( "remove", "touch", onScreenTouch )

-- Then, when you want to remove all of them:
removeRuntimeListeners()

I haven’t tested the above code in an actual project, so let me know if you come across any bugs. The theory is all correct though, and should definitely work in practice.

Good luck, and here’s to programming high performance apps using the Corona SDK!

To read more entries, visit the archives or subscribe to the RSS feed.