mirror of
https://github.com/minetest-mods/mesecons.git
synced 2025-06-30 14:50:21 +02:00
Optimize light updates when turning conductors on and off (#578)
This commit is contained in:
committed by
GitHub
parent
9323445182
commit
ecea0a2896
@ -368,11 +368,66 @@ function mesecon.is_power_off(pos, rulename)
|
||||
return false
|
||||
end
|
||||
|
||||
-- The set of conductor states which require light updates when they change.
|
||||
local light_update_conductors
|
||||
|
||||
-- Calculate the contents of the above set if they have not been calculated.
|
||||
-- This must be called before get_update_light_conductor.
|
||||
local function find_light_update_conductors()
|
||||
-- The expensive calculation is only done the first time.
|
||||
if light_update_conductors then return end
|
||||
|
||||
light_update_conductors = {}
|
||||
|
||||
-- Find conductors whose lighting characteristics change depending on their state.
|
||||
local checked = {}
|
||||
for name, def in pairs(minetest.registered_nodes) do
|
||||
local conductor = mesecon.get_conductor(name)
|
||||
if conductor and not checked[name] then
|
||||
-- Find the other states of the conductor besides the current one.
|
||||
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
|
||||
|
||||
-- Check the conductor. Other states are marked as checked.
|
||||
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.
|
||||
-- The states are added to the set.
|
||||
light_update_conductors[name] = true
|
||||
for _, other_state in ipairs(other_states) do
|
||||
light_update_conductors[other_state] = true
|
||||
checked[other_state] = true
|
||||
end
|
||||
break
|
||||
end
|
||||
checked[other_state] = true
|
||||
end
|
||||
end
|
||||
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 function get_update_light_conductor(pos, name)
|
||||
return light_update_conductors[name] ~= nil
|
||||
end
|
||||
|
||||
-- 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.
|
||||
-- Follow all all conductor paths replacing conductors that were already
|
||||
-- looked at, activating / changing all effectors along the way.
|
||||
function mesecon.turnon(pos, link)
|
||||
find_light_update_conductors()
|
||||
|
||||
local frontiers = fifo_queue.new()
|
||||
frontiers:add({pos = pos, link = link})
|
||||
local pos_can_be_skipped = {}
|
||||
@ -398,7 +453,7 @@ function mesecon.turnon(pos, link)
|
||||
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
|
||||
|
||||
-- Only conductors with flat rules can be reliably skipped later
|
||||
@ -434,6 +489,8 @@ end
|
||||
-- depth = indicates order in which signals wire fired, higher is later
|
||||
-- }
|
||||
function mesecon.turnoff(pos, link)
|
||||
find_light_update_conductors()
|
||||
|
||||
local frontiers = fifo_queue.new()
|
||||
frontiers:add({pos = pos, link = link})
|
||||
local signals = {}
|
||||
@ -470,7 +527,7 @@ function mesecon.turnoff(pos, link)
|
||||
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
|
||||
|
||||
-- Only conductors with flat rules can be reliably skipped later
|
||||
|
Reference in New Issue
Block a user