mirror of
https://github.com/vrld/hump.git
synced 2024-11-23 12:24:19 +00:00
Merge pull request #68 from Kingdaro/kingdaro-timer-fix
Timer now accounts for "lateness" and repetition
This commit is contained in:
commit
400c8ea75e
@ -38,7 +38,7 @@ function GS.new(t) return t or {} end -- constructor - deprecated!
|
|||||||
|
|
||||||
local function change_state(stack_offset, to, ...)
|
local function change_state(stack_offset, to, ...)
|
||||||
local pre = stack[#stack]
|
local pre = stack[#stack]
|
||||||
|
|
||||||
-- initialize only on first call
|
-- initialize only on first call
|
||||||
;(initialized_states[to] or to.init or __NULL__)(to)
|
;(initialized_states[to] or to.init or __NULL__)(to)
|
||||||
initialized_states[to] = __NULL__
|
initialized_states[to] = __NULL__
|
||||||
|
73
spec/timer_spec.lua
Normal file
73
spec/timer_spec.lua
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
local timer = require 'timer'()
|
||||||
|
|
||||||
|
describe('hump.timer', function()
|
||||||
|
it('runs a function during a specified time', function()
|
||||||
|
local delta, remaining
|
||||||
|
|
||||||
|
timer:during(10, function(...) delta, remaining = ... end)
|
||||||
|
|
||||||
|
timer:update(2)
|
||||||
|
assert.are.equal(delta, 2)
|
||||||
|
assert.are.equal(8, remaining)
|
||||||
|
|
||||||
|
timer:update(5)
|
||||||
|
assert.are.equal(delta, 5)
|
||||||
|
assert.are.equal(3, remaining)
|
||||||
|
|
||||||
|
timer:update(10)
|
||||||
|
assert.are.equal(delta, 10)
|
||||||
|
assert.are.equal(0, remaining)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it('runs a function after a specified time', function()
|
||||||
|
local finished1 = false
|
||||||
|
local finished2 = false
|
||||||
|
|
||||||
|
timer:after(3, function(...) finished1 = true end)
|
||||||
|
timer:after(5, function(...) finished2 = true end)
|
||||||
|
|
||||||
|
timer:update(4)
|
||||||
|
assert.are.equal(true, finished1)
|
||||||
|
assert.are.equal(false, finished2)
|
||||||
|
|
||||||
|
timer:update(4)
|
||||||
|
assert.are.equal(true, finished1)
|
||||||
|
assert.are.equal(true, finished2)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it('runs a function every so often', function()
|
||||||
|
local count = 0
|
||||||
|
|
||||||
|
timer:every(1, function(...) count = count + 1 end)
|
||||||
|
|
||||||
|
timer:update(3)
|
||||||
|
assert.are.equal(3, count)
|
||||||
|
|
||||||
|
timer:update(7)
|
||||||
|
assert.are.equal(10, count)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it('can script timed events', function()
|
||||||
|
local state
|
||||||
|
|
||||||
|
timer:script(function(wait)
|
||||||
|
state = 'foo'
|
||||||
|
wait(1)
|
||||||
|
state = 'bar'
|
||||||
|
end)
|
||||||
|
|
||||||
|
assert.are.equal('foo', state)
|
||||||
|
timer:update(0.5)
|
||||||
|
assert.are.equal('foo', state)
|
||||||
|
timer:update(1)
|
||||||
|
assert.are.equal('bar', state)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it('cancels and clears timer functions', function()
|
||||||
|
pending('to be tested...')
|
||||||
|
end)
|
||||||
|
|
||||||
|
it('tweens', function()
|
||||||
|
pending('to be tested...')
|
||||||
|
end)
|
||||||
|
end)
|
56
timer.lua
56
timer.lua
@ -31,23 +31,41 @@ local function _nothing_() end
|
|||||||
|
|
||||||
function Timer:update(dt)
|
function Timer:update(dt)
|
||||||
local to_remove = {}
|
local to_remove = {}
|
||||||
for handle, delay in pairs(self.functions) do
|
|
||||||
delay = delay - dt
|
for handle in pairs(self.functions) do
|
||||||
if delay <= 0 then
|
-- handle: {
|
||||||
to_remove[#to_remove+1] = handle
|
-- time = <number>,
|
||||||
|
-- after = <function>,
|
||||||
|
-- during = <function>,
|
||||||
|
-- limit = <number>,
|
||||||
|
-- count = <number>,
|
||||||
|
-- }
|
||||||
|
|
||||||
|
handle.time = handle.time + dt
|
||||||
|
handle.during(dt, math.max(handle.limit - handle.time, 0))
|
||||||
|
|
||||||
|
while handle.time >= handle.limit and handle.count > 0 do
|
||||||
|
if handle.after(handle.after) == false then
|
||||||
|
handle.count = 0
|
||||||
|
break
|
||||||
|
end
|
||||||
|
handle.time = handle.time - handle.limit
|
||||||
|
handle.count = handle.count - 1
|
||||||
|
end
|
||||||
|
|
||||||
|
if handle.count == 0 then
|
||||||
|
table.insert(to_remove, handle)
|
||||||
end
|
end
|
||||||
self.functions[handle] = delay
|
|
||||||
handle.func(dt, delay)
|
|
||||||
end
|
end
|
||||||
for _,handle in ipairs(to_remove) do
|
|
||||||
self.functions[handle] = nil
|
for i = 1, #to_remove do
|
||||||
handle.after(handle.after)
|
self.functions[to_remove[i]] = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function Timer:during(delay, func, after)
|
function Timer:during(delay, during, after)
|
||||||
local handle = {func = func, after = after or _nothing_}
|
local handle = { time = 0, during = during, after = after or _nothing_, limit = delay, count = 1 }
|
||||||
self.functions[handle] = delay
|
self.functions[handle] = true
|
||||||
return handle
|
return handle
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -55,16 +73,10 @@ function Timer:after(delay, func)
|
|||||||
return self:during(delay, _nothing_, func)
|
return self:during(delay, _nothing_, func)
|
||||||
end
|
end
|
||||||
|
|
||||||
function Timer:every(delay, func, count)
|
function Timer:every(delay, after, count)
|
||||||
local count, handle = count or math.huge -- exploit below: math.huge - 1 = math.huge
|
local count = count or math.huge -- exploit below: math.huge - 1 = math.huge
|
||||||
|
local handle = { time = 0, during = _nothing_, after = after, limit = delay, count = count }
|
||||||
handle = self:after(delay, function(f)
|
self.functions[handle] = true
|
||||||
if func(func) == false then return end
|
|
||||||
count = count - 1
|
|
||||||
if count > 0 then
|
|
||||||
self.functions[handle] = delay
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
return handle
|
return handle
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user