summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcheapie <no-email-for-you@example.com>2022-01-01 20:49:11 -0600
committercheapie <no-email-for-you@example.com>2022-01-01 20:49:11 -0600
commit31d6b050873091b4958fb9aeb3081e0cc7bb8848 (patch)
treed074d442467f8043acb7dc8388f03640185a5f0a
parent59e6f5446152a1e254af549ea8a8b260dce230ba (diff)
downloadmesecons-31d6b050873091b4958fb9aeb3081e0cc7bb8848.tar
mesecons-31d6b050873091b4958fb9aeb3081e0cc7bb8848.tar.gz
mesecons-31d6b050873091b4958fb9aeb3081e0cc7bb8848.tar.bz2
mesecons-31d6b050873091b4958fb9aeb3081e0cc7bb8848.tar.xz
mesecons-31d6b050873091b4958fb9aeb3081e0cc7bb8848.zip
Allow IIDs to be used with lightweight interrupts
For now this does cause a minimum delay of one second to be enforced in lightweight mode.
-rw-r--r--mesecons_luacontroller/init.lua74
1 files changed, 70 insertions, 4 deletions
diff --git a/mesecons_luacontroller/init.lua b/mesecons_luacontroller/init.lua
index a689650..121e7b9 100644
--- a/mesecons_luacontroller/init.lua
+++ b/mesecons_luacontroller/init.lua
@@ -324,15 +324,54 @@ local function validate_iid(iid)
return true, "Table interrupt IDs are deprecated and are unreliable; use strings instead"
end
+local function get_next_nodetimer_interrupt(interrupts)
+ local nextint = 0
+ for k,v in pairs(interrupts) do
+ if nextint == 0 or v < nextint then
+ nextint = v
+ end
+ end
+ if nextint ~= 0 then return(nextint) end
+end
+
+local function get_current_nodetimer_interrupts(interrupts)
+ local current = {}
+ for k,v in pairs(interrupts) do
+ if v <= os.time() then
+ table.insert(current,k)
+ end
+ end
+ return(current)
+end
+
+local function set_nodetimer_interrupt(pos,time,iid)
+ if type(iid) ~= "string" then iid = "" end
+ local meta = minetest.get_meta(pos)
+ local timer = minetest.get_node_timer(pos)
+ local interrupts = minetest.deserialize(meta:get_string("interrupts")) or {}
+ if time == nil then
+ interrupts[iid] = nil
+ else
+ interrupts[iid] = os.time()+time
+ end
+ local nextint = get_next_nodetimer_interrupt(interrupts)
+ if nextint then
+ timer:start(nextint-os.time())
+ end
+ meta:set_string("interrupts",minetest.serialize(interrupts))
+end
+
-- The setting affects API so is not intended to be changeable at runtime
local get_interrupt
if mesecon.setting("luacontroller_lightweight_interrupts", false) then
-- use node timer
get_interrupt = function(pos, itbl, send_warning)
return (function(time, iid)
- if type(time) ~= "number" then error("Delay must be a number") end
- if iid ~= nil then send_warning("Interrupt IDs are disabled on this server") end
- table.insert(itbl, function() minetest.get_node_timer(pos):start(time) end)
+ if type(time) ~= "nil" and type(time) ~= "number" then error("Delay must be a number to set or nil to cancel") end
+ if type(time) == "number" and time < 1 then send_warning("Delays of less than 1 second are not allowed on this server") end
+ local ok, warn = validate_iid(iid)
+ if ok then set_nodetimer_interrupt(pos,time,iid) end
+ if warn then send_warning(warn) end
end)
end
else
@@ -719,11 +758,38 @@ local function reset(pos)
set_port_states(pos, {a=false, b=false, c=false, d=false})
end
+local function on_nodetimer_interrupt(pos)
+ local meta = minetest.get_meta(pos)
+ local timer = minetest.get_node_timer(pos)
+ local interrupts = minetest.deserialize(meta:get_string("interrupts")) or {}
+ local current = get_current_nodetimer_interrupts(interrupts)
+ for _,i in ipairs(current) do
+ interrupts[i] = nil
+ local event = {}
+ event.type = "interrupt"
+ event.iid = i
+ run(pos,event)
+ end
+ local interrupts = minetest.deserialize(meta:get_string("interrupts")) or {} --Reload as it may have changed
+ for _,i in ipairs(current) do
+ if interrupts[i] and interrupts[i] <= os.time() then
+ interrupts[i] = nil
+ end
+ end
+ local nextint = get_next_nodetimer_interrupt(interrupts)
+ if nextint then
+ timer:start(nextint-os.time())
+ else
+ timer:stop()
+ end
+ meta:set_string("interrupts",minetest.serialize(interrupts))
+end
+
local function node_timer(pos)
if minetest.registered_nodes[minetest.get_node(pos).name].is_burnt then
return false
end
- run(pos, {type="interrupt"})
+ on_nodetimer_interrupt(pos)
return false
end