From ad75dba87bb39de2c3d12b228bf113abe740c942 Mon Sep 17 00:00:00 2001 From: DS Date: Wed, 27 Mar 2019 21:05:50 +0100 Subject: [PATCH] Optimize core.after in a simple way (#8351) --- builtin/common/after.lua | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/builtin/common/after.lua b/builtin/common/after.lua index 1bed2d31f..b314711c9 100644 --- a/builtin/common/after.lua +++ b/builtin/common/after.lua @@ -1,22 +1,28 @@ local jobs = {} local time = 0.0 +local time_next = math.huge core.register_globalstep(function(dtime) time = time + dtime - if #jobs < 1 then + if time < time_next then return end + time_next = math.huge + -- 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. + -- a timer callback. 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) + local jobs_l = #jobs + jobs[i] = jobs[jobs_l] + jobs[jobs_l] = nil + elseif job.expire < time_next then + time_next = job.expire end end end) @@ -24,10 +30,12 @@ end) function core.after(after, func, ...) assert(tonumber(after) and type(func) == "function", "Invalid minetest.after invocation") + local expire = time + after jobs[#jobs + 1] = { func = func, - expire = time + after, + expire = expire, arg = {...}, mod_origin = core.get_last_run_mod() } + time_next = math.min(time_next, expire) end