mirror of
https://github.com/minetest-mods/mesecons.git
synced 2025-11-20 12:05:23 +01:00
Luacontroller: Add overheat factor for deferred tasks
This commit is contained in:
@@ -12,12 +12,12 @@
|
|||||||
-- ports = get_real_port_states(pos): gets if inputs are powered from outside
|
-- ports = get_real_port_states(pos): gets if inputs are powered from outside
|
||||||
-- newport = merge_port_states(state1, state2): just does result = state1 or state2 for every port
|
-- newport = merge_port_states(state1, state2): just does result = state1 or state2 for every port
|
||||||
-- set_port(pos, rule, state): activates/deactivates the mesecons according to the port states
|
-- set_port(pos, rule, state): activates/deactivates the mesecons according to the port states
|
||||||
-- set_port_states(pos, ports): Applies new port states to a Luacontroller at pos
|
-- set_port_states(pos, ports, ignore_overheat): Applies new port states to a Luacontroller at pos
|
||||||
-- run_inner(pos, code, event): runs code on the controller at pos and event
|
-- run_inner(pos, code, event): runs code on the controller at pos and event
|
||||||
-- reset_formspec(pos, code, errmsg): installs new code and prints error messages, without resetting LCID
|
-- reset_formspec(pos, code, errmsg): installs new code and prints error messages, without resetting LCID
|
||||||
-- reset_meta(pos, code, errmsg): performs a software-reset, installs new code and prints error message
|
-- reset_meta(pos, code, errmsg): performs a software-reset, installs new code and prints error message
|
||||||
-- run(pos, event): a wrapper for run_inner which gets code & handles errors via reset_meta
|
-- run(pos, event): a wrapper for run_inner which gets code & handles errors via reset_meta
|
||||||
-- resetn(pos): performs a hardware reset, turns off all ports
|
-- reset(pos): performs a hardware reset, turns off all ports
|
||||||
--
|
--
|
||||||
-- The Sandbox
|
-- The Sandbox
|
||||||
-- The whole code of the controller runs in a sandbox,
|
-- The whole code of the controller runs in a sandbox,
|
||||||
@@ -129,10 +129,15 @@ local function clean_port_states(ports)
|
|||||||
ports.d = ports.d and true or false
|
ports.d = ports.d and true or false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local is_controller_burnt
|
||||||
|
|
||||||
local function set_port_states(pos, ports)
|
local function set_port_states(pos, ports, ignore_overheat)
|
||||||
local node = minetest.get_node(pos)
|
local node = minetest.get_node(pos)
|
||||||
local name = node.name
|
local name = node.name
|
||||||
|
if not ignore_overheat and is_controller_burnt(name) then
|
||||||
|
return -- Avoid swapping back to a non-burnt node
|
||||||
|
end
|
||||||
|
|
||||||
clean_port_states(ports)
|
clean_port_states(ports)
|
||||||
local vports = minetest.registered_nodes[name].virtual_portstates
|
local vports = minetest.registered_nodes[name].virtual_portstates
|
||||||
local new_name = generate_name(ports)
|
local new_name = generate_name(ports)
|
||||||
@@ -168,6 +173,16 @@ end
|
|||||||
-----------------
|
-----------------
|
||||||
-- Overheating --
|
-- Overheating --
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
-- Overheating factor of deferred tasks (e.g. digilines).
|
||||||
|
-- Higher values result in faster overheating.
|
||||||
|
-- See also: settings 'overheat_max' and 'cooldown_time'
|
||||||
|
local TASK_HEAT_FACTOR = 0.8
|
||||||
|
|
||||||
|
is_controller_burnt = function(node_name)
|
||||||
|
return node_name == (BASENAME .. "_burnt")
|
||||||
|
end
|
||||||
|
|
||||||
local function burn_controller(pos)
|
local function burn_controller(pos)
|
||||||
local node = minetest.get_node(pos)
|
local node = minetest.get_node(pos)
|
||||||
node.name = BASENAME.."_burnt"
|
node.name = BASENAME.."_burnt"
|
||||||
@@ -178,6 +193,10 @@ local function burn_controller(pos)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function overheat(pos)
|
local function overheat(pos)
|
||||||
|
if is_controller_burnt(core.get_node(pos).name) then
|
||||||
|
-- Avoid spamming "Node overheats" log messages.
|
||||||
|
return true
|
||||||
|
end
|
||||||
if mesecon.do_overheat(pos) then -- If too hot
|
if mesecon.do_overheat(pos) then -- If too hot
|
||||||
burn_controller(pos)
|
burn_controller(pos)
|
||||||
return true
|
return true
|
||||||
@@ -450,6 +469,10 @@ local function get_digiline_send(pos, itbl, send_warning)
|
|||||||
local chan_maxlen = mesecon.setting("luacontroller_digiline_channel_maxlen", 256)
|
local chan_maxlen = mesecon.setting("luacontroller_digiline_channel_maxlen", 256)
|
||||||
local maxlen = mesecon.setting("luacontroller_digiline_maxlen", 50000)
|
local maxlen = mesecon.setting("luacontroller_digiline_maxlen", 50000)
|
||||||
return function(channel, msg)
|
return function(channel, msg)
|
||||||
|
if is_controller_burnt(pos) then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
-- NOTE: This runs within string metatable sandbox, so don't *rely* on anything of the form (""):y
|
-- NOTE: This runs within string metatable sandbox, so don't *rely* on anything of the form (""):y
|
||||||
-- or via anything that could.
|
-- or via anything that could.
|
||||||
-- Make sure channel is string, number or boolean
|
-- Make sure channel is string, number or boolean
|
||||||
@@ -677,6 +700,13 @@ local function run_inner(pos, code, event)
|
|||||||
-- Save memory. This may burn the luacontroller if a memory overflow occurs.
|
-- Save memory. This may burn the luacontroller if a memory overflow occurs.
|
||||||
save_memory(pos, meta, env.mem)
|
save_memory(pos, meta, env.mem)
|
||||||
|
|
||||||
|
-- Action queues can escape the sandbox, thus give a harsh penalty.
|
||||||
|
for i = 1, math.floor(#itbl * TASK_HEAT_FACTOR + 0.5) do
|
||||||
|
if overheat(pos) then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- Execute deferred tasks
|
-- Execute deferred tasks
|
||||||
for _, v in ipairs(itbl) do
|
for _, v in ipairs(itbl) do
|
||||||
local failure = v()
|
local failure = v()
|
||||||
@@ -684,13 +714,15 @@ local function run_inner(pos, code, event)
|
|||||||
return false, failure
|
return false, failure
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return true, warning
|
return true, warning
|
||||||
end
|
end
|
||||||
|
|
||||||
local function reset_formspec(meta, code, errmsg)
|
local function reset_formspec(meta, code, errmsg)
|
||||||
|
code = code or ""
|
||||||
meta:set_string("code", code)
|
meta:set_string("code", code)
|
||||||
meta:mark_as_private("code")
|
meta:mark_as_private("code")
|
||||||
code = minetest.formspec_escape(code or "")
|
code = minetest.formspec_escape(code)
|
||||||
errmsg = minetest.formspec_escape(tostring(errmsg or ""))
|
errmsg = minetest.formspec_escape(tostring(errmsg or ""))
|
||||||
meta:set_string("formspec", "size[12,10]"
|
meta:set_string("formspec", "size[12,10]"
|
||||||
.."style_type[label,textarea;font=mono]"
|
.."style_type[label,textarea;font=mono]"
|
||||||
@@ -722,11 +754,11 @@ local function run(pos, event)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function reset(pos)
|
local function reset(pos)
|
||||||
set_port_states(pos, {a=false, b=false, c=false, d=false})
|
set_port_states(pos, {a=false, b=false, c=false, d=false}, true)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function node_timer(pos)
|
local function node_timer(pos)
|
||||||
if minetest.registered_nodes[minetest.get_node(pos).name].is_burnt then
|
if is_controller_burnt(core.get_node(pos).name) then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
run(pos, {type="interrupt"})
|
run(pos, {type="interrupt"})
|
||||||
@@ -740,7 +772,7 @@ end
|
|||||||
mesecon.queue:add_function("lc_interrupt", function (pos, luac_id, iid)
|
mesecon.queue:add_function("lc_interrupt", function (pos, luac_id, iid)
|
||||||
-- There is no luacontroller anymore / it has been reprogrammed / replaced / burnt
|
-- There is no luacontroller anymore / it has been reprogrammed / replaced / burnt
|
||||||
if (minetest.get_meta(pos):get_int("luac_id") ~= luac_id) then return end
|
if (minetest.get_meta(pos):get_int("luac_id") ~= luac_id) then return end
|
||||||
if (minetest.registered_nodes[minetest.get_node(pos).name].is_burnt) then return end
|
if is_controller_burnt(core.get_node(pos).name) then return end
|
||||||
run(pos, {type="interrupt", iid = iid})
|
run(pos, {type="interrupt", iid = iid})
|
||||||
end)
|
end)
|
||||||
|
|
||||||
@@ -748,7 +780,7 @@ mesecon.queue:add_function("lc_digiline_relay", function (pos, channel, luac_id,
|
|||||||
if not digiline then return end
|
if not digiline then return end
|
||||||
-- This check is only really necessary because in case of server crash, old actions can be thrown into the future
|
-- This check is only really necessary because in case of server crash, old actions can be thrown into the future
|
||||||
if (minetest.get_meta(pos):get_int("luac_id") ~= luac_id) then return end
|
if (minetest.get_meta(pos):get_int("luac_id") ~= luac_id) then return end
|
||||||
if (minetest.registered_nodes[minetest.get_node(pos).name].is_burnt) then return end
|
if is_controller_burnt(core.get_node(pos).name) then return end
|
||||||
-- The actual work
|
-- The actual work
|
||||||
digiline:receptor_send(pos, digiline.rules.default, channel, msg)
|
digiline:receptor_send(pos, digiline.rules.default, channel, msg)
|
||||||
end)
|
end)
|
||||||
@@ -929,7 +961,6 @@ minetest.register_node(BASENAME .. "_burnt", {
|
|||||||
"jeija_microcontroller_sides.png"
|
"jeija_microcontroller_sides.png"
|
||||||
},
|
},
|
||||||
inventory_image = "jeija_luacontroller_burnt_top.png",
|
inventory_image = "jeija_luacontroller_burnt_top.png",
|
||||||
is_burnt = true,
|
|
||||||
paramtype = "light",
|
paramtype = "light",
|
||||||
is_ground_content = false,
|
is_ground_content = false,
|
||||||
groups = {dig_immediate=2, not_in_creative_inventory=1},
|
groups = {dig_immediate=2, not_in_creative_inventory=1},
|
||||||
|
|||||||
Reference in New Issue
Block a user