Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
New timer design.
I could honestly not make much sense of the timer implementation
that was here. Instead I've implemented the type of timer algorithm
that I've used before, and tested it instead.

The concept is extremely simple: all timers are put in an ordered
list. We check every server tick if any of the timers have
elapsed, and execute the function associated with this timer.

We know that many timers by themselves cause new timers to be
added to this list, so we iterate *backwards* over the timer
list. This means that new timers being added while timers are
being executed, can never be executed in the same function pass,
as they are always appended to the table *after* the end of
the table, which we will never reach in the current pass over
all the table elements.

We switch time keeping to minetest.get_us_time(). dtime is
likely unreliable and we have our own high-res timer that we
can fix if it is indeed broken. This removes the need to do
any sort of time keeping.
  • Loading branch information
sofar authored and ShadowNinja committed Jan 29, 2016
1 parent 4ac1e9b commit ad884f2
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 59 deletions.
90 changes: 32 additions & 58 deletions builtin/game/misc.lua
Expand Up @@ -4,74 +4,48 @@
-- Misc. API functions
--

local timers = {}
local mintime
local function update_timers(delay)
mintime = false
local sub = 0
for index = 1, #timers do
index = index - sub
local timer = timers[index]
timer.time = timer.time - delay
if timer.time <= 0 then
core.set_last_run_mod(timer.mod_origin)
timer.func(unpack(timer.args or {}))
table.remove(timers, index)
sub = sub + 1
elseif mintime then
mintime = math.min(mintime, timer.time)
else
mintime = timer.time
end
end
end
local jobs = {}
local time = 0.0
local last = 0.0

local timers_to_add
local function add_timers()
for _, timer in ipairs(timers_to_add) do
table.insert(timers, timer)
core.register_globalstep(function(dtime)
local new = core.get_us_time() / 1000000
if new > last then
time = time + (new - last)
else
-- Overflow, we may lose a little bit of time here but
-- only 1 tick max, potentially running timers slightly
-- too early.
time = time + new
end
timers_to_add = false
end
last = new

local delay = 0
core.register_globalstep(function(dtime)
if not mintime then
-- abort if no timers are running
if #jobs < 1 then
return
end
if timers_to_add then
add_timers()
end
delay = delay + dtime
if delay < mintime then
return

-- Iterate backwards so that we miss any new timers added by
-- a timer callback, and so that we don't skip the next timer
-- in the list if we remove one.
for i = #jobs, 1, -1 do
local job = jobs[i]
if time >= job.expire then
core.set_last_run_mod(job.mod_origin)
job.func(unpack(job.arg))
table.remove(jobs, i)
end
end
update_timers(delay)
delay = 0
end)

function core.after(time, func, ...)
function core.after(after, func, ...)
assert(tonumber(time) and type(func) == "function",

This comment has been minimized.

Copy link
@BadToad2000

BadToad2000 Feb 23, 2016

Shouldn't this assert be for "after"

"Invalid core.after invocation")
if not mintime then
mintime = time
timers_to_add = {{
time = time+delay,
func = func,
args = {...},
mod_origin = core.get_last_run_mod(),
}}
return
end
mintime = math.min(mintime, time)
timers_to_add = timers_to_add or {}
timers_to_add[#timers_to_add+1] = {
time = time+delay,
func = func,
args = {...},
mod_origin = core.get_last_run_mod(),
}
table.insert(jobs, {
func = func,
expire = time + after,
arg = {...},
mod_origin = core.get_last_run_mod()
})
end

function core.check_player_privs(player_or_name, ...)
Expand Down
2 changes: 1 addition & 1 deletion doc/lua_api.txt
Expand Up @@ -2242,7 +2242,7 @@ These functions return the leftover itemstack.

### Timing
* `minetest.after(time, func, ...)`
* Call the function `func` after `time` seconds
* Call the function `func` after `time` seconds, may be fractional
* Optional: Variable number of arguments that are passed to `func`

### Server
Expand Down

0 comments on commit ad884f2

Please sign in to comment.