diff --git a/technic/machines/network.lua b/technic/machines/network.lua index b445aa4..981bb5f 100644 --- a/technic/machines/network.lua +++ b/technic/machines/network.lua @@ -4,7 +4,9 @@ local S = technic.getter local switch_max_range = tonumber(minetest.settings:get("technic.switch_max_range") or "256") +local off_delay_seconds = tonumber(minetest.settings:get("technic.switch.off_delay_seconds") or "1800") +technic.active_networks = {} technic.networks = {} technic.cables = {} @@ -18,10 +20,12 @@ function technic.create_network(sw_pos) end function technic.activate_network(network_id, timeout) - assert(network_id) + -- timeout is optional ttl for network in seconds, if not specified use default local network = technic.networks[network_id] - if network and (timeout or network.timeout < 4) then - network.timeout = timeout or 4 + if network then + -- timeout is absolute time in microseconds + network.timeout = minetest.get_us_time() + ((timeout or off_delay_seconds) * 1000 * 1000) + technic.active_networks[network_id] = network end end @@ -44,6 +48,7 @@ function technic.remove_network(network_id) end end technic.networks[network_id] = nil + technic.active_networks[network_id] = nil --print(string.format("technic.remove_network(%.17g) at %s", network_id, minetest.pos_to_string(technic.network2pos(network_id)))) end @@ -285,9 +290,14 @@ function technic.build_network(network_id) return end local network = { + -- Basic network data and lookup table for attached nodes (no switching stations) id = network_id, tier = tier, all_nodes = {}, + -- Indexed arrays for iteration by machine type SP_nodes = {}, PR_nodes = {}, RE_nodes = {}, BA_nodes = {}, - supply = 0, demand = 0, timeout = 4, battery_charge = 0, battery_charge_max = 0, + -- Power generation, usage and capacity related variables + supply = 0, demand = 0, battery_charge = 0, battery_charge_max = 0, + -- Network activation and excution control + timeout = 0, skip = 0, } -- Add first cable (one that is holding network id) and build network local queue = {} diff --git a/technic/machines/switching_station.lua b/technic/machines/switching_station.lua index 0bd8ef1..f0e66cd 100644 --- a/technic/machines/switching_station.lua +++ b/technic/machines/switching_station.lua @@ -173,7 +173,7 @@ minetest.register_abm({ end technic.network_infotext(network_id, infotext) else - -- Network exists and is not overloaded, reactivate for 4 seconds + -- Network exists and is not overloaded, reactivate network technic.activate_network(network_id) infotext = technic.network_infotext(network_id) end diff --git a/technic/machines/switching_station_globalstep.lua b/technic/machines/switching_station_globalstep.lua index bed6f07..98ee41a 100644 --- a/technic/machines/switching_station_globalstep.lua +++ b/technic/machines/switching_station_globalstep.lua @@ -1,22 +1,6 @@ local has_monitoring_mod = minetest.get_modpath("monitoring") -local switches = {} -- pos_hash -> { time = time_us } - -local function get_switch_data(network_id) - local switch = switches[network_id] - - if not switch then - switch = { - time = 0, - skip = 0 - } - switches[network_id] = switch - end - - return switch -end - local active_switching_stations_metric, switching_stations_usage_metric if has_monitoring_mod then @@ -31,30 +15,10 @@ if has_monitoring_mod then ) end --- collect all active switching stations -minetest.register_abm({ - nodenames = {"technic:switching_station"}, - label = "Switching Station", - interval = 1, - chance = 1, - action = function(pos) - local network_id = technic.sw_pos2network(pos) - if network_id then - if technic.is_overloaded(network_id) then - switches[network_id] = nil - else - local switch = get_switch_data(network_id) - switch.time = minetest.get_us_time() - end - end - end -}) - -- the interval between technic_run calls local technic_run_interval = 1.0 -- iterate over all collected switching stations and execute the technic_run function -local off_delay_seconds = tonumber(minetest.settings:get("technic.switch.off_delay_seconds") or "1800") local timer = 0 minetest.register_globalstep(function(dtime) timer = timer + dtime @@ -80,27 +44,24 @@ minetest.register_globalstep(function(dtime) local now = minetest.get_us_time() - local off_delay_micros = off_delay_seconds*1000*1000 - local active_switches = 0 - for network_id, switch in pairs(switches) do + for network_id, network in pairs(technic.active_networks) do local pos = technic.network2sw_pos(network_id) - local network = technic.networks[network_id] - local diff = now - switch.time - minetest.get_voxel_manip(pos, pos) - local node = minetest.get_node(pos) + local node = technic.get_or_load_node(pos) or minetest.get_node(pos) - if network == nil or node.name ~= "technic:switching_station" then + if node.name ~= "technic:switching_station" then -- station vanished - switches[network_id] = nil + technic.active_networks[network_id] = nil - elseif diff < off_delay_micros then + elseif network.timeout > now then -- station active active_switches = active_switches + 1 - if switch.skip < 1 then + if network.skip > 0 then + network.skip = network.skip - 1 + else local start = minetest.get_us_time() technic.network_run(network_id) @@ -111,34 +72,30 @@ minetest.register_globalstep(function(dtime) -- overload detection if switch_diff > 250000 then - switch.skip = 30 + network.skip = 30 elseif switch_diff > 150000 then - switch.skip = 20 + network.skip = 20 elseif switch_diff > 75000 then - switch.skip = 10 + network.skip = 10 elseif switch_diff > 50000 then - switch.skip = 2 + network.skip = 2 end - if switch.skip > 0 then + if network.skip > 0 then -- calculate efficiency in percent and display it - local efficiency = math.floor(1/switch.skip*100) + local efficiency = math.floor(1/network.skip*100) technic.network_infotext(network_id, "Polyfuse triggered, current efficiency: " .. efficiency .. "% generated lag : " .. math.floor(switch_diff/1000) .. " ms") - -- remove laggy switching station from active index + -- remove laggy network from active index -- it will be reactivated when a player is near it - -- laggy switching stations won't work well in unloaded areas this way - switches[network_id] = nil + technic.active_networks[network_id] = nil end - - else - switch.skip = math.max(switch.skip - 1, 0) end else -- station timed out - switches[network_id] = nil + technic.active_networks[network_id] = nil end end @@ -152,9 +109,9 @@ minetest.register_globalstep(function(dtime) end) minetest.register_chatcommand("technic_flush_switch_cache", { - description = "removes all loaded switching stations from the cache", + description = "removes all loaded networks from the cache", privs = { server = true }, func = function() - switches = {} + technic.active_networks = {} end })