mirror of
https://github.com/luanti-org/luanti.git
synced 2025-08-01 17:38:41 +00:00
Async environment for mods to do concurrent tasks (#11131)
This commit is contained in:
parent
663c936428
commit
e7659883cc
38 changed files with 1646 additions and 48 deletions
46
builtin/async/game.lua
Normal file
46
builtin/async/game.lua
Normal file
|
@ -0,0 +1,46 @@
|
|||
core.log("info", "Initializing asynchronous environment (game)")
|
||||
|
||||
local function pack2(...)
|
||||
return {n=select('#', ...), ...}
|
||||
end
|
||||
|
||||
-- Entrypoint to run async jobs, called by C++
|
||||
function core.job_processor(func, params)
|
||||
local retval = pack2(func(unpack(params, 1, params.n)))
|
||||
|
||||
return retval
|
||||
end
|
||||
|
||||
-- Import a bunch of individual files from builtin/game/
|
||||
local gamepath = core.get_builtin_path() .. "game" .. DIR_DELIM
|
||||
|
||||
dofile(gamepath .. "constants.lua")
|
||||
dofile(gamepath .. "item_s.lua")
|
||||
dofile(gamepath .. "misc_s.lua")
|
||||
dofile(gamepath .. "features.lua")
|
||||
dofile(gamepath .. "voxelarea.lua")
|
||||
|
||||
-- Transfer of globals
|
||||
do
|
||||
assert(core.transferred_globals)
|
||||
local all = core.deserialize(core.transferred_globals, true)
|
||||
core.transferred_globals = nil
|
||||
|
||||
-- reassemble other tables
|
||||
all.registered_nodes = {}
|
||||
all.registered_craftitems = {}
|
||||
all.registered_tools = {}
|
||||
for k, v in pairs(all.registered_items) do
|
||||
if v.type == "node" then
|
||||
all.registered_nodes[k] = v
|
||||
elseif v.type == "craftitem" then
|
||||
all.registered_craftitems[k] = v
|
||||
elseif v.type == "tool" then
|
||||
all.registered_tools[k] = v
|
||||
end
|
||||
end
|
||||
|
||||
for k, v in pairs(all) do
|
||||
core[k] = v
|
||||
end
|
||||
end
|
|
@ -1,5 +1,4 @@
|
|||
|
||||
core.log("info", "Initializing Asynchronous environment")
|
||||
core.log("info", "Initializing asynchronous environment")
|
||||
|
||||
function core.job_processor(func, serialized_param)
|
||||
local param = core.deserialize(serialized_param)
|
||||
|
@ -8,4 +7,3 @@ function core.job_processor(func, serialized_param)
|
|||
|
||||
return retval or core.serialize(nil)
|
||||
end
|
||||
|
22
builtin/game/async.lua
Normal file
22
builtin/game/async.lua
Normal file
|
@ -0,0 +1,22 @@
|
|||
|
||||
core.async_jobs = {}
|
||||
|
||||
function core.async_event_handler(jobid, retval)
|
||||
local callback = core.async_jobs[jobid]
|
||||
assert(type(callback) == "function")
|
||||
callback(unpack(retval, 1, retval.n))
|
||||
core.async_jobs[jobid] = nil
|
||||
end
|
||||
|
||||
function core.handle_async(func, callback, ...)
|
||||
assert(type(func) == "function" and type(callback) == "function",
|
||||
"Invalid minetest.handle_async invocation")
|
||||
local args = {n = select("#", ...), ...}
|
||||
local mod_origin = core.get_last_run_mod()
|
||||
|
||||
local jobid = core.do_async_callback(func, args, mod_origin)
|
||||
core.async_jobs[jobid] = callback
|
||||
|
||||
return true
|
||||
end
|
||||
|
|
@ -34,5 +34,6 @@ dofile(gamepath .. "voxelarea.lua")
|
|||
dofile(gamepath .. "forceloading.lua")
|
||||
dofile(gamepath .. "statbars.lua")
|
||||
dofile(gamepath .. "knockback.lua")
|
||||
dofile(gamepath .. "async.lua")
|
||||
|
||||
profiler = nil
|
||||
|
|
|
@ -235,3 +235,32 @@ end
|
|||
|
||||
-- Used for callback handling with dynamic_add_media
|
||||
core.dynamic_media_callbacks = {}
|
||||
|
||||
|
||||
-- Transfer of certain globals into async environment
|
||||
-- see builtin/async/game.lua for the other side
|
||||
|
||||
local function copy_filtering(t, seen)
|
||||
if type(t) == "userdata" or type(t) == "function" then
|
||||
return true -- don't use nil so presence can still be detected
|
||||
elseif type(t) ~= "table" then
|
||||
return t
|
||||
end
|
||||
local n = {}
|
||||
seen = seen or {}
|
||||
seen[t] = n
|
||||
for k, v in pairs(t) do
|
||||
local k_ = seen[k] or copy_filtering(k, seen)
|
||||
local v_ = seen[v] or copy_filtering(v, seen)
|
||||
n[k_] = v_
|
||||
end
|
||||
return n
|
||||
end
|
||||
|
||||
function core.get_globals_to_transfer()
|
||||
local all = {
|
||||
registered_items = copy_filtering(core.registered_items),
|
||||
registered_aliases = core.registered_aliases,
|
||||
}
|
||||
return core.serialize(all)
|
||||
end
|
||||
|
|
|
@ -56,8 +56,10 @@ elseif INIT == "mainmenu" then
|
|||
if not custom_loaded then
|
||||
dofile(core.get_mainmenu_path() .. DIR_DELIM .. "init.lua")
|
||||
end
|
||||
elseif INIT == "async" then
|
||||
dofile(asyncpath .. "init.lua")
|
||||
elseif INIT == "async" then
|
||||
dofile(asyncpath .. "mainmenu.lua")
|
||||
elseif INIT == "async_game" then
|
||||
dofile(asyncpath .. "game.lua")
|
||||
elseif INIT == "client" then
|
||||
dofile(clientpath .. "init.lua")
|
||||
else
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue