Eventable
A Series of Tubes for Lua tables.
Eventable lightly extends your tables to create a "network" of tables that can listen for, and send events. Works across modules too. It's basically a chat room for your tables and mods.
Install
Put the Eventable.lua
somewhere in your project, and require it where ever you need it
--== main.lua ==--
local Eventable = require('Eventable')
Usage
For a table to be part of the Eventable messaging loop, it must be evented like so:
local et = require('Eventable')
--== evented table
local tbl = et:new()
You now have a table that is also part of the Eventable messaging network. Use it as you would any other table. Just be sure not to overwrite any of the Eventable methods (see API below).
As long as you don't use any of the Eventable method names, you can pass in any starting data table.
local starter_tbl = { username = "Fred", age = 55 }
local etbl = Eventable:new( starter_tbl )
Listening for events in the network.
--== Listening for 'tweet' event
local etbl = et:new()
etbl:on('tweet', function( evt, message )
print( 'The '..evt.name..' was '..message )
end)
--== Sending
local starter_tbl = { greeting = "Hello!" }
local etbl2 = et:new( starter_tbl ) --wrap it
etbl2:emit('tweet', self.greeting )
--> The tweet was Hello!
Listening for events once.
etbl:once( 'tweet', function( evt, message )
print( 'tweet: ' .. message )
print( 'bye tweety!')
end)
--> tweet Goodbye!
--> bye tweety!
The event callback will trigger one time, and never again, unless you re-register the on
handler.
Sending events through the network.
etbl:emit('my-event', someval, otherval, alotofvals )
After specifying an event name, you can pass as many arguments as you need, comma separated.
Any evented table can opt-in to listening to any event from any other evented table.
local et = require('Eventable')
--Create some new evented tables
local cook = et:new()
local waiter = et:new()
--Cook waits for order
cook:on('order', function( evt, food )
print('Now cooking'..food)
-- ...
self:emit( 'order-up', food )
end)
--Waiter listens for order
waiter:on('order-up', function( evt, food )
print( 'Your ' .. food .. ' are served.')
end)
--Waiter places order
waiter:emit('order', 'Pancakes')
--> Now cooking Pancakes
--> Your Panackes are served
Communication through modules.
In this example, the first two modules are listening for a greeting event. The third module emits
the event. You might also notice the use of the once
method, instead of the more common on
. Usually once your greeted, you don't need to be re-greeted. So here once
makes sense.
--== mod_one.lua ==--
local et = require('Eventable')
local mod = et:new()
mod:once('greeting', function( evt, message )
print( message )
end)
return mod
--== mod_two.lua ==--
local et = require('Eventable')
local mod = et:new()
mod:once('greeting', function( evt, message )
print( 'this is my greeting: ' .. message )
end)
return mod
--== mod_three.lua ==--
local et = require('Eventable')
local mod = et:new()
mod:emit( 'greeting', 'Hello!' )
return mod
--> Hello!
--> this is my greeting: Hello!
Managing your listening options.
Stop listening for a certain event. Other events are unaffected.
etbl:off( 'tweet' )
Stop listening for any and all events.
etbl:allOff()
Once you release events using
off
orallOff
, you will need to re-register youron
handler again. You can also usemute
, which does not remove your events, as shown below.
Temporary silencing of all events. Events are not released.
-- Mute all events
etbl:mute( true )
-- Listen to all events again
etbl:mute( false )
Check if table listening is muted.
local trueOrFalse = etbl:isMuted()
Eventable API
The following methods are available on any evented table. Please do not overwrite them.
You can call methods directly on the evented table object, or through using self
internally.
local etbl = et:new()
etbl:emit('party', 'tonight')
local etbl = et:new()
etbl:goParty = function(when)
self:emit('party', when)
end
etbl:goParty('tonight')
Methods
:new([starting_table])
Creates a fresh evented table. This table can message with other evented tables and mods. Can optionally take a starting_table
that will become 'wrapped' into an evented table.
local et = require('Eventable')
local etbl = et:new()
-- or
local etbl = et:new( { username = "Bob" } )
:emit( event_name, ... )
Broadcast data parameters to any other evented tables listening for this event_name
.
local et = require('Eventable')
local etbl = et:new()
etbl:emit( 'greeting', 'Good Day!')
:on( event_name, callback )
Listens for a specific event name to be emitted, and take action with the callback. The callback will return an event
object and any other arguments available.
In the event
object you can find the event name
and target
key, which points to the table that triggered this event.
local et = require('Eventable')
local etbl = et:new()
etbl:on('greeting', function( evt, message )
print( message )
end)
:once( event_name, callback )
Listens for a specific event_name
to be emitted, and take action with the callback only one time, and no more.
local et = require('Eventable')
local etbl = et:new()
etbl:once('greeting', function( event, message )
print( message )
print( 'Bye bye!')
end)
Something like a "greeting" is a good candidate for using
once
, since you only greet someone one time each session.
:off( event_name )
Stop listening for the specified event_name
. Once a event is turned off, it can only be added as a new on
instance. See the mute
method for an alternative.
etbl:off( 'greeting' )
Will no longer listen for the greeting event.
:allOff()
Removes all events from the table / mod.
etbl:allOff()
Will no longer listen for any events.
:mute( trueOrFalse )
Mutes all event input while enabled. Event listeners are left active unlike off
or allOff
.
etbl:mute( true ) --no events read
-- or
etbl:mute( false ) --read events again
Toggle mute for all events. But listeners will remain.
:isMuted()
Checks whether the evented table is muted
. Will return true or false.
local is_muted = etbl:isMuted()
Eventable static methods
Print a table into human readable form.
Eventable.p( tbl )
To get a count of all the evented tables.
local count = Eventable.count()
Print all event names active to the terminal. (needs work)
Eventable.list()
Release a table from Eventable messaging loop. You cannot reattach after this action. You must create a new instance. Generally, you shouldn't need to use this action.
Eventable.release( etbl )