1
0
Fork 0
mirror of https://github.com/Reuh/ubiquitousse.git synced 2025-10-27 17:19:31 +00:00
ubiquitousse/signal/signal.can

116 lines
2.9 KiB
Text

--- ubiquitousse.signal
let registry_mt = {
--- Map of signals to list of listeners.
-- @impl ubiquitousse
signals = {},
--- Bind one or several functions to a signal name.
-- @impl ubiquitousse
bind = :(name, fn, ...)
if not @signals[name] then
@signals[name] = {}
end
table.insert(@signals[name], fn)
if ... then
return @bind(name, ...)
end
end,
--- Unbind one or several functions to a signal name.
-- @impl ubiquitousse
unbind = :(name, fn, ...)
if not @signals[name] then
return
end
for i=#@signals[name], 1, -1 do
if @signals[name] == fn then
table.remove(@signals[name], i)
end
end
if ... then
return @unbind(name, ...)
end
end,
--- Remove every bound function to a signal name.
-- @impl ubiquitousse
unbindAll = :(name)
@signals[name] = nil
end,
--- Replace a bound function with another function.
-- @impl ubiquitousse
replace = :(name, sourceFn, destFn)
if not @signals[name] then
@signals[name] = {}
end
for i, fn in ipairs(@signals[name]) do
if fn == sourceFn then
@signals[name][i] = destFn
break
end
end
end,
--- Remove every bound function to every signal.
-- @impl ubiquitousse
clear = :()
@signals = {}
end,
--- Emit a signal, i.e. call every function bound to it, with the given arguments.
-- @impl ubiquitousse
emit = :(name, ...)
if @signals[name] then
for _, fn in ipairs(@signals[name]) do
fn(...)
end
end
end
}
registry_mt.__index = registry_mt
let signal = {
--- Creates and return a new SignalRegistry.
-- A SignalRegistry is a separate ubiquitousse.signal instance: its signals will be independant from other registries.
-- @impl ubiquitousse
new = ()
return setmetatable({ signals = {} }, registry_mt)
end,
--- Global SignalRegistry.
-- @impl ubiquitousse
signals = {},
bind = (...)
return registry_mt.bind(signal, ...)
end,
unbind = (...)
return registry_mt.unbind(signal, ...)
end,
clear = (...)
return registry_mt.clear(signal, ...)
end,
emit = (...)
return registry_mt.emit(signal, ...)
end,
--- SignalRegistry which will be used to bind signals that need to be called on game engine event.
-- For example, every ubiquitousse module with a "update" function will bind it to the "update" signal in the registry;
-- you can then call this signal on each game update to update every ubiquitousse module easily.
-- Provided signals:
-- * update(dt), should be called on every game update
-- * draw, should be called on every game draw
-- * for LÖVE, there are callbacks for every LÖVE callback function that need to be called on their corresponding LÖVE callback
-- @impl mixed
event = nil,
--- Call this function to hook signal.event signals to the current backend.
-- For LÖVE, this means overriding every existing LÖVE callback. If a callback is already defined, the new one will call the old function along with the signal:emit.
-- @impl backend
registerEvents = () end
}
signal.event = signal.new()
return signal