diff options
Diffstat (limited to 'builtin/game')
-rw-r--r-- | builtin/game/misc.lua | 90 |
1 files changed, 32 insertions, 58 deletions
diff --git a/builtin/game/misc.lua b/builtin/game/misc.lua index efd0f8dc7..bacadf18f 100644 --- a/builtin/game/misc.lua +++ b/builtin/game/misc.lua @@ -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", "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, ...) |