Calculate light update conductors at the beginning
This was suggested by sfan5. This saves on memory, and I think it's a bit faster too. I didn't use register_on_mods_loaded. This is because other mods might register their own callbacks which run after mesecons'. These callbacks could override node properties. The code does not check the same conductor twice. This makes the code a bit more complicated, but some conductors have many states. If a conductor has 16 states, it requires 256 checks in the initial light update calculation. I think this is worth avoiding, especially since I don't know the maximum number of states a conductor can have.
This commit is contained in:
parent
8277799f29
commit
bbc6391e0a
|
@ -368,46 +368,59 @@ function mesecon.is_power_off(pos, rulename)
|
|||
return false
|
||||
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]
|
||||
-- The set of conductor states which require light updates when they change.
|
||||
local light_update_conductors
|
||||
|
||||
if update_light == nil then
|
||||
-- Calculate and cache whether the conductor needs light updates.
|
||||
-- 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
|
||||
|
||||
local def = minetest.registered_nodes[name]
|
||||
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)
|
||||
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
|
||||
if conductor then
|
||||
if 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
|
||||
|
||||
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
|
||||
-- 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
|
||||
|
||||
cached_update_light[name] = update_light
|
||||
for _, other_state in ipairs(other_states) do
|
||||
cached_update_light[other_state] = update_light
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return update_light
|
||||
-- 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`.
|
||||
|
@ -415,6 +428,8 @@ end
|
|||
-- 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 = {}
|
||||
|
@ -476,6 +491,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 = {}
|
||||
|
|
Loading…
Reference in New Issue