mirror of
https://github.com/minetest-mods/mesecons.git
synced 2024-09-27 23:00:29 +02:00
Optimize light updates when turning on and off
This commit is contained in:
parent
9323445182
commit
8277799f29
|
@ -368,6 +368,48 @@ function mesecon.is_power_off(pos, rulename)
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- This is the callback for swap_node_force in turnon and turnoff. It determines
|
||||||
|
-- whether a conductor node necessitates a lighting update.
|
||||||
|
local cached_update_light = {}
|
||||||
|
local function get_update_light_conductor(pos, name)
|
||||||
|
local update_light = cached_update_light[name]
|
||||||
|
|
||||||
|
if update_light == nil then
|
||||||
|
-- Calculate and cache whether the conductor needs light updates.
|
||||||
|
|
||||||
|
local def = minetest.registered_nodes[name]
|
||||||
|
|
||||||
|
local conductor = mesecon.get_conductor(name)
|
||||||
|
local other_states
|
||||||
|
if conductor.onstate then
|
||||||
|
other_states = {conductor.onstate}
|
||||||
|
elseif conductor.offstate then
|
||||||
|
other_states = {conductor.offstate}
|
||||||
|
else
|
||||||
|
other_states = conductor.states
|
||||||
|
end
|
||||||
|
|
||||||
|
update_light = false
|
||||||
|
for _, other_state in ipairs(other_states) do
|
||||||
|
local other_def = minetest.registered_nodes[other_state]
|
||||||
|
if (def.paramtype == "light") ~= (other_def.paramtype == "light")
|
||||||
|
or def.sunlight_propagates ~= other_def.sunlight_propagates
|
||||||
|
or def.light_source ~= other_def.light_source then
|
||||||
|
-- The light characteristics change depending on the state.
|
||||||
|
update_light = true
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
cached_update_light[name] = update_light
|
||||||
|
for _, other_state in ipairs(other_states) do
|
||||||
|
cached_update_light[other_state] = update_light
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return update_light
|
||||||
|
end
|
||||||
|
|
||||||
-- Turn off an equipotential section starting at `pos`, which outputs in the direction of `link`.
|
-- Turn off an equipotential section starting at `pos`, which outputs in the direction of `link`.
|
||||||
-- Breadth-first search. Map is abstracted away in a voxelmanip.
|
-- Breadth-first search. Map is abstracted away in a voxelmanip.
|
||||||
-- Follow all all conductor paths replacing conductors that were already
|
-- Follow all all conductor paths replacing conductors that were already
|
||||||
|
@ -398,7 +440,7 @@ function mesecon.turnon(pos, link)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
mesecon.swap_node_force(f.pos, mesecon.get_conductor_on(node, f.link))
|
mesecon.swap_node_force(f.pos, mesecon.get_conductor_on(node, f.link), get_update_light_conductor)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Only conductors with flat rules can be reliably skipped later
|
-- Only conductors with flat rules can be reliably skipped later
|
||||||
|
@ -470,7 +512,7 @@ function mesecon.turnoff(pos, link)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
mesecon.swap_node_force(f.pos, mesecon.get_conductor_off(node, f.link))
|
mesecon.swap_node_force(f.pos, mesecon.get_conductor_off(node, f.link), get_update_light_conductor)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Only conductors with flat rules can be reliably skipped later
|
-- Only conductors with flat rules can be reliably skipped later
|
||||||
|
|
|
@ -343,7 +343,7 @@ function mesecon.vm_commit()
|
||||||
if tbl.dirty then
|
if tbl.dirty then
|
||||||
local vm = tbl.vm
|
local vm = tbl.vm
|
||||||
vm:set_data(tbl.data)
|
vm:set_data(tbl.data)
|
||||||
vm:write_to_map()
|
vm:write_to_map(tbl.update_light)
|
||||||
vm:update_map()
|
vm:update_map()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -364,7 +364,7 @@ local function vm_get_or_create_entry(pos)
|
||||||
local vm = minetest.get_voxel_manip(pos, pos)
|
local vm = minetest.get_voxel_manip(pos, pos)
|
||||||
local min_pos, max_pos = vm:get_emerged_area()
|
local min_pos, max_pos = vm:get_emerged_area()
|
||||||
local va = VoxelArea:new{MinEdge = min_pos, MaxEdge = max_pos}
|
local va = VoxelArea:new{MinEdge = min_pos, MaxEdge = max_pos}
|
||||||
tbl = {vm = vm, va = va, data = vm:get_data(), param1 = vm:get_light_data(), param2 = vm:get_param2_data(), dirty = false}
|
tbl = {vm = vm, va = va, data = vm:get_data(), param1 = vm:get_light_data(), param2 = vm:get_param2_data(), dirty = false, update_light = false}
|
||||||
vm_cache[hash] = tbl
|
vm_cache[hash] = tbl
|
||||||
end
|
end
|
||||||
return tbl
|
return tbl
|
||||||
|
@ -388,8 +388,11 @@ end
|
||||||
-- Sets a node’s name during a VoxelManipulator-based transaction.
|
-- Sets a node’s name during a VoxelManipulator-based transaction.
|
||||||
--
|
--
|
||||||
-- Existing param1, param2, and metadata are left alone.
|
-- Existing param1, param2, and metadata are left alone.
|
||||||
function mesecon.vm_swap_node(pos, name)
|
--
|
||||||
|
-- See mesecon.swap_node_force for documentation about get_update_light.
|
||||||
|
function mesecon.vm_swap_node(pos, name, get_update_light)
|
||||||
local tbl = vm_get_or_create_entry(pos)
|
local tbl = vm_get_or_create_entry(pos)
|
||||||
|
tbl.update_light = tbl.update_light or (get_update_light == nil or get_update_light(pos, name))
|
||||||
local index = tbl.va:indexp(pos)
|
local index = tbl.va:indexp(pos)
|
||||||
tbl.data[index] = minetest.get_content_id(name)
|
tbl.data[index] = minetest.get_content_id(name)
|
||||||
tbl.dirty = true
|
tbl.dirty = true
|
||||||
|
@ -423,13 +426,15 @@ end
|
||||||
-- Outside a VM transaction, if the mapblock is not loaded, it is pulled into
|
-- Outside a VM transaction, if the mapblock is not loaded, it is pulled into
|
||||||
-- the server’s main map data cache and then accessed from there.
|
-- the server’s main map data cache and then accessed from there.
|
||||||
--
|
--
|
||||||
-- Inside a VM transaction, the transaction’s VM cache is used.
|
-- Inside a VM transaction, the transaction’s VM cache is used. If a third
|
||||||
|
-- argument is supplied, it may be called. If it returns false, the swap does
|
||||||
|
-- not necessitate a lighting update.
|
||||||
--
|
--
|
||||||
-- This function can only be used to change the node’s name, not its parameters
|
-- This function can only be used to change the node’s name, not its parameters
|
||||||
-- or metadata.
|
-- or metadata.
|
||||||
function mesecon.swap_node_force(pos, name)
|
function mesecon.swap_node_force(pos, name, get_update_light)
|
||||||
if vm_cache then
|
if vm_cache then
|
||||||
return mesecon.vm_swap_node(pos, name)
|
return mesecon.vm_swap_node(pos, name, get_update_light)
|
||||||
else
|
else
|
||||||
-- This serves to both ensure the mapblock is loaded and also hand us
|
-- This serves to both ensure the mapblock is loaded and also hand us
|
||||||
-- the old node table so we can preserve param2.
|
-- the old node table so we can preserve param2.
|
||||||
|
|
Loading…
Reference in New Issue
Block a user