summaryrefslogtreecommitdiff
path: root/mesecons_luacontroller
diff options
context:
space:
mode:
authorCiaran Gultnieks <ciaran@ciarang.com>2014-03-11 17:34:30 +0000
committerCiaran Gultnieks <ciaran@ciarang.com>2014-03-11 17:34:30 +0000
commit5002315ec91d614e5862e207b98a008f1cd8913c (patch)
tree4073f6a25e36fc86a97f95f65192a221a29bf3bc /mesecons_luacontroller
parenta59f53d71aa580e03adce238158d7852866f922c (diff)
downloadmesecons-5002315ec91d614e5862e207b98a008f1cd8913c.tar
mesecons-5002315ec91d614e5862e207b98a008f1cd8913c.tar.gz
mesecons-5002315ec91d614e5862e207b98a008f1cd8913c.tar.bz2
mesecons-5002315ec91d614e5862e207b98a008f1cd8913c.tar.xz
mesecons-5002315ec91d614e5862e207b98a008f1cd8913c.zip
Send digiline messages after luacontroller execution
In the same way as for port settings, this queues up digiline messages sent during the luacontroller's execution, and sends them afterwards. This solves many problems, but one example: 1. Send a message, and receive a reply from another device. 2. While handling the reply event (effectively a nested invocation on the same luacontroller) make a change to memory 3. Notice that the memory change has no effect, because after completion of the reply handling, it stores the memory, but then the original invocation completes and overwrites it with it's own earlier copy of the same memory.
Diffstat (limited to 'mesecons_luacontroller')
-rw-r--r--mesecons_luacontroller/init.lua33
1 files changed, 18 insertions, 15 deletions
diff --git a/mesecons_luacontroller/init.lua b/mesecons_luacontroller/init.lua
index 263a66a..6bc1431 100644
--- a/mesecons_luacontroller/init.lua
+++ b/mesecons_luacontroller/init.lua
@@ -2,7 +2,7 @@
-- ports = get_real_portstates(pos): gets if inputs are powered from outside
-- newport = merge_portstates(state1, state2): just does result = state1 or state2 for every port
-- action_setports(pos, rule, state): activates/deactivates the mesecons according to the portstates (helper for action)
--- action(pos, ports): Applies new portstates to a luacontroller at pos
+-- action(pos, ports, digiline_msgs): Applies new portstates to a luacontroller at pos, and sends pending digiline messages
-- lc_update(pos): updates the controller at pos by executing the code
-- reset_meta (pos, code, errmsg): performs a software-reset, installs new code and prints error messages
-- reset (pos): performs a hardware reset, turns off all ports
@@ -99,7 +99,7 @@ local setport = function (pos, rule, state)
end
end
-local action = function (pos, ports)
+local action = function (pos, ports, digiline_msgs)
local node = minetest.get_node(pos)
local name = node.name
local vports = minetest.registered_nodes[name].virtual_portstates
@@ -116,6 +116,13 @@ local action = function (pos, ports)
if ports.c ~= vports.c then setport(pos, rules.c, ports.c) end
if ports.d ~= vports.d then setport(pos, rules.d, ports.d) end
end
+
+ if digiline then
+ for i = 1, #digiline_msgs do
+ digiline:receptor_send(pos, digiline.rules.default,
+ digiline_msgs[i].channel, digiline_msgs[i].msg)
+ end
+ end
end
--------------------
@@ -219,15 +226,6 @@ local getinterrupt = function(pos)
return interrupt
end
-local getdigiline_send = function (pos)
- local digiline_send = function (channel, msg)
- if digiline then
- digiline:receptor_send(pos, digiline.rules.default, channel, msg)
- end
- end
- return digiline_send
-end
-
local create_environment = function(pos, mem, event)
-- Gather variables for the environment
local vports = minetest.registered_nodes[minetest.get_node(pos).name].virtual_portstates
@@ -239,7 +237,10 @@ local create_environment = function(pos, mem, event)
pin = merge_portstates(vports, rports),
port = vports,
interrupt = getinterrupt(pos),
- digiline_send = getdigiline_send(pos),
+ digiline_msgs = {},
+ digiline_send = function(channel, msg)
+ table.insert(lc_digiline_msgs, {["channel"]=channel, ["msg"]=msg})
+ end,
mem = mem,
tostring = tostring,
tonumber = tonumber,
@@ -356,6 +357,7 @@ end
-- Parsing function --
----------------------
+lc_digiline_msgs = nil
lc_update = function (pos, event)
local meta = minetest.get_meta(pos)
if not interrupt_allow(meta, event) then return end
@@ -371,6 +373,7 @@ lc_update = function (pos, event)
local env = create_environment(pos, mem, event)
-- create the sandbox and execute code
+ lc_digiline_msgs = {}
local chunk, msg = create_sandbox (code, env)
if not chunk then return msg end
local success, msg = pcall(f)
@@ -379,8 +382,8 @@ lc_update = function (pos, event)
save_memory(meta, mem)
- -- Actually set the ports
- minetest.after(0, action, pos, env.port)
+ -- Actually set the ports and send digiline messages
+ minetest.after(0, action, pos, env.port, lc_digiline_msgs)
end
local reset_meta = function(pos, code, errmsg)
@@ -399,7 +402,7 @@ end
local reset = function (pos)
minetest.get_meta(pos):set_string("lc_interrupts", "")
- action(pos, {a=false, b=false, c=false, d=false}, true)
+ action(pos, {a=false, b=false, c=false, d=false}, {})
end
-- ______