Provides custom event broadcaster/listener mechanism to regular Lua objects.
Lua
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
doc
EventDispatcher.lua
README.md
main.lua

README.md

##EventDispatcher

EventDispatcher provides a broadcaster / listener event mechanism to regular Lua objects. Corona SDK developers can write cleaner object-oriented code that doesn’t rely on sending messages from display objects or the global Runtime for custom messages. This module works as regular Lua 5.1 / 5.2 code, in Corona SDK, and likely other Lua-based frameworks.

Those who came from the good old Flash 5 days may remember FLEM (FLash Event Model). It was the first listener event model for Flash and ActionScript, and was created by Branden Hall and further developed and maintained by me. I’ve adapted the basic event model mechanism found in ActionScript 2/3 to Lua. This EventDispatcher has a similar interface as the listener model in Corona SDK, with some extra features thrown in (such as optional extra parameters when dispatching events, dispatching event as string or table, and returning status).

Basic usage:

local EvtD = require "EventDispatcher"

local dispatcher = EvtD()

-- listener as table
local listener = {
   eventName = function(event, ...)
      print(event.name, event.target, event.source)
   end
}

-- listener as function
local function listener(event, ...)
    print(event.name, event.target, event.source)
end

dispatcher:addEventListener( "eventName", listener ) -- or
dispatcher:on( "eventName", listener )

dispatcher:once( "eventName", listener )

dispatcher:hasEventListener( "eventName", listener )

dispatcher:dispatchEvent( { name="eventName" } ) -- or
dispatcher:dispatchEvent( "eventName" ) -- or
dispatcher:emit( { name="eventName" } ) -- or
dispatcher:emit( "eventName" )

dispatcher:removeEventListener( "eventName", listener )

dispatcher:removeAllListeners( "eventName" ) -- or
dispatcher:removeAllListeners()

dispatcher:printListeners()

All listeners receive the following fields in the parameter event table:

  • event.name (name of the event)
  • event.target (the listener itself)
  • event.source (the dispatcher)

####Documentation (read here)

Sample code below demonstrates how it can be used:

-- main.lua for EventDispatcher demo

local EvtD = require "EventDispatcher"

---------------------------------------------------------------------------

-- shared function for cowboys; shows the use of event.target
local function cowboyDraw(event, ...)
	if event.subject then
		print(event.target.name .." is ".. event.name .."ing a gun and shooting a ".. event.subject)
	else
		print(event.target.name .." is ".. event.name .."ing a gun")
	end
end

---------------------------------------------------------------------------

-- table listeners

local cowboy1 = {
	name = "Cowboy1",
	draw = cowboyDraw
}

local cowboy2 = {
	name = "Cowboy2",
	draw = cowboyDraw
}

---------------------------------------------------------------------------

-- listener as table; shows the use of event.source
local iPad = {
	turnOn = function(event, ...)
		print("iPad is turned on by ".. event.source.name .." (table)")
	end,

	turnOff = function(event, ...)
		print("iPad is turned off by ".. event.source.name .." (table)")
	end
}

-- listener as function
local function turnOniPad(event, ...)
	print("iPad is turned on by ".. event.source.name .." (function)")
end

---------------------------------------------------------------------------

-- basic artist draw function
local function artistDraw(event, ...)
	print(event.target.name .." is ".. event.name .."ing a picture")
end

---------------------------------------------------------------------------

-- artist1 is both a listener and a event dispatcher
local artist1 = EvtD{
	name = "Artist1",
	draw = artistDraw,

	-- responds to the 'rest' message, and sends a message to the iPad
	rest = function(event, ...)
		print(event.target.name .." is ".. event.name .."ing")

		-- event.target is artist1
		event.target:dispatchEvent({name="turnOff"})
	end
}

-- artist1 tells iPad to listen to the 'turnOff' message
artist1:addEventListener("turnOff", iPad)

---------------------------------------------------------------------------

