use promises

This commit is contained in:
BuckarooBanzay 2023-04-17 07:42:43 +02:00
parent 5d4511edb9
commit afee95e2d2
9 changed files with 82 additions and 96 deletions

View File

@ -14,5 +14,5 @@ read_globals = {
"minetest", "minetest",
-- mods -- mods
"mapblock_lib", "mtt" "mapblock_lib", "mtt", "Promise"
} }

View File

@ -44,12 +44,8 @@ function building_lib.autoplace(mapblock_pos, playername, autoplacer_name, enabl
return false, building_name return false, building_name
end end
local err local p = building_lib.build(mapblock_pos, playername, building_name, rotation)
success, err = building_lib.build(mapblock_pos, playername, building_name, rotation) p:next(function()
if not success then
return success, err
end
local autoplacer = building_lib.get_autoplacer(autoplacer_name) local autoplacer = building_lib.get_autoplacer(autoplacer_name)
if enable_propagation and autoplacer.propagate then if enable_propagation and autoplacer.propagate then
-- propagate changes -- propagate changes
@ -62,6 +58,7 @@ function building_lib.autoplace(mapblock_pos, playername, autoplacer_name, enabl
end end
end end
end end
end)
return true return p
end end

View File

@ -39,13 +39,12 @@ function building_lib.can_build(mapblock_pos, _, building_name, rotation)
return true return true
end end
function building_lib.build(mapblock_pos, playername, building_name, rotation, callback) function building_lib.build(mapblock_pos, playername, building_name, rotation)
callback = callback or function() end
rotation = rotation or 0 rotation = rotation or 0
local success, message = building_lib.can_build(mapblock_pos, playername, building_name, rotation) local success, message = building_lib.can_build(mapblock_pos, playername, building_name, rotation)
if not success then if not success then
return false, message return Promise.rejected(message)
end end
local building_def = building_lib.get_building(building_name) local building_def = building_lib.get_building(building_name)
@ -84,8 +83,11 @@ function building_lib.build(mapblock_pos, playername, building_name, rotation, c
replacements = building_def.replace(mapblock_pos, building_def) replacements = building_def.replace(mapblock_pos, building_def)
end end
local promise = Promise.new()
placement.place(placement, mapblock_pos, building_def, replacements, rotation, function() placement.place(placement, mapblock_pos, building_def, replacements, rotation, function()
callback() promise:resolve()
if old_building_info then if old_building_info then
-- replacement -- replacement
local old_building_def = building_lib.get_building(old_building_info.name) local old_building_def = building_lib.get_building(old_building_info.name)
@ -111,7 +113,7 @@ function building_lib.build(mapblock_pos, playername, building_name, rotation, c
}) })
end end
end) end)
return true return promise
end end
-- mapgen build shortcut, only for 1x1x1 sized buildings -- mapgen build shortcut, only for 1x1x1 sized buildings

View File

@ -13,31 +13,29 @@ building_lib.register_building("building_lib:dummy_v2", {
} }
}) })
local mapblock_pos = {x=0, y=0, z=0}
local building_name = "building_lib:dummy"
local rotation = 0
local playername = "singleplayer"
mtt.register("build", function(callback) mtt.register("build", function(callback)
-- clear store -- clear store
building_lib.store:clear() building_lib.store:clear()
local mapblock_pos = {x=0, y=0, z=0}
local building_name = "building_lib:dummy"
local rotation = 0
local playername = "singleplayer"
-- try to build -- try to build
local success, err = building_lib.can_build(mapblock_pos, playername, building_name, rotation) local success, err = building_lib.can_build(mapblock_pos, playername, building_name, rotation)
assert(not err) assert(not err)
assert(success) assert(success)
-- build -- build
local callback_called = false building_lib.build(mapblock_pos, playername, building_name, rotation)
success, err = building_lib.build(mapblock_pos, playername, building_name, rotation, :next(callback)
function() callback_called = true end end)
)
assert(not err)
assert(success)
assert(callback_called)
mtt.register("try build again", function(callback)
-- try to build again -- try to build again
success, err = building_lib.can_build(mapblock_pos, playername, building_name, rotation) local success, err = building_lib.can_build(mapblock_pos, playername, building_name, rotation)
assert(err) assert(err)
assert(not success) assert(not success)
@ -56,16 +54,13 @@ mtt.register("build", function(callback)
assert(success) assert(success)
-- build over -- build over
callback_called = false building_lib.build(mapblock_pos, playername, "building_lib:dummy_v2", rotation)
success, err = building_lib.build(mapblock_pos, playername, "building_lib:dummy_v2", rotation, :next(callback)
function() callback_called = true end end)
)
assert(not err)
assert(success)
assert(callback_called)
mtt.register("remove and verify", function(callback)
-- try to remove -- try to remove
success, err = building_lib.can_remove(mapblock_pos) local success, err = building_lib.can_remove(mapblock_pos)
assert(not err) assert(not err)
assert(success) assert(success)
@ -75,7 +70,7 @@ mtt.register("build", function(callback)
assert(success) assert(success)
-- check -- check
info = building_lib.get_placed_building_info(mapblock_pos) local info = building_lib.get_placed_building_info(mapblock_pos)
assert(info == nil) assert(info == nil)
callback() callback()
@ -85,23 +80,12 @@ mtt.benchmark("build", function(callback, iterations)
-- clear store -- clear store
building_lib.store:clear() building_lib.store:clear()
local mapblock_pos = {x=0, y=0, z=0}
local building_name = "building_lib:dummy"
local rotation = 0
local playername = "singleplayer"
for _=1,iterations do for _=1,iterations do
-- build -- build
local callback_called = false building_lib.build(mapblock_pos, playername, building_name, rotation)
local success, err = building_lib.build(mapblock_pos, playername, building_name, rotation,
function() callback_called = true end
)
assert(not err)
assert(success)
assert(callback_called)
-- remove -- remove
success, err = building_lib.remove(mapblock_pos) local success, err = building_lib.remove(mapblock_pos)
assert(not err) assert(not err)
assert(success) assert(success)
end end

View File

@ -15,41 +15,38 @@ building_lib.register_building("building_lib:dummy_extension", {
} }
}) })
mtt.register("build-over", function(callback) local mapblock_pos = {x=0, y=0, z=0}
local playername = "singleplayer"
mtt.register("build-over (success)", function(callback)
-- clear store -- clear store
building_lib.store:clear() building_lib.store:clear()
local mapblock_pos = {x=0, y=0, z=0}
local rotation = 0
local playername = "singleplayer"
-- build -- build
local callback_called = false building_lib.build(mapblock_pos, playername, "building_lib:dummy_base", 0)
local success, err = building_lib.build(mapblock_pos, playername, "building_lib:dummy_base", rotation, :next(callback)
function() callback_called = true end :catch(callback)
) end)
assert(not err)
assert(success) mtt.register("build-over (wrong angle)", function(callback)
assert(callback_called) -- build
building_lib.build(mapblock_pos, playername, "building_lib:dummy_extension", 90)
-- build over (wrong angle) :catch(function()
success, err = building_lib.build(mapblock_pos, playername, "building_lib:dummy_extension", 90) callback()
assert(err) end)
assert(not success) end)
-- build over (wrong angle 2) mtt.register("build-over (wrong angle 2)", function(callback)
success, err = building_lib.build(mapblock_pos, playername, "building_lib:dummy_extension", 270) -- build
assert(err) building_lib.build(mapblock_pos, playername, "building_lib:dummy_extension", 270)
assert(not success) :catch(function()
callback()
-- build over (180° rotated) end)
callback_called = false end)
success, err = building_lib.build(mapblock_pos, playername, "building_lib:dummy_extension", 180,
function() callback_called = true end mtt.register("build-over (180°)", function(callback)
) -- build
assert(not err) building_lib.build(mapblock_pos, playername, "building_lib:dummy_extension", 180)
assert(success) :next(callback)
assert(callback_called) :catch(callback)
callback()
end) end)

View File

@ -107,10 +107,10 @@ minetest.register_tool("building_lib:place", {
local meta = itemstack:get_meta() local meta = itemstack:get_meta()
local buildingname = meta:get_string("buildingname") local buildingname = meta:get_string("buildingname")
local success, err = building_lib.build(pointed_mapblock_pos, playername, buildingname, rotation) building_lib.build(pointed_mapblock_pos, playername, buildingname, rotation)
if not success then :catch(function(err)
minetest.chat_send_player(playername, err) minetest.chat_send_player(playername, err)
end end)
end, end,
on_step = function(itemstack, player) on_step = function(itemstack, player)
local playername = player:get_player_name() local playername = player:get_player_name()

View File

@ -1,4 +1,4 @@
name = building_lib name = building_lib
description = Mapblock granular building placement and tools description = Mapblock granular building placement and tools
depends = mapblock_lib depends = mapblock_lib, promise
optional_depends = mtt optional_depends = mtt

View File

@ -8,7 +8,12 @@
local success, message = building_lib.can_build(mapblock_pos, playername, building_name, rotation) local success, message = building_lib.can_build(mapblock_pos, playername, building_name, rotation)
-- build it there -- build it there
local success, message = building_lib.build(mapblock_pos, playername, building_name, rotation, callback) local promise = building_lib.build(mapblock_pos, playername, building_name, rotation, callback)
promise:next(function()
-- success
end):catch(function(e)
-- error
end)
-- check if it can be removed -- check if it can be removed
local success, message = building_lib.can_remove(mapblock_pos) local success, message = building_lib.can_remove(mapblock_pos)

View File

@ -7,6 +7,7 @@ RUN apk add git &&\
cd /root/.minetest/worlds/world/worldmods &&\ cd /root/.minetest/worlds/world/worldmods &&\
git clone https://github.com/BuckarooBanzay/mtt &&\ git clone https://github.com/BuckarooBanzay/mtt &&\
git clone https://github.com/BuckarooBanzay/mtzip &&\ git clone https://github.com/BuckarooBanzay/mtzip &&\
git clone https://github.com/BuckarooBanzay/promise &&\
git clone https://github.com/BuckarooBanzay/mapblock_lib git clone https://github.com/BuckarooBanzay/mapblock_lib
ENTRYPOINT minetestserver --config /minetest.conf ENTRYPOINT minetestserver --config /minetest.conf