mirror of
https://github.com/Reuh/ubiquitousse.git
synced 2025-10-27 17:19:31 +00:00
Since I only use the LÖVE backend anyway, this simplifies the code. Tidied some code.
144 lines
3.9 KiB
Text
144 lines
3.9 KiB
Text
--- ubiquitousse.signal
|
|
|
|
let registry_mt = {
|
|
--- Map of signals to list of listeners.
|
|
signals = {},
|
|
|
|
--- Bind one or several functions to a signal name.
|
|
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.
|
|
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.
|
|
unbindAll = :(name)
|
|
@signals[name] = nil
|
|
end,
|
|
|
|
--- Replace a bound function with another function.
|
|
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.
|
|
clear = :()
|
|
@signals = {}
|
|
end,
|
|
|
|
--- Emit a signal, i.e. call every function bound to it, with the given arguments.
|
|
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.
|
|
new = ()
|
|
return setmetatable({ signals = {} }, registry_mt)
|
|
end,
|
|
|
|
--- Global SignalRegistry.
|
|
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
|
|
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 love
|
|
registerEvents = ()
|
|
local callbacks = { -- everything except run, errorhandler, threaderror
|
|
"displayrotated", "draw", "load", "lowmemory", "quit", "update",
|
|
"directorydropped", "filedropped", "focus", "mousefocus", "resize", "visible",
|
|
"keypressed", "keyreleased", "textedited", "textinput",
|
|
"mousemoved", "mousepressed", "mousereleased", "wheelmoved",
|
|
"gamepadaxis", "gamepadpressed", "gamepadreleased",
|
|
"joystickadded", "joystickaxis", "joystickhat", "joystickpressed", "joystickreleased", "joystickremoved",
|
|
"touchmoved", "touchpressed", "touchreleased"
|
|
}
|
|
local event = signal.event
|
|
for _, callback in ipairs(callbacks) do
|
|
if callback == "update" then
|
|
if love[callback] then
|
|
local old = love[callback]
|
|
love[callback] = function(dt)
|
|
old(dt)
|
|
event:emit(callback, dt)
|
|
end
|
|
else
|
|
love[callback] = function(dt)
|
|
event:emit(callback, dt)
|
|
end
|
|
end
|
|
else
|
|
if love[callback] then
|
|
local old = love[callback]
|
|
love[callback] = function(...)
|
|
old(...)
|
|
event:emit(callback, ...)
|
|
end
|
|
else
|
|
love[callback] = function(...)
|
|
event:emit(callback, ...)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
}
|
|
|
|
signal.event = signal.new()
|
|
|
|
return signal
|