mirror of
https://github.com/Reuh/ubiquitousse.git
synced 2025-10-27 17:19:31 +00:00
Rename time to timer
This commit is contained in:
parent
b5324faace
commit
82bc7268e6
9 changed files with 37 additions and 37 deletions
6
timer/backend/ctrulua.lua
Normal file
6
timer/backend/ctrulua.lua
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
local timer = require((...):match("^(.-%.)backend").."timer")
|
||||
local ctr = require("ctr")
|
||||
|
||||
timer.get = ctr.time
|
||||
|
||||
return timer
|
||||
7
timer/backend/love.lua
Normal file
7
timer/backend/love.lua
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
local timer = require((...):match("^(.-%.)backend").."timer")
|
||||
|
||||
timer.get = function()
|
||||
return love.timer.getTime() * 1000
|
||||
end
|
||||
|
||||
return timer
|
||||
435
timer/easing.lua
Normal file
435
timer/easing.lua
Normal file
|
|
@ -0,0 +1,435 @@
|
|||
--
|
||||
-- Adapted from
|
||||
-- Tweener's easing functions (Penner's Easing Equations)
|
||||
-- and http://code.google.com/p/tweener/ (jstweener javascript version)
|
||||
--
|
||||
|
||||
--[[
|
||||
Disclaimer for Robert Penner's Easing Equations license:
|
||||
|
||||
TERMS OF USE - EASING EQUATIONS
|
||||
|
||||
Open source under the BSD License.
|
||||
|
||||
Copyright © 2001 Robert Penner
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the author nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
]]
|
||||
|
||||
-- For all easing functions:
|
||||
-- t = elapsed time
|
||||
-- b = begin
|
||||
-- c = change == ending - beginning
|
||||
-- d = duration (total time)
|
||||
|
||||
local pow = math.pow
|
||||
local sin = math.sin
|
||||
local cos = math.cos
|
||||
local pi = math.pi
|
||||
local sqrt = math.sqrt
|
||||
local abs = math.abs
|
||||
local asin = math.asin
|
||||
|
||||
local function linear(t, b, c, d)
|
||||
return c * t / d + b
|
||||
end
|
||||
|
||||
local function inQuad(t, b, c, d)
|
||||
t = t / d
|
||||
return c * pow(t, 2) + b
|
||||
end
|
||||
|
||||
local function outQuad(t, b, c, d)
|
||||
t = t / d
|
||||
return -c * t * (t - 2) + b
|
||||
end
|
||||
|
||||
local function inOutQuad(t, b, c, d)
|
||||
t = t / d * 2
|
||||
if t < 1 then
|
||||
return c / 2 * pow(t, 2) + b
|
||||
else
|
||||
return -c / 2 * ((t - 1) * (t - 3) - 1) + b
|
||||
end
|
||||
end
|
||||
|
||||
local function outInQuad(t, b, c, d)
|
||||
if t < d / 2 then
|
||||
return outQuad (t * 2, b, c / 2, d)
|
||||
else
|
||||
return inQuad((t * 2) - d, b + c / 2, c / 2, d)
|
||||
end
|
||||
end
|
||||
|
||||
local function inCubic (t, b, c, d)
|
||||
t = t / d
|
||||
return c * pow(t, 3) + b
|
||||
end
|
||||
|
||||
local function outCubic(t, b, c, d)
|
||||
t = t / d - 1
|
||||
return c * (pow(t, 3) + 1) + b
|
||||
end
|
||||
|
||||
local function inOutCubic(t, b, c, d)
|
||||
t = t / d * 2
|
||||
if t < 1 then
|
||||
return c / 2 * t * t * t + b
|
||||
else
|
||||
t = t - 2
|
||||
return c / 2 * (t * t * t + 2) + b
|
||||
end
|
||||
end
|
||||
|
||||
local function outInCubic(t, b, c, d)
|
||||
if t < d / 2 then
|
||||
return outCubic(t * 2, b, c / 2, d)
|
||||
else
|
||||
return inCubic((t * 2) - d, b + c / 2, c / 2, d)
|
||||
end
|
||||
end
|
||||
|
||||
local function inQuart(t, b, c, d)
|
||||
t = t / d
|
||||
return c * pow(t, 4) + b
|
||||
end
|
||||
|
||||
local function outQuart(t, b, c, d)
|
||||
t = t / d - 1
|
||||
return -c * (pow(t, 4) - 1) + b
|
||||
end
|
||||
|
||||
local function inOutQuart(t, b, c, d)
|
||||
t = t / d * 2
|
||||
if t < 1 then
|
||||
return c / 2 * pow(t, 4) + b
|
||||
else
|
||||
t = t - 2
|
||||
return -c / 2 * (pow(t, 4) - 2) + b
|
||||
end
|
||||
end
|
||||
|
||||
local function outInQuart(t, b, c, d)
|
||||
if t < d / 2 then
|
||||
return outQuart(t * 2, b, c / 2, d)
|
||||
else
|
||||
return inQuart((t * 2) - d, b + c / 2, c / 2, d)
|
||||
end
|
||||
end
|
||||
|
||||
local function inQuint(t, b, c, d)
|
||||
t = t / d
|
||||
return c * pow(t, 5) + b
|
||||
end
|
||||
|
||||
local function outQuint(t, b, c, d)
|
||||
t = t / d - 1
|
||||
return c * (pow(t, 5) + 1) + b
|
||||
end
|
||||
|
||||
local function inOutQuint(t, b, c, d)
|
||||
t = t / d * 2
|
||||
if t < 1 then
|
||||
return c / 2 * pow(t, 5) + b
|
||||
else
|
||||
t = t - 2
|
||||
return c / 2 * (pow(t, 5) + 2) + b
|
||||
end
|
||||
end
|
||||
|
||||
local function outInQuint(t, b, c, d)
|
||||
if t < d / 2 then
|
||||
return outQuint(t * 2, b, c / 2, d)
|
||||
else
|
||||
return inQuint((t * 2) - d, b + c / 2, c / 2, d)
|
||||
end
|
||||
end
|
||||
|
||||
local function inSine(t, b, c, d)
|
||||
return -c * cos(t / d * (pi / 2)) + c + b
|
||||
end
|
||||
|
||||
local function outSine(t, b, c, d)
|
||||
return c * sin(t / d * (pi / 2)) + b
|
||||
end
|
||||
|
||||
local function inOutSine(t, b, c, d)
|
||||
return -c / 2 * (cos(pi * t / d) - 1) + b
|
||||
end
|
||||
|
||||
local function outInSine(t, b, c, d)
|
||||
if t < d / 2 then
|
||||
return outSine(t * 2, b, c / 2, d)
|
||||
else
|
||||
return inSine((t * 2) -d, b + c / 2, c / 2, d)
|
||||
end
|
||||
end
|
||||
|
||||
local function inExpo(t, b, c, d)
|
||||
if t == 0 then
|
||||
return b
|
||||
else
|
||||
return c * pow(2, 10 * (t / d - 1)) + b - c * 0.001
|
||||
end
|
||||
end
|
||||
|
||||
local function outExpo(t, b, c, d)
|
||||
if t == d then
|
||||
return b + c
|
||||
else
|
||||
return c * 1.001 * (-pow(2, -10 * t / d) + 1) + b
|
||||
end
|
||||
end
|
||||
|
||||
local function inOutExpo(t, b, c, d)
|
||||
if t == 0 then return b end
|
||||
if t == d then return b + c end
|
||||
t = t / d * 2
|
||||
if t < 1 then
|
||||
return c / 2 * pow(2, 10 * (t - 1)) + b - c * 0.0005
|
||||
else
|
||||
t = t - 1
|
||||
return c / 2 * 1.0005 * (-pow(2, -10 * t) + 2) + b
|
||||
end
|
||||
end
|
||||
|
||||
local function outInExpo(t, b, c, d)
|
||||
if t < d / 2 then
|
||||
return outExpo(t * 2, b, c / 2, d)
|
||||
else
|
||||
return inExpo((t * 2) - d, b + c / 2, c / 2, d)
|
||||
end
|
||||
end
|
||||
|
||||
local function inCirc(t, b, c, d)
|
||||
t = t / d
|
||||
return(-c * (sqrt(1 - pow(t, 2)) - 1) + b)
|
||||
end
|
||||
|
||||
local function outCirc(t, b, c, d)
|
||||
t = t / d - 1
|
||||
return(c * sqrt(1 - pow(t, 2)) + b)
|
||||
end
|
||||
|
||||
local function inOutCirc(t, b, c, d)
|
||||
t = t / d * 2
|
||||
if t < 1 then
|
||||
return -c / 2 * (sqrt(1 - t * t) - 1) + b
|
||||
else
|
||||
t = t - 2
|
||||
return c / 2 * (sqrt(1 - t * t) + 1) + b
|
||||
end
|
||||
end
|
||||
|
||||
local function outInCirc(t, b, c, d)
|
||||
if t < d / 2 then
|
||||
return outCirc(t * 2, b, c / 2, d)
|
||||
else
|
||||
return inCirc((t * 2) - d, b + c / 2, c / 2, d)
|
||||
end
|
||||
end
|
||||
|
||||
local function inElastic(t, b, c, d, a, p)
|
||||
if t == 0 then return b end
|
||||
|
||||
t = t / d
|
||||
|
||||
if t == 1 then return b + c end
|
||||
|
||||
if not p then p = d * 0.3 end
|
||||
|
||||
local s
|
||||
|
||||
if not a or a < abs(c) then
|
||||
a = c
|
||||
s = p / 4
|
||||
else
|
||||
s = p / (2 * pi) * asin(c/a)
|
||||
end
|
||||
|
||||
t = t - 1
|
||||
|
||||
return -(a * pow(2, 10 * t) * sin((t * d - s) * (2 * pi) / p)) + b
|
||||
end
|
||||
|
||||
-- a: amplitud
|
||||
-- p: period
|
||||
local function outElastic(t, b, c, d, a, p)
|
||||
if t == 0 then return b end
|
||||
|
||||
t = t / d
|
||||
|
||||
if t == 1 then return b + c end
|
||||
|
||||
if not p then p = d * 0.3 end
|
||||
|
||||
local s
|
||||
|
||||
if not a or a < abs(c) then
|
||||
a = c
|
||||
s = p / 4
|
||||
else
|
||||
s = p / (2 * pi) * asin(c/a)
|
||||
end
|
||||
|
||||
return a * pow(2, -10 * t) * sin((t * d - s) * (2 * pi) / p) + c + b
|
||||
end
|
||||
|
||||
-- p = period
|
||||
-- a = amplitud
|
||||
local function inOutElastic(t, b, c, d, a, p)
|
||||
if t == 0 then return b end
|
||||
|
||||
t = t / d * 2
|
||||
|
||||
if t == 2 then return b + c end
|
||||
|
||||
if not p then p = d * (0.3 * 1.5) end
|
||||
if not a then a = 0 end
|
||||
|
||||
local s
|
||||
|
||||
if not a or a < abs(c) then
|
||||
a = c
|
||||
s = p / 4
|
||||
else
|
||||
s = p / (2 * pi) * asin(c / a)
|
||||
end
|
||||
|
||||
if t < 1 then
|
||||
t = t - 1
|
||||
return -0.5 * (a * pow(2, 10 * t) * sin((t * d - s) * (2 * pi) / p)) + b
|
||||
else
|
||||
t = t - 1
|
||||
return a * pow(2, -10 * t) * sin((t * d - s) * (2 * pi) / p ) * 0.5 + c + b
|
||||
end
|
||||
end
|
||||
|
||||
-- a: amplitud
|
||||
-- p: period
|
||||
local function outInElastic(t, b, c, d, a, p)
|
||||
if t < d / 2 then
|
||||
return outElastic(t * 2, b, c / 2, d, a, p)
|
||||
else
|
||||
return inElastic((t * 2) - d, b + c / 2, c / 2, d, a, p)
|
||||
end
|
||||
end
|
||||
|
||||
local function inBack(t, b, c, d, s)
|
||||
if not s then s = 1.70158 end
|
||||
t = t / d
|
||||
return c * t * t * ((s + 1) * t - s) + b
|
||||
end
|
||||
|
||||
local function outBack(t, b, c, d, s)
|
||||
if not s then s = 1.70158 end
|
||||
t = t / d - 1
|
||||
return c * (t * t * ((s + 1) * t + s) + 1) + b
|
||||
end
|
||||
|
||||
local function inOutBack(t, b, c, d, s)
|
||||
if not s then s = 1.70158 end
|
||||
s = s * 1.525
|
||||
t = t / d * 2
|
||||
if t < 1 then
|
||||
return c / 2 * (t * t * ((s + 1) * t - s)) + b
|
||||
else
|
||||
t = t - 2
|
||||
return c / 2 * (t * t * ((s + 1) * t + s) + 2) + b
|
||||
end
|
||||
end
|
||||
|
||||
local function outInBack(t, b, c, d, s)
|
||||
if t < d / 2 then
|
||||
return outBack(t * 2, b, c / 2, d, s)
|
||||
else
|
||||
return inBack((t * 2) - d, b + c / 2, c / 2, d, s)
|
||||
end
|
||||
end
|
||||
|
||||
local function outBounce(t, b, c, d)
|
||||
t = t / d
|
||||
if t < 1 / 2.75 then
|
||||
return c * (7.5625 * t * t) + b
|
||||
elseif t < 2 / 2.75 then
|
||||
t = t - (1.5 / 2.75)
|
||||
return c * (7.5625 * t * t + 0.75) + b
|
||||
elseif t < 2.5 / 2.75 then
|
||||
t = t - (2.25 / 2.75)
|
||||
return c * (7.5625 * t * t + 0.9375) + b
|
||||
else
|
||||
t = t - (2.625 / 2.75)
|
||||
return c * (7.5625 * t * t + 0.984375) + b
|
||||
end
|
||||
end
|
||||
|
||||
local function inBounce(t, b, c, d)
|
||||
return c - outBounce(d - t, 0, c, d) + b
|
||||
end
|
||||
|
||||
local function inOutBounce(t, b, c, d)
|
||||
if t < d / 2 then
|
||||
return inBounce(t * 2, 0, c, d) * 0.5 + b
|
||||
else
|
||||
return outBounce(t * 2 - d, 0, c, d) * 0.5 + c * .5 + b
|
||||
end
|
||||
end
|
||||
|
||||
local function outInBounce(t, b, c, d)
|
||||
if t < d / 2 then
|
||||
return outBounce(t * 2, b, c / 2, d)
|
||||
else
|
||||
return inBounce((t * 2) - d, b + c / 2, c / 2, d)
|
||||
end
|
||||
end
|
||||
|
||||
return {
|
||||
linear = linear,
|
||||
inQuad = inQuad,
|
||||
outQuad = outQuad,
|
||||
inOutQuad = inOutQuad,
|
||||
outInQuad = outInQuad,
|
||||
inCubic = inCubic ,
|
||||
outCubic = outCubic,
|
||||
inOutCubic = inOutCubic,
|
||||
outInCubic = outInCubic,
|
||||
inQuart = inQuart,
|
||||
outQuart = outQuart,
|
||||
inOutQuart = inOutQuart,
|
||||
outInQuart = outInQuart,
|
||||
inQuint = inQuint,
|
||||
outQuint = outQuint,
|
||||
inOutQuint = inOutQuint,
|
||||
outInQuint = outInQuint,
|
||||
inSine = inSine,
|
||||
outSine = outSine,
|
||||
inOutSine = inOutSine,
|
||||
outInSine = outInSine,
|
||||
inExpo = inExpo,
|
||||
outExpo = outExpo,
|
||||
inOutExpo = inOutExpo,
|
||||
outInExpo = outInExpo,
|
||||
inCirc = inCirc,
|
||||
outCirc = outCirc,
|
||||
inOutCirc = inOutCirc,
|
||||
outInCirc = outInCirc,
|
||||
inElastic = inElastic,
|
||||
outElastic = outElastic,
|
||||
inOutElastic = inOutElastic,
|
||||
outInElastic = outInElastic,
|
||||
inBack = inBack,
|
||||
outBack = outBack,
|
||||
inOutBack = inOutBack,
|
||||
outInBack = outInBack,
|
||||
inBounce = inBounce,
|
||||
outBounce = outBounce,
|
||||
inOutBounce = inOutBounce,
|
||||
outInBounce = outInBounce,
|
||||
}
|
||||
14
timer/init.lua
Normal file
14
timer/init.lua
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
local time
|
||||
|
||||
local p = ...
|
||||
if love then
|
||||
time = require(p..".backend.love")
|
||||
elseif package.loaded["ctr"] then
|
||||
time = require(p..".backend.ctrulua")
|
||||
elseif package.loaded["libretro"] then
|
||||
error("NYI")
|
||||
else
|
||||
error("no backend for ubiquitousse.timer")
|
||||
end
|
||||
|
||||
return time
|
||||
349
timer/timer.lua
Normal file
349
timer/timer.lua
Normal file
|
|
@ -0,0 +1,349 @@
|
|||
--- ubiquitousse.timer
|
||||
-- Depends on a backend.
|
||||
local ease = require((...):match("^.-timer")..".easing")
|
||||
local timer
|
||||
|
||||
--- Returns true if all the values in the list are true ; functions in the list will be called and the test will be performed on their return value.
|
||||
-- Returns default if the list is empty.
|
||||
local function all(list, default)
|
||||
if #list == 0 then
|
||||
return default
|
||||
else
|
||||
local r = true
|
||||
for _,v in ipairs(list) do
|
||||
if type(v) == "function" then
|
||||
r = r and v()
|
||||
else
|
||||
r = r and v
|
||||
end
|
||||
end
|
||||
return r
|
||||
end
|
||||
end
|
||||
|
||||
--- Registry methods.
|
||||
local registry_mt = {
|
||||
--- Update all the TimedFunctions calls.
|
||||
-- Should be called at every game update; called by ubiquitousse.update.
|
||||
-- @tparam[opt=calculate here] number dt the delta-time (time spent since last time the function was called) (miliseconds)
|
||||
-- @impl ubiquitousse
|
||||
update = function(self, dt)
|
||||
local currentTime = timer.get()
|
||||
|
||||
if not dt then
|
||||
dt = currentTime - self.lastTime
|
||||
self.lastTime = currentTime
|
||||
end
|
||||
self.dt = dt
|
||||
|
||||
local done = {} -- functions done running
|
||||
|
||||
local d = self.delayed
|
||||
for func, t in pairs(d) do
|
||||
if t and all(t.initWhen, true) then
|
||||
t.initWhen = {}
|
||||
local co = t.coroutine
|
||||
t.after = t.after - dt
|
||||
if t.forceStart or (t.after <= 0 and all(t.startWhen, true)) then
|
||||
t.startWhen = {}
|
||||
d[func] = false -- niling here cause the next pair iteration to error
|
||||
table.insert(done, func)
|
||||
if not co then
|
||||
co = coroutine.create(func)
|
||||
t.coroutine = co
|
||||
t.started = currentTime
|
||||
if t.times > 0 then t.times = t.times - 1 end
|
||||
for _, f in ipairs(t.onStart) do f(t.object) end
|
||||
end
|
||||
assert(coroutine.resume(co, function(delay)
|
||||
t.after = delay or 0
|
||||
d[func] = t
|
||||
coroutine.yield()
|
||||
end, dt))
|
||||
for _, f in ipairs(t.onUpdate) do f(t.object) end
|
||||
if all(t.stopWhen, false) then t.forceStop = true end
|
||||
if t.forceStop or coroutine.status(co) == "dead" then
|
||||
if t.forceStop
|
||||
or (t.during >= 0 and t.started + t.during < currentTime)
|
||||
or (t.times == 0)
|
||||
or (not all(t.repeatWhile, true))
|
||||
or (t.every == -1 and t.times == -1 and t.during == -1 and #t.repeatWhile == 0) -- no repeat
|
||||
then
|
||||
for _, f in ipairs(t.onEnd) do f(t.object) end
|
||||
else
|
||||
if t.times > 0 then t.times = t.times - 1 end
|
||||
t.after = t.every
|
||||
t.coroutine = coroutine.create(func)
|
||||
d[func] = t
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for _, func in ipairs(done) do
|
||||
if not d[func] then
|
||||
d[func] = nil
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
--- Schedule a function to run.
|
||||
-- The function will receive as first parameter the wait(time) function, which will pause the function execution for time miliseconds.
|
||||
-- As a second parameter, the function will receive the delta time (dt).
|
||||
-- @tparam[opt] function func the function to schedule
|
||||
-- @treturn TimedFunction the object
|
||||
-- @impl ubiquitousse
|
||||
run = function(self, func)
|
||||
-- Creates empty function (the TimedFunction may be used for time measure or stuff like that which doesn't need a specific function)
|
||||
func = func or function() end
|
||||
|
||||
-- Since delayed functions can end in any order, it doesn't really make sense to use a integer-keyed list.
|
||||
-- Using the function as the key works and it's unique.
|
||||
self.delayed[func] = {
|
||||
object = nil,
|
||||
coroutine = nil,
|
||||
started = 0,
|
||||
|
||||
after = -1,
|
||||
every = -1,
|
||||
times = -1,
|
||||
during = -1,
|
||||
|
||||
initWhen = {},
|
||||
startWhen = {},
|
||||
repeatWhile = {},
|
||||
stopWhen = {},
|
||||
|
||||
forceStart = false,
|
||||
forceStop = false,
|
||||
|
||||
onStart = {},
|
||||
onUpdate = {},
|
||||
onEnd = {}
|
||||
}
|
||||
|
||||
local t = self.delayed[func] -- internal data
|
||||
local r -- external interface
|
||||
r = {
|
||||
--- Timed conditions ---
|
||||
--- Wait time milliseconds before running the function.
|
||||
after = function(_, time)
|
||||
t.after = time
|
||||
return r
|
||||
end,
|
||||
--- Run the function every time millisecond.
|
||||
every = function(_, time)
|
||||
t.every = time
|
||||
return r
|
||||
end,
|
||||
--- The function will not execute more than count times.
|
||||
times = function(_, count)
|
||||
t.times = count
|
||||
return r
|
||||
end,
|
||||
--- The TimedFunction will be active for a time duration.
|
||||
during = function(_, time)
|
||||
t.during = time
|
||||
return r
|
||||
end,
|
||||
|
||||
--- Function conditions ---
|
||||
--- Starts the function execution when func() returns true. Checked before the "after" condition,
|
||||
-- meaning the "after" countdown starts when func() returns true.
|
||||
-- If multiple init functions are added, init will trigger only when all of them returns true.
|
||||
initWhen = function(_, func)
|
||||
table.insert(t.initWhen, func)
|
||||
return r
|
||||
end,
|
||||
--- Starts the function execution when func() returns true. Checked after the "after" condition.
|
||||
-- If multiple start functions are added, start will trigger only when all of them returns true.
|
||||
startWhen = function(_, func)
|
||||
table.insert(t.startWhen, func)
|
||||
return r
|
||||
end,
|
||||
--- When the functions ends, the execution won't stop and will repeat as long as func() returns true.
|
||||
-- Will cancel timed repeat conditions if false but needs other timed repeat conditions to be true to create a new repeat.
|
||||
-- If multiple repeat functions are added, a repeat will trigger only when all of them returns true.
|
||||
repeatWhile = function(_, func)
|
||||
table.insert(t.repeatWhile, func)
|
||||
return r
|
||||
end,
|
||||
--- Stops the function execution when func() returns true. Checked before all timed conditions.
|
||||
-- If multiple stop functions are added, stop will trigger only when all of them returns true.
|
||||
stopWhen = function(_, func)
|
||||
table.insert(t.stopWhen, func)
|
||||
return r
|
||||
end,
|
||||
|
||||
--- Conditions override ---
|
||||
--- Force the function to start its execution.
|
||||
start = function(_)
|
||||
t.forceStart = true
|
||||
return r
|
||||
end,
|
||||
--- Force the function to stop its execution.
|
||||
stop = function(_)
|
||||
t.forceStop = true
|
||||
return r
|
||||
end,
|
||||
|
||||
--- Callbacks functions ---
|
||||
--- Will execute func(self) when the function execution start.
|
||||
onStart = function(_, func)
|
||||
table.insert(t.onStart, func)
|
||||
return r
|
||||
end,
|
||||
--- Will execute func(self) each frame the main function is run.
|
||||
onUpdate = function(_, func)
|
||||
table.insert(t.onUpdate, func)
|
||||
return r
|
||||
end,
|
||||
--- Will execute func(self) when the function execution end.
|
||||
onEnd = function(_, func)
|
||||
table.insert(t.onEnd, func)
|
||||
return r
|
||||
end,
|
||||
|
||||
--- Chaining ---
|
||||
--- Creates another TimedFunction which will be initialized when the current one ends.
|
||||
-- Returns the new TimedFunction.
|
||||
chain = function(_, func)
|
||||
local done = false
|
||||
r:onEnd(function() done = true end)
|
||||
return self:run(func)
|
||||
:initWhen(function() return done end)
|
||||
end
|
||||
}
|
||||
t.object = r
|
||||
return r
|
||||
end,
|
||||
|
||||
--- Tween some numeric values.
|
||||
-- @tparam number duration tween duration (miliseconds)
|
||||
-- @tparam table tbl the table containing the values to tween
|
||||
-- @tparam table to the new values
|
||||
-- @tparam[opt="linear"] string/function method tweening method (string name or the actual function(time, start, change, duration))
|
||||
-- @treturn TimedFunction the object. A duration is already defined, and the :chain methods takes the same arguments as tween (and creates a tween).
|
||||
-- @impl ubiquitousse
|
||||
tween = function(self, duration, tbl, to, method)
|
||||
method = method or "linear"
|
||||
method = type(method) == "string" and ease[method] or method
|
||||
|
||||
local time = 0 -- tweening time elapsed
|
||||
local from = {} -- initial state
|
||||
|
||||
local function update(tbl_, from_, to_) -- apply the method to tbl_ recursively (doesn't handle cycles)
|
||||
for k, v in pairs(to_) do
|
||||
if type(v) == "table" then
|
||||
update(tbl_[k], from_[k], to_[k])
|
||||
else
|
||||
if time < duration then
|
||||
tbl_[k] = method(time, from_[k], v - from_[k], duration)
|
||||
else
|
||||
tbl_[k] = v
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local r = self:run(function(wait, dt)
|
||||
time = time + dt
|
||||
update(tbl, from, to)
|
||||
end):during(duration)
|
||||
:onStart(function()
|
||||
local function copy(stencil, source, dest) -- copy initial state recursively
|
||||
for k, v in pairs(stencil) do
|
||||
if type(v) == "table" then
|
||||
if not dest[k] then dest[k] = {} end
|
||||
copy(stencil[k], source[k], dest[k])
|
||||
else
|
||||
dest[k] = source[k]
|
||||
end
|
||||
end
|
||||
end
|
||||
copy(to, tbl, from)
|
||||
end)
|
||||
|
||||
--- Creates another tween which will be initialized when the current one ends.
|
||||
-- If tbl_ and/or method_ are not specified, the values from the current tween will be used.
|
||||
-- Returns the new tween.
|
||||
r.chain = function(_, duration_, tbl_, to_, method_)
|
||||
if not method_ and to_ then
|
||||
if type(to_) == "string" then
|
||||
tbl_, to_, method_ = tbl, tbl_, to_
|
||||
else
|
||||
method_ = method
|
||||
end
|
||||
elseif not method_ and not to_ then
|
||||
tbl_, to_, method_ = tbl, tbl_, method
|
||||
end
|
||||
|
||||
local done = false
|
||||
r:onEnd(function() done = true end)
|
||||
return self:tween(duration_, tbl_, to_, method_)
|
||||
:initWhen(function() return done end)
|
||||
end
|
||||
|
||||
return r
|
||||
end,
|
||||
|
||||
--- Cancels all the running TimedFunctions.
|
||||
-- @impl ubiquitousse
|
||||
clear = function(self)
|
||||
self.delayed = {}
|
||||
end
|
||||
}
|
||||
registry_mt.__index = registry_mt
|
||||
|
||||
--- Time related functions
|
||||
timer = {
|
||||
--- Creates and return a new TimerRegistry.
|
||||
-- A TimerRegistry is a separate ubiquitousse.time instance: its TimedFunctions will be independant
|
||||
-- from the one registered using ubiquitousse.time.run (the global TimerRegistry). If you use the scene
|
||||
-- system, a scene-specific TimerRegistry is available at ubiquitousse.scene.current.time.
|
||||
-- @impl ubiquitousse
|
||||
new = function()
|
||||
return setmetatable({
|
||||
--- Used to store all the functions delayed with ubiquitousse.time.delay
|
||||
-- The default implementation use the structure {<key: function> = <value: data table>, ...}
|
||||
-- This table is for internal use and shouldn't be used from an external script.
|
||||
delayed = {},
|
||||
|
||||
-- Used to calculate the deltatime
|
||||
lastTime = timer.get(),
|
||||
|
||||
--- Time since last timer update (miliseconds).
|
||||
dt = 0
|
||||
}, registry_mt)
|
||||
end,
|
||||
|
||||
--- Returns the number of miliseconds elapsed since some point in time.
|
||||
-- This point is fixed but undetermined, so this function should only be used to calculate durations.
|
||||
-- Should at least have millisecond-precision, but can be more precise if available.
|
||||
-- @impl backend
|
||||
get = function() end,
|
||||
|
||||
--- Time since last update (miliseconds).
|
||||
-- @impl ubiquitousse
|
||||
dt = 0,
|
||||
|
||||
--- Global TimerRegistry.
|
||||
-- @impl ubiquitousse
|
||||
delayed = {},
|
||||
lastTime = 0,
|
||||
update = function(...)
|
||||
return registry_mt.update(timer, ...)
|
||||
end,
|
||||
run = function(...)
|
||||
return registry_mt.run(timer, ...)
|
||||
end,
|
||||
tween = function(...)
|
||||
return registry_mt.tween(timer, ...)
|
||||
end,
|
||||
clear = function(...)
|
||||
return registry_mt.clear(timer, ...)
|
||||
end
|
||||
}
|
||||
|
||||
return timer
|
||||
Loading…
Add table
Add a link
Reference in a new issue