mirror of
https://github.com/Reuh/ubiquitousse.git
synced 2025-10-27 17:19:31 +00:00
uqt.signal
This commit is contained in:
parent
82bc7268e6
commit
f6fb8ad649
11 changed files with 331 additions and 80 deletions
|
|
@ -2,10 +2,25 @@ local uqt = require((...):match("^(.-ubiquitousse)%."))
|
|||
local ctr = require("ctr")
|
||||
local gfx = require("ctr.gfx")
|
||||
|
||||
local function checkCompat(stuffName, expectedVersion, actualVersion)
|
||||
if actualVersion ~= expectedVersion then
|
||||
local txt = ("Ubiquitousse ctrµLua backend was made for %s %s but %s is used!\nThings may not work as expected.")
|
||||
:format(stuffName, expectedVersion, actualVersion)
|
||||
local madeForCtr = "v1.0"
|
||||
local madeForUqt = "0.0.1"
|
||||
|
||||
-- Check versions
|
||||
local txt = ""
|
||||
|
||||
if ctr.version ~= madeForCtr then
|
||||
txt = txt .. ("Ubiquitousse ctrµLua backend was made for ctrµLua %s but %s is used!\n")
|
||||
:format(madeForCtr, uqt.version)
|
||||
end
|
||||
|
||||
if uqt.version ~= madeForUqt then
|
||||
txt = txt .. ("Ubiquitousse ctrµLua backend was made for Ubiquitousse %s but %s is used!\n")
|
||||
:format(madeForUqt, uqt.version)
|
||||
end
|
||||
|
||||
-- Show warnings
|
||||
if txt ~= "" then
|
||||
txt = txt .. "Things may not work as expected.\n"
|
||||
print(txt)
|
||||
for _=0,300 do
|
||||
gfx.start(gfx.TOP)
|
||||
|
|
@ -14,6 +29,3 @@ local function checkCompat(stuffName, expectedVersion, actualVersion)
|
|||
gfx.render()
|
||||
end
|
||||
end
|
||||
end
|
||||
checkCompat("ctrµLua", "v1.0", ctr.version) -- not really a version, just get the latest build
|
||||
checkCompat("Ubiquitousse", "0.0.1", uqt.version)
|
||||
|
|
|
|||
|
|
@ -1,11 +1,30 @@
|
|||
local uqt = require((...):match("^(.-ubiquitousse)%."))
|
||||
|
||||
local function checkCompat(stuffName, expectedVersion, actualVersion)
|
||||
if actualVersion ~= expectedVersion then
|
||||
local txt = ("Ubiquitousse Löve backend was made for %s %s but %s is used!\nThings may not work as expected.")
|
||||
:format(stuffName, expectedVersion, actualVersion)
|
||||
local madeForLove = { 11, "x", "x" }
|
||||
local madeForUqt = "0.0.1"
|
||||
|
||||
-- Check versions
|
||||
local txt = ""
|
||||
|
||||
local actualLove = { love.getVersion() }
|
||||
for i, v in ipairs(madeForLove) do
|
||||
if v ~= "x" then
|
||||
if actualLove[i] ~= v then
|
||||
txt = txt .. ("Ubiquitousse Löve backend was made for LÖVE %s.%s.%s but %s.%s.%s is used!\n")
|
||||
:format(madeForLove[1], madeForLove[2], madeForLove[3], actualLove[1], actualLove[2], actualLove[3])
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if uqt.version ~= madeForUqt then
|
||||
txt = txt .. ("Ubiquitousse Löve backend was made for Ubiquitousse %s but %s is used!\n")
|
||||
:format(madeForUqt, uqt.version)
|
||||
end
|
||||
|
||||
-- Show warnings
|
||||
if txt ~= "" then
|
||||
txt = txt .. "Things may not work as expected.\n"
|
||||
print(txt)
|
||||
love.window.showMessageBox("Compatibility warning", txt, "warning")
|
||||
end
|
||||
end
|
||||
checkCompat("Löve", "11.3.0", ("%s.%s.%s"):format(love.getVersion()))
|
||||
checkCompat("Ubiquitousse", "0.0.1", uqt.version)
|
||||
|
|
|
|||
22
init.lua
22
init.lua
|
|
@ -64,33 +64,19 @@ local ubiquitousse
|
|||
ubiquitousse = {
|
||||
--- Ubiquitousse version.
|
||||
-- @impl ubiquitousse
|
||||
version = "0.0.1",
|
||||
|
||||
--- Should be called each time the game loop is ran; will update every loaded Ubiquitousse module that needs it.
|
||||
-- @tparam number dt time since last call, in miliseconds
|
||||
-- @impl mixed
|
||||
update = function(dt)
|
||||
if ubiquitousse.timer then ubiquitousse.timer.update(dt) end
|
||||
if ubiquitousse.scene then ubiquitousse.scene.update(dt) end
|
||||
if ubiquitousse.input then ubiquitousse.input.update(dt) end
|
||||
end,
|
||||
|
||||
--- Should be called each time the game expect a new frame to be drawn; will draw every loaded Ubiquitousse module that needs it
|
||||
-- The screen is expected to be cleared since last frame.
|
||||
-- @impl mixed
|
||||
draw = function()
|
||||
if ubiquitousse.scene then ubiquitousse.scene.draw() end
|
||||
end
|
||||
version = "0.0.1"
|
||||
}
|
||||
|
||||
-- We're going to require modules requiring Ubiquitousse, so to avoid stack overflows we already register the ubiquitousse package
|
||||
package.loaded[p] = ubiquitousse
|
||||
|
||||
-- Require external submodules
|
||||
for _, m in ipairs{"asset", "ecs", "input", "scene", "timer", "util"} do
|
||||
for _, m in ipairs{"signal", "asset", "ecs", "input", "scene", "timer", "util"} do
|
||||
local s, t = pcall(require, p.."."..m)
|
||||
if s then
|
||||
ubiquitousse[m] = t
|
||||
elseif not t:match("^module [^n]+ not found") then
|
||||
error(t)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
local input = require((...):match("^(.-%.)backend").."input")
|
||||
|
||||
local loaded, signal = pcall(require, (...):match("^(.-)input").."signal")
|
||||
if not loaded then signal = nil end
|
||||
|
||||
local gfx = require("ctr.gfx")
|
||||
local hid = require("ctr.hid")
|
||||
|
||||
|
|
@ -266,4 +269,9 @@ input.default.pointer:bind(
|
|||
input.default.confirm:bind("key.a")
|
||||
input.default.cancel:bind("key.b")
|
||||
|
||||
--- Register signals
|
||||
if signal then
|
||||
signal.event:replace("update", oUpdate, input.update)
|
||||
end
|
||||
|
||||
return input
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
local input = require((...):match("^(.-%.)backend").."input")
|
||||
|
||||
local loaded, signal = pcall(require, (...):match("^(.-)input").."signal")
|
||||
if not loaded then signal = nil end
|
||||
|
||||
-- Config --
|
||||
|
||||
-- Use ScanCodes (layout independant input) instead of KeyConstants (layout dependant) for keyboard input
|
||||
|
|
@ -13,24 +16,23 @@ local displayKeyConstant = true
|
|||
love.mouse.setVisible(false)
|
||||
|
||||
-- Button detection
|
||||
-- FIXME love callbacks do something cleaner
|
||||
local buttonsInUse = {}
|
||||
local axesInUse = {}
|
||||
function love.keypressed(key, scancode, isrepeat)
|
||||
function input.keypressed(key, scancode, isrepeat)
|
||||
if useScancodes then key = scancode end
|
||||
buttonsInUse["keyboard."..key] = true
|
||||
end
|
||||
function love.keyreleased(key, scancode)
|
||||
function input.keyreleased(key, scancode)
|
||||
if useScancodes then key = scancode end
|
||||
buttonsInUse["keyboard."..key] = nil
|
||||
end
|
||||
function love.mousepressed(x, y, button, istouch)
|
||||
function input.mousepressed(x, y, button, istouch)
|
||||
buttonsInUse["mouse."..button] = true
|
||||
end
|
||||
function love.mousereleased(x, y, button, istouch)
|
||||
function input.mousereleased(x, y, button, istouch)
|
||||
buttonsInUse["mouse."..button] = nil
|
||||
end
|
||||
function love.wheelmoved(x, y)
|
||||
function input.wheelmoved(x, y)
|
||||
if y > 0 then
|
||||
buttonsInUse["mouse.wheel.up"] = true
|
||||
elseif y < 0 then
|
||||
|
|
@ -42,17 +44,17 @@ function love.wheelmoved(x, y)
|
|||
buttonsInUse["mouse.wheel.left"] = true
|
||||
end
|
||||
end
|
||||
function love.mousemoved(x, y, dx, dy)
|
||||
function input.mousemoved(x, y, dx, dy)
|
||||
if dx ~= 0 then axesInUse["mouse.move.x"] = dx/love.graphics.getWidth() end
|
||||
if dy ~= 0 then axesInUse["mouse.move.y"] = dy/love.graphics.getHeight() end
|
||||
end
|
||||
function love.gamepadpressed(joystick, button)
|
||||
function input.gamepadpressed(joystick, button)
|
||||
buttonsInUse["gamepad.button."..joystick:getID().."."..button] = true
|
||||
end
|
||||
function love.gamepadreleased(joystick, button)
|
||||
function input.gamepadreleased(joystick, button)
|
||||
buttonsInUse["gamepad.button."..joystick:getID().."."..button] = nil
|
||||
end
|
||||
function love.gamepadaxis(joystick, axis, value)
|
||||
function input.gamepadaxis(joystick, axis, value)
|
||||
if value ~= 0 then
|
||||
axesInUse["gamepad.axis."..joystick:getID().."."..axis] = value
|
||||
else
|
||||
|
|
@ -61,11 +63,7 @@ function love.gamepadaxis(joystick, axis, value)
|
|||
end
|
||||
|
||||
-- Windows size
|
||||
input.drawWidth, input.drawHeight = love.graphics.getWidth(), love.graphics.getHeight()
|
||||
function love.resize(width, height)
|
||||
input.drawWidth = width
|
||||
input.drawHeight = height
|
||||
end
|
||||
input.getDrawWidth, input.getDrawHeight = love.graphics.getWidth, love.graphics.getHeight
|
||||
|
||||
-- Update
|
||||
local oUpdate = input.update
|
||||
|
|
@ -190,7 +188,7 @@ input.basicAxisDetector = function(id)
|
|||
end
|
||||
end
|
||||
|
||||
input.buttonsInUse = function(threshold)
|
||||
input.buttonUsed = function(threshold)
|
||||
local r = {}
|
||||
threshold = threshold or 0.5
|
||||
for b in pairs(buttonsInUse) do
|
||||
|
|
@ -201,10 +199,10 @@ input.buttonsInUse = function(threshold)
|
|||
table.insert(r, b.."%"..(v < 0 and -threshold or threshold))
|
||||
end
|
||||
end
|
||||
return r
|
||||
return unpack(r)
|
||||
end
|
||||
|
||||
input.axesInUse = function(threshold)
|
||||
input.axisUsed = function(threshold)
|
||||
local r = {}
|
||||
threshold = threshold or 0.5
|
||||
for b,v in pairs(axesInUse) do
|
||||
|
|
@ -212,7 +210,7 @@ input.axesInUse = function(threshold)
|
|||
table.insert(r, b.."%"..threshold)
|
||||
end
|
||||
end
|
||||
return r
|
||||
return unpack(r)
|
||||
end
|
||||
|
||||
input.buttonName = function(...)
|
||||
|
|
@ -316,4 +314,18 @@ input.default.cancel:bind(
|
|||
"gamepad.button.1.b"
|
||||
)
|
||||
|
||||
--- Register signals
|
||||
if signal then
|
||||
signal.event:bind("keypressed", input.keypressed)
|
||||
signal.event:bind("keyreleased", input.keyreleased)
|
||||
signal.event:bind("mousepressed", input.mousepressed)
|
||||
signal.event:bind("mousereleased", input.mousereleased)
|
||||
signal.event:bind("wheelmoved", input.wheelmoved)
|
||||
signal.event:bind("mousemoved", input.mousemoved)
|
||||
signal.event:bind("gamepadpressed", input.gamepadpressed)
|
||||
signal.event:bind("gamepadreleased", input.gamepadreleased)
|
||||
signal.event:bind("gamepadaxis", input.gamepadaxis)
|
||||
signal.event:replace("update", oUpdate, input.update)
|
||||
end
|
||||
|
||||
return input
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
--- ubiquitousse.input
|
||||
-- Depends on a backend.
|
||||
-- Optional dependencies: ubiquitousse.signal (to bind to update signal in signal.event)
|
||||
local loaded, signal = pcall(require, (...):match("^(.-)input").."signal")
|
||||
if not loaded then signal = nil end
|
||||
|
||||
-- TODO: some key selection helper? Will be backend-implemented, to account for all the possible input methods.
|
||||
-- TODO: some way to list all possible input / outputs, or make the *inUse make some separation between inputs indiscutitably in use and those who are incertain.
|
||||
|
|
@ -40,8 +43,8 @@ local button_mt = {
|
|||
-- @treturn ButtonInput this ButtonInput object
|
||||
unbind = function(self, ...)
|
||||
for _, d in ipairs({...}) do
|
||||
for i, detector in ipairs(self.detectors) do
|
||||
if detector == d then
|
||||
for i=#self.detectors, 1, -1 do
|
||||
if self.detectors[i] == d then
|
||||
table.remove(self.detectors, i)
|
||||
break
|
||||
end
|
||||
|
|
@ -270,7 +273,9 @@ local axis_mt = {
|
|||
self.val, self.raw, self.max = val, raw, max
|
||||
updated[self] = true
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
--- LÖVE note: other callbacks that are defined in backend/love.lua and need to be called in the associated LÖVE callbacks.
|
||||
}
|
||||
axis_mt.__index = axis_mt
|
||||
|
||||
|
|
@ -382,9 +387,9 @@ local pointer_mt = {
|
|||
x = function(self)
|
||||
if self.grabbing == self then
|
||||
self:update()
|
||||
return self.valX + (self.offsetX or self.width or input.drawWidth/2)
|
||||
return self.valX + (self.offsetX or self.width or input.getDrawWidth()/2)
|
||||
else
|
||||
return self.offsetX or self.width or input.drawWidth/2
|
||||
return self.offsetX or self.width or input.getDrawWidth()/2
|
||||
end
|
||||
end,
|
||||
--- Returns the current Y value of the pointer.
|
||||
|
|
@ -392,9 +397,9 @@ local pointer_mt = {
|
|||
y = function(self)
|
||||
if self.grabbing == self then
|
||||
self:update()
|
||||
return self.valY + (self.offsetY or self.height or input.drawHeight/2)
|
||||
return self.valY + (self.offsetY or self.height or input.getDrawHeight()/2)
|
||||
else
|
||||
return self.offsetY or self.height or input.drawHeight/2
|
||||
return self.offsetY or self.height or input.getDrawHeight()/2
|
||||
end
|
||||
end,
|
||||
|
||||
|
|
@ -418,9 +423,9 @@ local pointer_mt = {
|
|||
local magnitude = sqrt(x*x + y*y)
|
||||
cx, cy = cx / magnitude * width, cy / magnitude * height
|
||||
end
|
||||
return cx + (self.offsetX or width or input.drawWidth/2), cy + (self.offsetY or height or input.drawHeight/2)
|
||||
return cx + (self.offsetX or width or input.getDrawWidth()/2), cy + (self.offsetY or height or input.getDrawHeight()/2)
|
||||
else
|
||||
return self.offsetX or width or input.drawWidth/2, self.offsetY or height or input.drawHeight/2
|
||||
return self.offsetX or width or input.getDrawWidth()/2, self.offsetY or height or input.getDrawHeight()/2
|
||||
end
|
||||
end,
|
||||
|
||||
|
|
@ -445,7 +450,7 @@ local pointer_mt = {
|
|||
if not updated[self] then
|
||||
local x, y = self.valX, self.valY
|
||||
local xSpeed, ySpeed = self.xSpeed, self.ySpeed
|
||||
local width, height = self.width or input.drawWidth/2, self.height or input.drawHeight/2
|
||||
local width, height = self.width or input.getDrawWidth()/2, self.height or input.getDrawHeight()/2
|
||||
local newX, newY = x, y
|
||||
local maxMovX, maxMovY = 0, 0 -- the maxium axis movement in a direction (used to determine which axes have the priority) (absolute value)
|
||||
for _, pointer in ipairs(self.detectors) do
|
||||
|
|
@ -642,16 +647,16 @@ input = {
|
|||
|
||||
--- Returns a list of the buttons currently in use, identified by their string button identifier.
|
||||
-- This may also returns "axis threshold" buttons if an axis passes the threshold.
|
||||
-- @treturn table<string> buttons identifiers list
|
||||
-- @treturn[opt=0.5] number threshold the threshold to detect axes as button
|
||||
-- @tparam[opt=0.5] number threshold the threshold to detect axes as button
|
||||
-- @treturn string,... buttons identifiers list
|
||||
-- @impl backend
|
||||
buttonsInUse = function(threshold) end,
|
||||
buttonUsed = function(threshold) end,
|
||||
|
||||
--- Returns a list of the axes currently in use, identified by their string axis identifier
|
||||
-- @treturn table<string> axes identifiers list
|
||||
-- @treturn[opt=0.5] number threshold the threshold to detect axes
|
||||
-- @tparam[opt=0.5] number threshold the threshold to detect axes
|
||||
-- @treturn string,... axes identifiers list
|
||||
-- @impl backend
|
||||
axesInUse = function(threshold) end,
|
||||
axisUsed = function(threshold) end,
|
||||
|
||||
--- Returns a nice name for the button identifier.
|
||||
-- Can be locale-depedant and stuff, it's only for display.
|
||||
|
|
@ -686,14 +691,14 @@ input = {
|
|||
cancel = nil -- Button: used to cancel something. Example binds: Escape, B button.
|
||||
},
|
||||
|
||||
--- Draw area dimensions.
|
||||
--- Get draw area dimensions.
|
||||
-- Used for pointers.
|
||||
-- @impl backend
|
||||
drawWidth = 1,
|
||||
drawHeight = 1,
|
||||
getDrawWidth = function() return 1 end,
|
||||
getDrawHeight = function() return 1 end,
|
||||
|
||||
--- Update all the Inputs.
|
||||
-- Should be called at every game update; called by ubiquitousse.update.
|
||||
-- Should be called at every game update. If ubiquitousse.signal is available, will be bound to the "update" signal in signal.event.
|
||||
-- The backend can hook into this function to to its input-related updates.
|
||||
-- @tparam numder dt the delta-time
|
||||
-- @impl ubiquitousse
|
||||
|
|
@ -701,6 +706,11 @@ input = {
|
|||
dt = newDt
|
||||
updated = {}
|
||||
end
|
||||
|
||||
--- If you use LÖVE, note that in order to provide every feature (especially key detection), several callbacks functions will
|
||||
-- need to be called on LÖVE events. See backend/love.lua.
|
||||
-- If ubiquitousse.signal is available, these callbacks will be bound to signals in signal.event (with the same name as the LÖVE
|
||||
-- callbacks, minux the "love.").
|
||||
}
|
||||
|
||||
-- Create default inputs
|
||||
|
|
@ -708,4 +718,9 @@ input.default.pointer = input.pointer()
|
|||
input.default.confirm = input.button()
|
||||
input.default.cancel = input.button()
|
||||
|
||||
-- Bind signals
|
||||
if signal then
|
||||
signal.event:bind("update", input.update)
|
||||
end
|
||||
|
||||
return input
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
--- ubiquitousse.scene
|
||||
-- Optional dependencies: ubiquitousse.timer (to provide each scene a timer registry)
|
||||
-- Optional dependencies: ubiquitousse.signal (to bind to update and draw signal in signal.event)
|
||||
local loaded, signal = pcall(require, (...):match("^(.-)scene").."signal")
|
||||
if not loaded then signal = nil end
|
||||
local loaded, timer = pcall(require, (...):match("^(.-)scene").."timer")
|
||||
if not loaded then timer = nil end
|
||||
|
||||
|
|
@ -134,8 +137,16 @@ scene = setmetatable({
|
|||
table.remove(scene.stack)
|
||||
end,
|
||||
|
||||
--- Pop all scenes.
|
||||
-- @impl ubiquitousse
|
||||
popAll = function()
|
||||
while scene.current do
|
||||
scene.pop()
|
||||
end
|
||||
end,
|
||||
|
||||
--- Update the current scene.
|
||||
-- Should be called at every game update; called by ubiquitousse.update.
|
||||
-- Should be called at every game update. If ubiquitousse.signal is available, will be bound to the "update" signal in signal.event.
|
||||
-- @tparam number dt the delta-time (milisecond)
|
||||
-- @param ... arguments to pass to the scene's update function after dt
|
||||
-- @impl ubiquitousse
|
||||
|
|
@ -147,7 +158,7 @@ scene = setmetatable({
|
|||
end,
|
||||
|
||||
--- Draw the current scene.
|
||||
-- Should be called every time the game is draw; called by ubiquitousse.draw.
|
||||
-- Should be called every time the game is draw. If ubiquitousse.signal is available, will be bound to the "draw" signal in signal.event.
|
||||
-- @param ... arguments to pass to the scene's draw function
|
||||
-- @impl ubiquitousse
|
||||
draw = function(...)
|
||||
|
|
@ -160,4 +171,10 @@ scene = setmetatable({
|
|||
end
|
||||
})
|
||||
|
||||
-- Bind signals
|
||||
if signal then
|
||||
signal.event:bind("update", scene.update)
|
||||
signal.event:bind("draw", scene.draw)
|
||||
end
|
||||
|
||||
return scene
|
||||
|
|
|
|||
43
signal/backend/love.lua
Normal file
43
signal/backend/love.lua
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
local signal = require((...):match("^(.-%.)backend").."signal")
|
||||
|
||||
function signal.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*1000)
|
||||
end
|
||||
else
|
||||
love[callback] = function(dt)
|
||||
event:emit(callback, dt*1000)
|
||||
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
|
||||
|
||||
return signal
|
||||
14
signal/init.lua
Normal file
14
signal/init.lua
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
local signal
|
||||
|
||||
local p = ...
|
||||
if love then
|
||||
signal = require(p..".backend.love")
|
||||
elseif package.loaded["ctr"] then
|
||||
error("NYI")
|
||||
elseif package.loaded["libretro"] then
|
||||
error("NYI")
|
||||
else
|
||||
error("no backend for ubiquitousse.signal")
|
||||
end
|
||||
|
||||
return signal
|
||||
116
signal/signal.can
Normal file
116
signal/signal.can
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
--- 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, 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
|
||||
|
|
@ -1,5 +1,9 @@
|
|||
--- ubiquitousse.timer
|
||||
-- Depends on a backend.
|
||||
-- Optional dependencies: ubiquitousse.signal (to bind to update signal in signal.event)
|
||||
local loaded, signal = pcall(require, (...):match("^(.-)timer").."signal")
|
||||
if not loaded then signal = nil end
|
||||
|
||||
local ease = require((...):match("^.-timer")..".easing")
|
||||
local timer
|
||||
|
||||
|
|
@ -332,7 +336,7 @@ timer = {
|
|||
-- @impl ubiquitousse
|
||||
delayed = {},
|
||||
lastTime = 0,
|
||||
update = function(...)
|
||||
update = function(...) -- If ubiquitousse.signal is available, will be bound to the "update" signal in signal.event.
|
||||
return registry_mt.update(timer, ...)
|
||||
end,
|
||||
run = function(...)
|
||||
|
|
@ -346,4 +350,9 @@ timer = {
|
|||
end
|
||||
}
|
||||
|
||||
-- Bind signals
|
||||
if signal then
|
||||
signal.event:bind("update", timer.update)
|
||||
end
|
||||
|
||||
return timer
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue