1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-06-27 16:36:03 +00:00

Make core.get_node_raw a public API (#16265)

Co-authored-by: Erich Schubert <erich.schubert@tu-dortmund.de>
This commit is contained in:
sfan5 2025-06-25 15:05:22 +02:00 committed by GitHub
parent 0794145b64
commit 8eceabd812
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 125 additions and 12 deletions

View file

@ -740,16 +740,16 @@ core.noneitemdef_default = { -- This is used for the hand and unknown items
-- --
local get_node_raw = core.get_node_raw local get_node_raw = core.get_node_raw
core.get_node_raw = nil local get_name_from_content_id = core.get_name_from_content_id
function core.get_node(pos) function core.get_node(pos)
local content, param1, param2 = get_node_raw(pos.x, pos.y, pos.z) local content, param1, param2 = get_node_raw(pos.x, pos.y, pos.z)
return {name = core.get_name_from_content_id(content), param1 = param1, param2 = param2} return {name = get_name_from_content_id(content), param1 = param1, param2 = param2}
end end
function core.get_node_or_nil(pos) function core.get_node_or_nil(pos)
local content, param1, param2, pos_ok = get_node_raw(pos.x, pos.y, pos.z) local content, param1, param2, pos_ok = get_node_raw(pos.x, pos.y, pos.z)
return pos_ok and return pos_ok and
{name = core.get_name_from_content_id(content), param1 = param1, param2 = param2} {name = get_name_from_content_id(content), param1 = param1, param2 = param2}
or nil or nil
end end

View file

@ -6481,6 +6481,11 @@ Environment access
* `core.get_node_or_nil(pos)` * `core.get_node_or_nil(pos)`
* Same as `get_node` but returns `nil` for unloaded areas. * Same as `get_node` but returns `nil` for unloaded areas.
* Note that even loaded areas can contain "ignore" nodes. * Note that even loaded areas can contain "ignore" nodes.
* `core.get_node_raw(x, y, z)`
* Same as `get_node` but a faster low-level API
* Returns `content_id`, `param1`, `param2`, and `pos_ok`
* The `content_id` can be mapped to a name using `core.get_name_from_content_id()`
* If `pos_ok` is false, the area is unloaded and `content_id == core.CONTENT_IGNORE`
* `core.get_node_light(pos[, timeofday])` * `core.get_node_light(pos[, timeofday])`
* Gets the light value at the given position. Note that the light value * Gets the light value at the given position. Note that the light value
"inside" the node at the given position is returned, so you usually want "inside" the node at the given position is returned, so you usually want

View file

@ -116,6 +116,7 @@ core.register_chatcommand("bench_bulk_set_node", {
((middle_time - start_time)) / 1000, ((middle_time - start_time)) / 1000,
((end_time - middle_time)) / 1000 ((end_time - middle_time)) / 1000
) )
print(msg)
return true, msg return true, msg
end, end,
}) })
@ -129,16 +130,13 @@ core.register_chatcommand("bench_bulk_get_node", {
return false, "No player." return false, "No player."
end end
local pos_list = get_positions_cube(player:get_pos()) local pos_list = get_positions_cube(player:get_pos())
local dummy = 0
local function bench() local function bench()
local start_time = core.get_us_time() local start_time = core.get_us_time()
for i = 1, #pos_list do for i = 1, #pos_list do
local n = core.get_node(pos_list[i]) local n = core.get_node(pos_list[i])
-- Make sure the name lookup is never optimized away. -- Make sure the name lookup is not optimized away (can this even happen?)
-- Table allocation might still be omitted. But only accessing dummy = dummy + #n.name
-- the name of a node is a common pattern anyways.
if n.name == "benchmarks:nonexistent_node" then
error("should never happen")
end
end end
return core.get_us_time() - start_time return core.get_us_time() - start_time
end end
@ -151,6 +149,115 @@ core.register_chatcommand("bench_bulk_get_node", {
local msg = string.format("Benchmark results: core.get_node loop 1: %.2f ms", local msg = string.format("Benchmark results: core.get_node loop 1: %.2f ms",
result_us / 1000) result_us / 1000)
print(msg)
return true, msg
end,
})
core.register_chatcommand("bench_bulk_get_node_raw", {
params = "",
description = "Benchmark: Bulk-get 99×99×99 nodes with raw API",
func = function(name, param)
local player = core.get_player_by_name(name)
if not player then
return false, "No player."
end
local pos_list = get_positions_cube(player:get_pos())
local dummy = 0
local function bench()
local start_time = core.get_us_time()
for i = 1, #pos_list do
local pos_i = pos_list[i]
local nid = core.get_node_raw(pos_i.x, pos_i.y, pos_i.z)
-- Make sure the result is not optimized away
dummy = dummy + nid
end
return core.get_us_time() - start_time
end
core.chat_send_player(name, "Benchmarking core.get_node_raw. Warming up ...")
bench()
core.chat_send_player(name, "Warming up finished, now benchmarking ...")
local result_us = bench()
local msg = string.format("Benchmark results: core.get_node_raw loop 1: %.2f ms",
result_us / 1000)
print(msg)
return true, msg
end,
})
core.register_chatcommand("bench_bulk_get_node_raw2", {
params = "",
description = "Benchmark: Bulk-get 99×99×99 nodes with raw API and lookup names",
func = function(name, param)
local player = core.get_player_by_name(name)
if not player then
return false, "No player."
end
local pos_list = get_positions_cube(player:get_pos())
local dummy = 0
local function bench()
local start_time = core.get_us_time()
for i = 1, #pos_list do
local pos_i = pos_list[i]
local nid = core.get_node_raw(pos_i.x, pos_i.y, pos_i.z)
local name = core.get_name_from_content_id(nid)
-- Make sure the name lookup is not optimized away
dummy = dummy + #name
end
return core.get_us_time() - start_time
end
core.chat_send_player(name, "Benchmarking core.get_node_raw+get_name_from_content_id. Warming up ...")
bench()
core.chat_send_player(name, "Warming up finished, now benchmarking ...")
local result_us = bench()
local msg = string.format("Benchmark results: core.get_node_raw+get_name_from_content_id loop 1: %.2f ms",
result_us / 1000)
print(msg)
return true, msg
end,
})
core.register_chatcommand("bench_bulk_get_node_vm", {
params = "",
description = "Benchmark: Bulk-get 99×99×99 nodes with voxel manipulator",
func = function(name, param)
local player = core.get_player_by_name(name)
if not player then
return false, "No player."
end
local pos = player:get_pos()
local dummy = 0
local function bench()
local start_time = core.get_us_time()
local vm = core.get_voxel_manip(pos:offset(1,1,1), pos:offset(100,100,100))
local data = vm:get_data()
local mid_time = core.get_us_time()
-- Note that the VManip will actually retrieve more than just the 100³ nodes
-- and also we don't need to iterate pos_list here, so it's not an entirely
-- fair comparison.
for i = 1, 99*99*99 do
local nid = data[i]
-- Make sure the table lookup is not optimized away
dummy = dummy + nid
end
return core.get_us_time() - start_time, mid_time - start_time
end
core.chat_send_player(name, "Benchmarking core.get_voxel_vmanip+get_data+loop . Warming up ...")
bench()
core.chat_send_player(name, "Warming up finished, now benchmarking ...")
local result_us, get_data_us = bench()
local msg = string.format("Benchmark results: core.get_voxel_vmanip+get_data+loop loop 1: %.2f ms of which get_data() %.2f ms",
result_us / 1000, get_data_us / 1000)
print(msg)
return true, msg return true, msg
end, end,
}) })
@ -184,6 +291,7 @@ core.register_chatcommand("bench_bulk_swap_node", {
((middle_time - start_time)) / 1000, ((middle_time - start_time)) / 1000,
((end_time - middle_time)) / 1000 ((end_time - middle_time)) / 1000
) )
print(msg)
return true, msg return true, msg
end, end,
}) })