forked from minetest-mods/mesecons
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.
This commit is contained in:
parent
a59f53d71a
commit
5002315ec9
@ -2,7 +2,7 @@
|
|||||||
-- ports = get_real_portstates(pos): gets if inputs are powered from outside
|
-- 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
|
-- 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_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
|
-- 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_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
|
-- reset (pos): performs a hardware reset, turns off all ports
|
||||||
@ -99,7 +99,7 @@ local setport = function (pos, rule, state)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local action = function (pos, ports)
|
local action = function (pos, ports, digiline_msgs)
|
||||||
local node = minetest.get_node(pos)
|
local node = minetest.get_node(pos)
|
||||||
local name = node.name
|
local name = node.name
|
||||||
local vports = minetest.registered_nodes[name].virtual_portstates
|
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.c ~= vports.c then setport(pos, rules.c, ports.c) end
|
||||||
if ports.d ~= vports.d then setport(pos, rules.d, ports.d) end
|
if ports.d ~= vports.d then setport(pos, rules.d, ports.d) end
|
||||||
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
|
end
|
||||||
|
|
||||||
--------------------
|
--------------------
|
||||||
@ -219,15 +226,6 @@ local getinterrupt = function(pos)
|
|||||||
return interrupt
|
return interrupt
|
||||||
end
|
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)
|
local create_environment = function(pos, mem, event)
|
||||||
-- Gather variables for the environment
|
-- Gather variables for the environment
|
||||||
local vports = minetest.registered_nodes[minetest.get_node(pos).name].virtual_portstates
|
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),
|
pin = merge_portstates(vports, rports),
|
||||||
port = vports,
|
port = vports,
|
||||||
interrupt = getinterrupt(pos),
|
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,
|
mem = mem,
|
||||||
tostring = tostring,
|
tostring = tostring,
|
||||||
tonumber = tonumber,
|
tonumber = tonumber,
|
||||||
@ -356,6 +357,7 @@ end
|
|||||||
-- Parsing function --
|
-- Parsing function --
|
||||||
----------------------
|
----------------------
|
||||||
|
|
||||||
|
lc_digiline_msgs = nil
|
||||||
lc_update = function (pos, event)
|
lc_update = function (pos, event)
|
||||||
local meta = minetest.get_meta(pos)
|
local meta = minetest.get_meta(pos)
|
||||||
if not interrupt_allow(meta, event) then return end
|
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)
|
local env = create_environment(pos, mem, event)
|
||||||
|
|
||||||
-- create the sandbox and execute code
|
-- create the sandbox and execute code
|
||||||
|
lc_digiline_msgs = {}
|
||||||
local chunk, msg = create_sandbox (code, env)
|
local chunk, msg = create_sandbox (code, env)
|
||||||
if not chunk then return msg end
|
if not chunk then return msg end
|
||||||
local success, msg = pcall(f)
|
local success, msg = pcall(f)
|
||||||
@ -379,8 +382,8 @@ lc_update = function (pos, event)
|
|||||||
|
|
||||||
save_memory(meta, mem)
|
save_memory(meta, mem)
|
||||||
|
|
||||||
-- Actually set the ports
|
-- Actually set the ports and send digiline messages
|
||||||
minetest.after(0, action, pos, env.port)
|
minetest.after(0, action, pos, env.port, lc_digiline_msgs)
|
||||||
end
|
end
|
||||||
|
|
||||||
local reset_meta = function(pos, code, errmsg)
|
local reset_meta = function(pos, code, errmsg)
|
||||||
@ -399,7 +402,7 @@ end
|
|||||||
|
|
||||||
local reset = function (pos)
|
local reset = function (pos)
|
||||||
minetest.get_meta(pos):set_string("lc_interrupts", "")
|
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
|
end
|
||||||
|
|
||||||
-- ______
|
-- ______
|
||||||
|
Loading…
Reference in New Issue
Block a user