Fix #103: Unexpected behavior of timer:cancel()

This commit is contained in:
Matthias Richter 2018-06-17 18:29:30 +02:00
parent 0dea46b0b5
commit 0bf301f710

View File

@ -29,17 +29,7 @@ Timer.__index = Timer
local function _nothing_() end local function _nothing_() end
function Timer:update(dt) local function updateTimerHandle(handle, dt)
local to_remove = {}
-- timers may create new timers, which leads to undefined behavior
-- in pairs() - so we need to put them in a different table first
local to_update = {}
for handle in pairs(self.functions) do
to_update[handle] = handle
end
for handle in pairs(to_update) do
-- handle: { -- handle: {
-- time = <number>, -- time = <number>,
-- after = <function>, -- after = <function>,
@ -47,7 +37,6 @@ function Timer:update(dt)
-- limit = <number>, -- limit = <number>,
-- count = <number>, -- count = <number>,
-- } -- }
handle.time = handle.time + dt handle.time = handle.time + dt
handle.during(dt, math.max(handle.limit - handle.time, 0)) handle.during(dt, math.max(handle.limit - handle.time, 0))
@ -59,14 +48,23 @@ function Timer:update(dt)
handle.time = handle.time - handle.limit handle.time = handle.time - handle.limit
handle.count = handle.count - 1 handle.count = handle.count - 1
end end
end
if handle.count == 0 then function Timer:update(dt)
table.insert(to_remove, handle) -- timers may create new timers, which leads to undefined behavior
end -- in pairs() - so we need to put them in a different table first
local to_update = {}
for handle in pairs(self.functions) do
to_update[handle] = handle
end end
for i = 1, #to_remove do for handle in pairs(to_update) do
self.functions[to_remove[i]] = nil if self.functions[handle] then
updateTimerHandle(handle, dt)
if handle.count == 0 then
self.functions[handle] = nil
end
end
end end
end end