aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authororwell96 <orwell@bleipb.de>2021-02-17 19:45:52 +0100
committerorwell96 <orwell@bleipb.de>2021-02-17 19:45:52 +0100
commit04c78373f1db0b011557b92cd6fb58268cbeefe4 (patch)
tree8d79d0b946d2bd59d4e9bf891d120e18ae4630a8
parent1e4156d0a4e42b519ca2f64f4146c7a7faec49a3 (diff)
downloadadvtrains-04c78373f1db0b011557b92cd6fb58268cbeefe4.tar.gz
advtrains-04c78373f1db0b011557b92cd6fb58268cbeefe4.tar.bz2
advtrains-04c78373f1db0b011557b92cd6fb58268cbeefe4.zip
LuaATC: add interrupt_safe() and clear_interrupts(), fix queue mainloop
-rw-r--r--advtrains_luaautomation/README.md15
-rw-r--r--advtrains_luaautomation/active_common.lua12
-rw-r--r--advtrains_luaautomation/interrupt.lua35
3 files changed, 56 insertions, 6 deletions
diff --git a/advtrains_luaautomation/README.md b/advtrains_luaautomation/README.md
index c8fb7fe..5232c22 100644
--- a/advtrains_luaautomation/README.md
+++ b/advtrains_luaautomation/README.md
@@ -20,6 +20,13 @@ Create environment with the given name. To be able to do anything, you first nee
- `/env_setup <env_name>`:
Invoke the form to edit the environment's initialization code. For more information, see the section on active components. You can also delete an environment from here.
+ - `/env_subscribe <env_name>`, `/env_unsubscribe <env_name>`:
+Subscribe or unsubscribe from log/error messages originating from this environment
+
+ - `/env_subscriptions [env_name]`:
+List your subscriptions or players subscribed to an environment.
+
+
## Functions and variables
### General Functions and Variables
The following standard Lua libraries are available:
@@ -71,11 +78,17 @@ Set the state of the passive component at position `pos`.
Checks whether there is a passive component at the position pos (and/or whether a passive component with this name exists)
- `interrupt(time, message)`
-Cause LuaAutomation to trigger an `int` event on this component after the given time in seconds with the specified `message` field. `message` can be of any Lua data type. *Not available in init code.*
+Cause LuaAutomation to trigger an `int` event on this component after the given time in seconds with the specified `message` field. `message` can be of any Lua data type. Returns true. *Not available in init code.*
+
+ - `interrupt_safe(time, message)`
+Like `interrupt()`, but does not add an interrupt and returns false when an interrupt (of any type) is already present for this component. Returns true when interrupt was successfully added.
- `interrupt_pos(pos, message)`
Immediately trigger an `ext_int` event on the active component at position pos. `message` is like in interrupt(). Use with care, or better **_don't use_**! Incorrect use can result in **_expotential growth of interrupts_**.
+ - `clear_interrupts()`
+Removes any pending interrupts of this node.
+
- `digiline_send(channel, message)`
Make this active component send a digiline message on the specified channel.
Not available in init code.
diff --git a/advtrains_luaautomation/active_common.lua b/advtrains_luaautomation/active_common.lua
index f06eb51..d168bad 100644
--- a/advtrains_luaautomation/active_common.lua
+++ b/advtrains_luaautomation/active_common.lua
@@ -122,6 +122,18 @@ function ac.run_in_env(pos, evtdata, customfct_p)
assert(t >= 0)
atlatc.interrupt.add(t, pos, {type="int", int=true, message=imesg, msg=imesg}) --Compatiblity "message" field.
end
+ customfct.interrupt_safe=function(t, imesg)
+ assertt(t, "number")
+ assert(t >= 0)
+ if atlatc.interrupt.has_at_pos(pos) then
+ return false
+ end
+ atlatc.interrupt.add(t, pos, {type="int", int=true, message=imesg, msg=imesg}) --Compatiblity "message" field.
+ return true
+ end
+ customfct.clear_interrupts=function()
+ atlatc.interrupt.clear_ints_at_pos(pos)
+ end
-- add digiline_send function, if digiline is loaded
if minetest.global_exists("digiline") then
customfct.digiline_send=function(channel, msg)
diff --git a/advtrains_luaautomation/interrupt.lua b/advtrains_luaautomation/interrupt.lua
index 525c3b4..2e54ad8 100644
--- a/advtrains_luaautomation/interrupt.lua
+++ b/advtrains_luaautomation/interrupt.lua
@@ -16,6 +16,30 @@ function iq.save()
return {queue = queue, timer=timer}
end
+function iq.has_at_pos(pos)
+ for i=1,#queue do
+ local qe=queue[i]
+ if vector.equals(pos, qe.p) then
+ return true
+ end
+ end
+ return false
+end
+
+function iq.clear_ints_at_pos(pos)
+ local i=1
+ while i<=#queue do
+ local qe=queue[i]
+ if not qe then
+ table.remove(queue, i)
+ elseif vector.equals(pos, qe.p) and (qe.e.int or qe.e.ext_int) then
+ table.remove(queue, i)
+ else
+ i=i+1
+ end
+ end
+end
+
function iq.add(t, pos, evtdata)
queue[#queue+1]={t=t+timer, p=pos, e=evtdata}
run=true
@@ -23,13 +47,14 @@ end
function iq.mainloop(dtime)
timer=timer + math.min(dtime, 0.2)
- for i=1,#queue do
+ local i=1
+ while i<=#queue do
local qe=queue[i]
if not qe then
table.remove(queue, i)
- i=i-1
elseif timer>qe.t then
- local pos, evtdata=queue[i].p, queue[i].e
+ table.remove(queue, i)
+ local pos, evtdata=qe.p, qe.e
local node=advtrains.ndb.get_node(pos)
local ndef=minetest.registered_nodes[node.name]
if ndef and ndef.luaautomation and ndef.luaautomation.fire_event then
@@ -37,8 +62,8 @@ function iq.mainloop(dtime)
else
atwarn("[atlatc][interrupt] Couldn't run event",evtdata.type,"on",pos,", something wrong with the node",node)
end
- table.remove(queue, i)
- i=i-1
+ else
+ i=i+1
end
end
end