mirror of
https://github.com/luanti-org/luanti.git
synced 2025-07-22 17:18:39 +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
149
games/devtest/mods/unittests/async_env.lua
Normal file
149
games/devtest/mods/unittests/async_env.lua
Normal file
|
@ -0,0 +1,149 @@
|
|||
-- helper
|
||||
|
||||
core.register_async_dofile(core.get_modpath(core.get_current_modname()) ..
|
||||
DIR_DELIM .. "inside_async_env.lua")
|
||||
|
||||
local function deepequal(a, b)
|
||||
if type(a) == "function" then
|
||||
return type(b) == "function"
|
||||
elseif type(a) ~= "table" then
|
||||
return a == b
|
||||
elseif type(b) ~= "table" then
|
||||
return false
|
||||
end
|
||||
for k, v in pairs(a) do
|
||||
if not deepequal(v, b[k]) then
|
||||
return false
|
||||
end
|
||||
end
|
||||
for k, v in pairs(b) do
|
||||
if not deepequal(a[k], v) then
|
||||
return false
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
-- Object Passing / Serialization
|
||||
|
||||
local test_object = {
|
||||
name = "stairs:stair_glass",
|
||||
type = "node",
|
||||
groups = {oddly_breakable_by_hand = 3, cracky = 3, stair = 1},
|
||||
description = "Glass Stair",
|
||||
sounds = {
|
||||
dig = {name = "default_glass_footstep", gain = 0.5},
|
||||
footstep = {name = "default_glass_footstep", gain = 0.3},
|
||||
dug = {name = "default_break_glass", gain = 1}
|
||||
},
|
||||
node_box = {
|
||||
fixed = {
|
||||
{-0.5, -0.5, -0.5, 0.5, 0, 0.5},
|
||||
{-0.5, 0, 0, 0.5, 0.5, 0.5}
|
||||
},
|
||||
type = "fixed"
|
||||
},
|
||||
tiles = {
|
||||
{name = "stairs_glass_split.png", backface_culling = true},
|
||||
{name = "default_glass.png", backface_culling = true},
|
||||
{name = "stairs_glass_stairside.png^[transformFX", backface_culling = true}
|
||||
},
|
||||
on_place = function(itemstack, placer)
|
||||
return core.is_player(placer)
|
||||
end,
|
||||
sunlight_propagates = true,
|
||||
is_ground_content = false,
|
||||
light_source = 0,
|
||||
}
|
||||
|
||||
local function test_object_passing()
|
||||
local tmp = core.serialize_roundtrip(test_object)
|
||||
assert(deepequal(test_object, tmp))
|
||||
|
||||
-- Circular key, should error
|
||||
tmp = {"foo", "bar"}
|
||||
tmp[tmp] = true
|
||||
assert(not pcall(core.serialize_roundtrip, tmp))
|
||||
|
||||
-- Circular value, should error
|
||||
tmp = {"foo"}
|
||||
tmp[2] = tmp
|
||||
assert(not pcall(core.serialize_roundtrip, tmp))
|
||||
end
|
||||
unittests.register("test_object_passing", test_object_passing)
|
||||
|
||||
local function test_userdata_passing(_, pos)
|
||||
-- basic userdata passing
|
||||
local obj = table.copy(test_object.tiles[1])
|
||||
obj.test = ItemStack("default:cobble 99")
|
||||
local tmp = core.serialize_roundtrip(obj)
|
||||
assert(type(tmp.test) == "userdata")
|
||||
assert(obj.test:to_string() == tmp.test:to_string())
|
||||
|
||||
-- object can't be passed, should error
|
||||
obj = core.raycast(pos, pos)
|
||||
assert(not pcall(core.serialize_roundtrip, obj))
|
||||
|
||||
-- VManip
|
||||
local vm = core.get_voxel_manip(pos, pos)
|
||||
local expect = vm:get_node_at(pos)
|
||||
local vm2 = core.serialize_roundtrip(vm)
|
||||
assert(deepequal(vm2:get_node_at(pos), expect))
|
||||
end
|
||||
unittests.register("test_userdata_passing", test_userdata_passing, {map=true})
|
||||
|
||||
-- Asynchronous jobs
|
||||
|
||||
local function test_handle_async(cb)
|
||||
-- Basic test including mod name tracking and unittests.async_test()
|
||||
-- which is defined inside_async_env.lua
|
||||
local func = function(x)
|
||||
return core.get_last_run_mod(), _VERSION, unittests[x]()
|
||||
end
|
||||
local expect = {core.get_last_run_mod(), _VERSION, true}
|
||||
|
||||
core.handle_async(func, function(...)
|
||||
if not deepequal(expect, {...}) then
|
||||
cb("Values did not equal")
|
||||
end
|
||||
if core.get_last_run_mod() ~= expect[1] then
|
||||
cb("Mod name not tracked correctly")
|
||||
end
|
||||
|
||||
-- Test passing of nil arguments and return values
|
||||
core.handle_async(function(a, b)
|
||||
return a, b
|
||||
end, function(a, b)
|
||||
if b ~= 123 then
|
||||
cb("Argument went missing")
|
||||
end
|
||||
cb()
|
||||
end, nil, 123)
|
||||
end, "async_test")
|
||||
end
|
||||
unittests.register("test_handle_async", test_handle_async, {async=true})
|
||||
|
||||
local function test_userdata_passing2(cb, _, pos)
|
||||
-- VManip: check transfer into other env
|
||||
local vm = core.get_voxel_manip(pos, pos)
|
||||
local expect = vm:get_node_at(pos)
|
||||
|
||||
core.handle_async(function(vm_, pos_)
|
||||
return vm_:get_node_at(pos_)
|
||||
end, function(ret)
|
||||
if not deepequal(expect, ret) then
|
||||
cb("Node data mismatch (one-way)")
|
||||
end
|
||||
|
||||
-- VManip: test a roundtrip
|
||||
core.handle_async(function(vm_)
|
||||
return vm_
|
||||
end, function(vm2)
|
||||
if not deepequal(expect, vm2:get_node_at(pos)) then
|
||||
cb("Node data mismatch (roundtrip)")
|
||||
end
|
||||
cb()
|
||||
end, vm)
|
||||
end, vm, pos)
|
||||
end
|
||||
unittests.register("test_userdata_passing2", test_userdata_passing2, {map=true, async=true})
|
|
@ -175,6 +175,7 @@ dofile(modpath .. "/misc.lua")
|
|||
dofile(modpath .. "/player.lua")
|
||||
dofile(modpath .. "/crafting.lua")
|
||||
dofile(modpath .. "/itemdescription.lua")
|
||||
dofile(modpath .. "/async_env.lua")
|
||||
|
||||
--------------
|
||||
|
||||
|
|
15
games/devtest/mods/unittests/inside_async_env.lua
Normal file
15
games/devtest/mods/unittests/inside_async_env.lua
Normal file
|
@ -0,0 +1,15 @@
|
|||
unittests = {}
|
||||
|
||||
core.log("info", "Hello World")
|
||||
|
||||
function unittests.async_test()
|
||||
assert(core == minetest)
|
||||
-- stuff that should not be here
|
||||
assert(not core.get_player_by_name)
|
||||
assert(not core.set_node)
|
||||
assert(not core.object_refs)
|
||||
-- stuff that should be here
|
||||
assert(ItemStack)
|
||||
assert(core.registered_items[""])
|
||||
return true
|
||||
end
|
Loading…
Add table
Add a link
Reference in a new issue