-- artist2 is both a listener and a event dispatcher
local artist2 = EvtD{
	name = "Artist2",

	draw = function(event, ...)
		-- event.target is artist2
		event.target:dispatchEvent({name="turnOn"})

		if event.subject then
			print(event.target.name .." is ".. event.name .."ing a ".. event.subject .." on the iPad")

			-- shows the use of extra arguments
			local func, pieces, name = ...
			func(pieces, name)
		else
			print(event.target.name .." is ".. event.name .."ing on the iPad")
		end
	end,

	rest = function(event, ...)
		event.target:dispatchEvent({name="turnOff"})
		print(event.target.name .." is ".. event.name .."ing")
	end
}

-- shows the use of table and function listeners
artist2:addEventListener("turnOff", iPad)
artist2:addEventListener("turnOn", turnOniPad)

---------------------------------------------------------------------------

-- mayor is a event dispatcher who tells others what to do
local mayor = EvtD()

-- mayor shows how much gold is collected
mayor.collectGold = function(nPieces, fromName)
	print("Mayor collected ".. nPieces .." pieces of gold from ".. fromName)
end

-- mayor tells these four people to pay attention to different messages
mayor:addEventListener("draw", cowboy1)
mayor:addEventListener("draw", cowboy2)
mayor:addEventListener("draw", artist1)
mayor:addEventListener("draw", artist2)
mayor:addEventListener("rest", artist2)

-- mayor sends the 'rest' message
mayor:dispatchEvent({name="rest"})
print("Rested 1")

-- mayor tells everyone to draw
mayor:dispatchEvent({name="draw"})

-- mayor tells these people to stop listening to the 'draw' message
mayor:removeEventListener("draw", cowboy1)
mayor:removeEventListener("draw", artist1)
print("Removed")

-- mayor tells artist1 to listen to the 'rest' message
mayor:addEventListener("rest", artist1)

-- mayor tells whoever is still listening to rest
mayor:dispatchEvent({name="rest"})
print("Rested 2")

-- mayor tells whoever is still listening to draw, with a subject and extra parameters
mayor:dispatchEvent({name="draw", subject="bandit"}, mayor.collectGold, 42, "Dave")
print("Collected gold")

-- remove all listeners listening for the 'rest' message
mayor:removeAllListeners("rest")
-- this should not be heard by any mayor listener
mayor:dispatchEvent({name="rest"})

-- remove all listeners for all messages
mayor:removeAllListeners()
-- this also won't be heard because all listeners are removed
mayor:dispatchEvent({name="draw", subject="bandit"}, mayor.collectGold, 42, "Dave")

---------------------------------------------------------------------------

-- test the once() method, uncomment the printListeners() lines to verify it's gone after the event is dispatched once
mayor:once("bye", function()
	print("Goodbye!")
end)

--mayor:printListeners()

-- test the emit() method and the simpler event as string (instead of table with a 'name' field)
mayor:emit("bye")

--mayor:printListeners()

Here is the output from the code:

iPad is turned off by Artist2 (table)
Artist2 is resting
Rested 1
Cowboy1 is drawing a gun
Cowboy2 is drawing a gun
Artist1 is drawing a picture
iPad is turned on by Artist2 (function)
Artist2 is drawing on the iPad
Removed
iPad is turned off by Artist2 (table)
Artist2 is resting
Artist1 is resting
iPad is turned off by Artist1 (table)
Rested 2
Cowboy1 is drawing a gun and shooting a bandit
Cowboy2 is drawing a gun and shooting a bandit
Artist1 is drawing a picture
iPad is turned on by Artist2 (function)
Artist2 is drawing a bandit on the iPad
Mayor collected 42 pieces of gold from Dave
Collected gold
Goodbye!

The MIT License (MIT)

Copyright (c) 2014-2018 Dave Yang / Quantumwave Interactive Inc. @ qwmobile.com

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.