diff --git a/builtin/client/init.lua b/builtin/client/init.lua index 8ed4c94d4..dd218aab6 100644 --- a/builtin/client/init.lua +++ b/builtin/client/init.lua @@ -4,6 +4,7 @@ local clientpath = scriptpath.."client"..DIR_DELIM local commonpath = scriptpath.."common"..DIR_DELIM dofile(clientpath .. "register.lua") +dofile(commonpath .. "after.lua") dofile(commonpath .. "chatcommands.lua") dofile(clientpath .. "preview.lua") diff --git a/builtin/client/preview.lua b/builtin/client/preview.lua index 0d7d50a0d..22e8bb97f 100644 --- a/builtin/client/preview.lua +++ b/builtin/client/preview.lua @@ -37,3 +37,6 @@ core.register_chatcommand("dump", { end, }) +core.after(2, function() + print("After 2") +end) diff --git a/builtin/common/after.lua b/builtin/common/after.lua new file mode 100644 index 000000000..30a9c7bad --- /dev/null +++ b/builtin/common/after.lua @@ -0,0 +1,43 @@ +local jobs = {} +local time = 0.0 +local last = core.get_us_time() / 1000000 + +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 + last = new + + if #jobs < 1 then + return + end + + -- 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 +end) + +function core.after(after, func, ...) + assert(tonumber(after) and type(func) == "function", + "Invalid core.after invocation") + jobs[#jobs + 1] = { + func = func, + expire = time + after, + arg = {...}, + mod_origin = core.get_last_run_mod() + } +end diff --git a/builtin/game/init.lua b/builtin/game/init.lua index 793d9fe2b..3e192a30a 100644 --- a/builtin/game/init.lua +++ b/builtin/game/init.lua @@ -17,6 +17,7 @@ if core.setting_getbool("profiler.load") then profiler = dofile(scriptpath.."profiler"..DIR_DELIM.."init.lua") end +dofile(commonpath .. "after.lua") dofile(gamepath.."item_entity.lua") dofile(gamepath.."deprecated.lua") dofile(gamepath.."misc.lua") diff --git a/builtin/game/misc.lua b/builtin/game/misc.lua index 3419c1980..25376c180 100644 --- a/builtin/game/misc.lua +++ b/builtin/game/misc.lua @@ -4,50 +4,6 @@ -- Misc. API functions -- -local jobs = {} -local time = 0.0 -local last = core.get_us_time() / 1000000 - -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 - last = new - - if #jobs < 1 then - return - end - - -- 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 -end) - -function core.after(after, func, ...) - assert(tonumber(after) and type(func) == "function", - "Invalid core.after invocation") - jobs[#jobs + 1] = { - func = func, - expire = time + after, - arg = {...}, - mod_origin = core.get_last_run_mod() - } -end - function core.check_player_privs(name, ...) local arg_type = type(name) if (arg_type == "userdata" or arg_type == "table") and diff --git a/doc/client_lua_api.txt b/doc/client_lua_api.txt index c7329b0d8..8ce487bf8 100644 --- a/doc/client_lua_api.txt +++ b/doc/client_lua_api.txt @@ -706,6 +706,11 @@ Call these functions only at load time! * `parameters` is a sound parameter table * `minetest.sound_stop(handle)` +### Timing +* `minetest.after(time, func, ...)` + * Call the function `func` after `time` seconds, may be fractional + * Optional: Variable number of arguments that are passed to `func` + ### Misc. * `minetest.parse_json(string[, nullvalue])`: returns something * Convert a string containing JSON data into the Lua equivalent diff --git a/src/script/lua_api/l_util.cpp b/src/script/lua_api/l_util.cpp index 277a874bf..b9c334121 100644 --- a/src/script/lua_api/l_util.cpp +++ b/src/script/lua_api/l_util.cpp @@ -530,6 +530,8 @@ void ModApiUtil::InitializeClient(lua_State *L, int top) { API_FCT(log); + API_FCT(get_us_time); + API_FCT(setting_set); API_FCT(setting_get); API_FCT(setting_setbool);