Merge pull request #19 from Thomas--S/icta-func
Refactor ICTA to use functions instead of loadstring
This commit is contained in:
commit
2b6fcb5b9b
@ -99,9 +99,10 @@ techage.icta_register_action("print", {
|
||||
return 'print("'..data.text:sub(1,12)..'")'
|
||||
end,
|
||||
code = function(data, environ)
|
||||
local s1 = 'local text = string.gsub("'..(techage.icta_escape(data.text))..'", "*", env.result[#])'
|
||||
local s2 = 'output(env.pos, text)'
|
||||
return s1.."\n\t"..s2
|
||||
return function(env, output, idx)
|
||||
local text = string.gsub(data.text, "*", tostring(env.result[idx]))
|
||||
output(env.pos, text)
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
|
@ -16,32 +16,19 @@
|
||||
local M = minetest.get_meta
|
||||
local S = techage.S
|
||||
local logic = techage.logic
|
||||
|
||||
local function send_single_string(environ, number, topic, payload)
|
||||
payload = payload or "nil"
|
||||
local s = 'techage.send_single("%s", "%s", "%s", %s)'
|
||||
return string.format(s, environ.number, number, topic, payload)
|
||||
end
|
||||
|
||||
local function send_multi_string(environ, numbers, topic, payload)
|
||||
payload = payload or "nil"
|
||||
local s = 'techage.send_multi("%s", "%s", "%s", %s)'
|
||||
return string.format(s, environ.number, numbers, topic, payload)
|
||||
end
|
||||
|
||||
function techage.operand(s)
|
||||
if s == "is" then
|
||||
return "== "
|
||||
elseif s == "is not" then
|
||||
return "~= "
|
||||
elseif s == "greater" then
|
||||
return "> "
|
||||
elseif s == "less" then
|
||||
return "< "
|
||||
function techage.compare(op1, op2, method)
|
||||
if method == "is" then
|
||||
return op1 == op2
|
||||
elseif method == "is not" then
|
||||
return op1 ~= op2
|
||||
elseif method == "greater" then
|
||||
return op1 > op2
|
||||
elseif method == "less" then
|
||||
return op1 < op2
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function techage.fmt_number(num)
|
||||
local mtch = num:match('^(%d+).*')
|
||||
if mtch and num ~= mtch then
|
||||
@ -50,13 +37,6 @@ function techage.fmt_number(num)
|
||||
return num
|
||||
end
|
||||
|
||||
-- '#' is used as placeholder for rule numbers and has to be escaped
|
||||
function techage.icta_escape(s)
|
||||
s = tostring(s)
|
||||
s = s:gsub('"', '\\"') -- to prevent code injection!!!
|
||||
return s:gsub("#", '"..string.char(35).."')
|
||||
end
|
||||
|
||||
|
||||
techage.icta_register_condition("initial", {
|
||||
title = "initial",
|
||||
@ -69,8 +49,14 @@ techage.icta_register_condition("initial", {
|
||||
},
|
||||
-- Return two chunks of executable Lua code for the controller, according:
|
||||
-- return <read condition>, <expected result>
|
||||
code = function(data, environ)
|
||||
return 'env.ticks', '== 1'
|
||||
code = function(data, environ)
|
||||
local condition = function(env, idx)
|
||||
return env.ticks
|
||||
end
|
||||
local result = function(val)
|
||||
return val == 1
|
||||
end
|
||||
return condition, result
|
||||
end,
|
||||
button = function(data, environ) return "Initial after start" end,
|
||||
})
|
||||
@ -84,8 +70,14 @@ techage.icta_register_condition("true", {
|
||||
label = "Condition is always true.",
|
||||
},
|
||||
},
|
||||
code = function(data, environ)
|
||||
return '"true"', '== "true"'
|
||||
code = function(data, environ)
|
||||
local condition = function(env, idx)
|
||||
return true
|
||||
end
|
||||
local result = function(val)
|
||||
return val == true
|
||||
end
|
||||
return condition, result
|
||||
end,
|
||||
button = function(data, environ) return "true" end,
|
||||
})
|
||||
@ -113,13 +105,15 @@ techage.icta_register_condition("condition", {
|
||||
label = "Used to execute two or more\nactions based on one condition.",
|
||||
},
|
||||
},
|
||||
code = function(data, environ)
|
||||
local idx = data.condition:byte(-1) - 0x30
|
||||
local expected_result = "== false"
|
||||
if data.operand == "was true" then
|
||||
expected_result = "== true"
|
||||
code = function(data, environ)
|
||||
local condition = function(env, idx)
|
||||
local index = data.condition:byte(-1) - 0x30
|
||||
return env.condition[index]
|
||||
end
|
||||
return "env.condition["..idx.."]", expected_result
|
||||
local result = function(val)
|
||||
return val == (data.operand == "was true")
|
||||
end
|
||||
return condition, result
|
||||
end,
|
||||
button = function(data, environ) return "cond("..data.condition:sub(-1,-1)..","..data.operand..")" end,
|
||||
})
|
||||
@ -154,9 +148,14 @@ techage.icta_register_condition("input", {
|
||||
button = function(data, environ) -- default button label
|
||||
return 'inp('..techage.fmt_number(data.number)..','..data.operand.." "..data.value..')'
|
||||
end,
|
||||
code = function(data, environ)
|
||||
return 'env.input["'..data.number..'"]',
|
||||
techage.operand(data.operand)..'"'..data.value..'"'
|
||||
code = function(data, environ)
|
||||
local condition = function(env, idx)
|
||||
return env.input[data.number]
|
||||
end
|
||||
local result = function(val)
|
||||
return techage.compare(val, data.value, data.operand)
|
||||
end
|
||||
return condition, result
|
||||
end,
|
||||
})
|
||||
|
||||
@ -192,9 +191,14 @@ techage.icta_register_condition("state", {
|
||||
button = function(data, environ) -- default button label
|
||||
return 'sts('..techage.fmt_number(data.number)..","..data.operand..' '..data.value..')'
|
||||
end,
|
||||
code = function(data, environ)
|
||||
return send_single_string(environ, data.number, "state"),
|
||||
techage.operand(data.operand)..'"'..data.value..'"'
|
||||
code = function(data, environ)
|
||||
local condition = function(env, idx)
|
||||
return techage.send_single(environ.number, data.number, "state")
|
||||
end
|
||||
local result = function(val)
|
||||
return techage.compare(val, data.value, data.operand)
|
||||
end
|
||||
return condition, result
|
||||
end,
|
||||
})
|
||||
|
||||
@ -229,9 +233,14 @@ techage.icta_register_condition("fuel", {
|
||||
button = function(data, environ)
|
||||
return 'fuel('..techage.fmt_number(data.number)..","..data.operand..' '..data.value..')'
|
||||
end,
|
||||
code = function(data, environ)
|
||||
return send_single_string(environ, data.number, "fuel"),
|
||||
techage.operand(data.operand)..tonumber(data.value)
|
||||
code = function(data, environ)
|
||||
local condition = function(env, idx)
|
||||
return techage.send_single(environ.number, data.number, "fuel")
|
||||
end
|
||||
local result = function(val)
|
||||
return techage.compare(val, tonumber(data.value), data.operand)
|
||||
end
|
||||
return condition, result
|
||||
end,
|
||||
})
|
||||
|
||||
@ -266,9 +275,14 @@ techage.icta_register_condition("load", {
|
||||
button = function(data, environ)
|
||||
return 'load('..techage.fmt_number(data.number)..","..data.operand..' '..data.value..')'
|
||||
end,
|
||||
code = function(data, environ)
|
||||
return send_single_string(environ, data.number, "load"),
|
||||
techage.operand(data.operand)..tonumber(data.value)
|
||||
code = function(data, environ)
|
||||
local condition = function(env, idx)
|
||||
return techage.send_single(environ.number, data.number, "load")
|
||||
end
|
||||
local result = function(val)
|
||||
return techage.compare(val, tonumber(data.value), data.operand)
|
||||
end
|
||||
return condition, result
|
||||
end,
|
||||
})
|
||||
|
||||
@ -303,9 +317,14 @@ techage.icta_register_condition("depth", {
|
||||
button = function(data, environ)
|
||||
return 'depth('..techage.fmt_number(data.number)..","..data.operand..' '..data.value..')'
|
||||
end,
|
||||
code = function(data, environ)
|
||||
return send_single_string(environ, data.number, "depth"),
|
||||
techage.operand(data.operand)..tonumber(data.value)
|
||||
code = function(data, environ)
|
||||
local condition = function(env, idx)
|
||||
return techage.send_single(environ.number, data.number, "depth")
|
||||
end
|
||||
local result = function(val)
|
||||
return techage.compare(val, tonumber(data.value), data.operand)
|
||||
end
|
||||
return condition, result
|
||||
end,
|
||||
})
|
||||
|
||||
@ -340,9 +359,14 @@ techage.icta_register_condition("delivered", {
|
||||
button = function(data, environ)
|
||||
return 'deliv('..techage.fmt_number(data.number)..","..data.operand..' '..data.value..')'
|
||||
end,
|
||||
code = function(data, environ)
|
||||
return send_single_string(environ, data.number, "delivered"),
|
||||
techage.operand(data.operand)..tonumber(data.value)
|
||||
code = function(data, environ)
|
||||
local condition = function(env, idx)
|
||||
return techage.send_single(environ.number, data.number, "delivered")
|
||||
end
|
||||
local result = function(val)
|
||||
return techage.compare(val, tonumber(data.value), data.operand)
|
||||
end
|
||||
return condition, result
|
||||
end,
|
||||
})
|
||||
|
||||
@ -379,9 +403,14 @@ techage.icta_register_condition("chest", {
|
||||
button = function(data, environ) -- default button label
|
||||
return 'chest('..techage.fmt_number(data.number)..","..data.operand..' '..data.value..')'
|
||||
end,
|
||||
code = function(data, environ)
|
||||
return send_single_string(environ, data.number, "state"),
|
||||
techage.operand(data.operand)..'"'..data.value..'"'
|
||||
code = function(data, environ)
|
||||
local condition = function(env, idx)
|
||||
return techage.send_single(environ.number, data.number, "state")
|
||||
end
|
||||
local result = function(val)
|
||||
return techage.compare(val, data.value, data.operand)
|
||||
end
|
||||
return condition, result
|
||||
end,
|
||||
})
|
||||
|
||||
@ -415,9 +444,14 @@ techage.icta_register_condition("signaltower", {
|
||||
button = function(data, environ) -- default button label
|
||||
return 'tower('..techage.fmt_number(data.number)..","..data.operand..' '..data.value..')'
|
||||
end,
|
||||
code = function(data, environ)
|
||||
return send_single_string(environ, data.number, "state"),
|
||||
techage.operand(data.operand)..'"'..data.value..'"'
|
||||
code = function(data, environ)
|
||||
local condition = function(env, idx)
|
||||
return techage.send_single(environ.number, data.number, "state")
|
||||
end
|
||||
local result = function(val)
|
||||
return techage.compare(val, data.value, data.operand)
|
||||
end
|
||||
return condition, result
|
||||
end,
|
||||
})
|
||||
|
||||
@ -447,7 +481,9 @@ techage.icta_register_action("signaltower", {
|
||||
return 'tower('..techage.fmt_number(data.number)..","..data.value..')'
|
||||
end,
|
||||
code = function(data, environ)
|
||||
return send_multi_string(environ, data.number, data.value)
|
||||
return function(env, output, idx)
|
||||
techage.send_multi(environ.number, data.number, data.value)
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
@ -477,7 +513,9 @@ techage.icta_register_action("switch", {
|
||||
return 'turn('..techage.fmt_number(data.number)..","..data.value..')'
|
||||
end,
|
||||
code = function(data, environ)
|
||||
return send_multi_string(environ, data.number, data.value)
|
||||
return function(env, output, idx)
|
||||
techage.send_multi(environ.number, data.number, data.value)
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
@ -509,11 +547,14 @@ techage.icta_register_action("display", {
|
||||
label = "Use a '*' character as reference\nto any condition result",
|
||||
},
|
||||
},
|
||||
code = function(data, environ)
|
||||
local s1 = string.format('local text = string.gsub("%s", "*", tostring(env.result[#]))', techage.icta_escape(data.text))
|
||||
local s2 = string.format('local payload = {row = %s, str = text}', data.row)
|
||||
local s3 = send_multi_string(environ, data.number, "set", "payload")
|
||||
return s1.."\n\t"..s2.."\n\t"..s3
|
||||
code = function(data, environ)
|
||||
return function(env, output, idx)
|
||||
local text = string.gsub(data.text, "*", tostring(env.result[idx]))
|
||||
local payload = safer_lua.Store()
|
||||
payload.set("row", data.row)
|
||||
payload.set("str", text)
|
||||
techage.send_multi(environ.number, data.number, "set", payload)
|
||||
end
|
||||
end,
|
||||
button = function(data, environ)
|
||||
return "lcd("..techage.fmt_number(data.number)..","..data.row..',"'..data.text..'")'
|
||||
@ -530,8 +571,10 @@ techage.icta_register_action("cleardisplay", {
|
||||
default = "",
|
||||
},
|
||||
},
|
||||
code = function(data, environ)
|
||||
return send_multi_string(environ, data.number, "clear")
|
||||
code = function(data, environ)
|
||||
return function(env, output, idx)
|
||||
techage.send_multi(environ.number, data.number, "clear")
|
||||
end
|
||||
end,
|
||||
button = function(data, environ)
|
||||
return "clear lcd("..techage.fmt_number(data.number)..")"
|
||||
@ -553,8 +596,10 @@ techage.icta_register_action("chat", {
|
||||
label = "The chat message is send to the\nController owner, only.",
|
||||
},
|
||||
},
|
||||
code = function(data, environ)
|
||||
return 'minetest.chat_send_player("'..environ.owner..'", "[TA4 ICTA Controller] '..techage.icta_escape(data.text)..' ")'
|
||||
code = function(data, environ)
|
||||
return function(env, output, idx)
|
||||
minetest.chat_send_player(environ.owner, "[TA4 ICTA Controller] "..data.text)
|
||||
end
|
||||
end,
|
||||
button = function(data, environ)
|
||||
return 'chat("'..data.text:sub(1,12)..'")'
|
||||
@ -602,8 +647,10 @@ techage.icta_register_action("door", {
|
||||
"Use the Techage Info Tool to\neasily determine a door position.",
|
||||
},
|
||||
},
|
||||
code = function(data, environ)
|
||||
return 'techage.icta_door_toggle("'..data.pos..'", "'..environ.owner..'", "'..data.door_state..'")'
|
||||
code = function(data, environ)
|
||||
return function(env, output, idx)
|
||||
techage.icta_door_toggle(data.pos, environ.owner, data.door_state)
|
||||
end
|
||||
end,
|
||||
button = function(data, environ)
|
||||
return 'door("'..data.pos..'",'..data.door_state..")"
|
||||
@ -644,8 +691,14 @@ techage.icta_register_condition("playerdetector", {
|
||||
},
|
||||
},
|
||||
|
||||
code = function(data, environ)
|
||||
return 'techage.icta_player_detect("'..environ.number..'", "'..data.number..'", "'..techage.icta_escape(data.name)..'")', "~= nil"
|
||||
code = function(data, environ)
|
||||
local condition = function(env, idx)
|
||||
return techage.icta_player_detect(environ.number, data.number, data.name)
|
||||
end
|
||||
local result = function(val)
|
||||
return val ~= nil
|
||||
end
|
||||
return condition, result
|
||||
end,
|
||||
button = function(data, environ)
|
||||
return "detector("..techage.fmt_number(data.number)..","..data.name:sub(1,8)..")"
|
||||
@ -685,7 +738,9 @@ techage.icta_register_action("set_filter", {
|
||||
return 'turn('..techage.fmt_number(data.number)..","..data.color..","..data.value..')'
|
||||
end,
|
||||
code = function(data, environ)
|
||||
local payload = '{slot = "'..data.color..'", val = "'..data.value..'"}'
|
||||
return send_single_string(environ, data.number, "filter", payload)
|
||||
return function(env, output, idx)
|
||||
local payload = data.color.."="..data.value
|
||||
techage.send_single(environ.number, data.number, "port", payload)
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
@ -71,7 +71,15 @@ end
|
||||
techage.icta_register_condition("default", {
|
||||
title = "",
|
||||
formspec = {},
|
||||
code = function(data, environ) return false, false end,
|
||||
code = function(data, environ)
|
||||
local condition = function(env, idx)
|
||||
return false
|
||||
end
|
||||
local result = function(val)
|
||||
return false
|
||||
end
|
||||
return condition, result
|
||||
end,
|
||||
button = function(data, environ) return "..." end,
|
||||
})
|
||||
|
||||
|
@ -57,100 +57,51 @@ local function output(pos, text, flush_buffer)
|
||||
meta:set_string("formspec", techage.formspecOutput(meta))
|
||||
end
|
||||
|
||||
----------------- template -------------------------------
|
||||
-- -- Rule 1
|
||||
-- if env.blocked[1] == false and env.ticks % <cycle> == 0 then
|
||||
-- env.result[1] = <check condition>
|
||||
-- env.blocked[1] = env.result[1] <expected result>
|
||||
-- if env.blocked[1] then
|
||||
-- env.timer[1] = env.ticks + <after>
|
||||
-- end
|
||||
-- env.conditions[1] = env.blocked[1]
|
||||
-- else
|
||||
-- env.conditions[1] = false
|
||||
-- end
|
||||
-- if env.blocked[1] and env.timer[1] == env.ticks then
|
||||
-- <action>
|
||||
-- env.blocked[1] = false
|
||||
-- end
|
||||
|
||||
-- -- Callback variant
|
||||
-- if env.blocked[1] == false and env.ticks % <cycle> == 0 then
|
||||
-- env.result[1], env.blocked[1] = <callback>
|
||||
-- if env.blocked[1] then
|
||||
-- env.timer[1] = env.ticks + <after>
|
||||
-- end
|
||||
-- env.conditions[1] = env.blocked[1]
|
||||
-- else
|
||||
-- env.conditions[1] = false
|
||||
-- end
|
||||
-- if env.blocked[1] and env.timer[1] == env.ticks then
|
||||
-- <action>
|
||||
-- env.blocked[1] = false
|
||||
-- end
|
||||
|
||||
|
||||
-- cyclic execution (cycle, cond, result, after, actn)
|
||||
local TemplCyc = [[
|
||||
-- Rule #
|
||||
if env.blocked[#] == false and env.ticks %% %s == 0 then
|
||||
env.result[#] = %s
|
||||
env.blocked[#] = env.result[#] %s
|
||||
if env.blocked[#] then
|
||||
env.timer[#] = env.ticks + %s
|
||||
local function TemplCyc(cycle, cond, result, after, actn, idx)
|
||||
return function(env, output)
|
||||
if env.blocked[idx] == false and env.ticks % cycle == 0 then
|
||||
env.result[idx] = cond(env, idx)
|
||||
env.blocked[idx] = result(env.result[idx])
|
||||
if env.blocked[idx] then
|
||||
env.timer[idx] = env.ticks + after
|
||||
end
|
||||
env.condition[idx] = env.blocked[idx]
|
||||
else
|
||||
env.condition[idx] = false
|
||||
end
|
||||
if env.blocked[idx] and env.timer[idx] == env.ticks then
|
||||
actn(env, output, idx)
|
||||
env.blocked[idx] = false
|
||||
end
|
||||
end
|
||||
env.condition[#] = env.blocked[#]
|
||||
else
|
||||
env.condition[#] = false
|
||||
end
|
||||
if env.blocked[#] and env.timer[#] == env.ticks then
|
||||
%s
|
||||
env.blocked[#] = false
|
||||
end
|
||||
]]
|
||||
|
||||
-- event based execution
|
||||
local TemplEvt = [[
|
||||
-- Rule #
|
||||
if env.blocked[#] == false and env.event then
|
||||
env.result[#] = %s
|
||||
env.blocked[#] = env.result[#] %s
|
||||
if env.blocked[#] then
|
||||
env.timer[#] = env.ticks + %s
|
||||
local function TemplEvt(cond, result, after, actn, idx)
|
||||
return function(env, output)
|
||||
if env.blocked[idx] == false and env.event then
|
||||
env.result[idx] = cond(env, idx)
|
||||
env.blocked[idx] = result(env.result[idx])
|
||||
if env.blocked[idx] then
|
||||
env.timer[idx] = env.ticks + after
|
||||
end
|
||||
env.condition[idx] = env.blocked[idx]
|
||||
else
|
||||
env.condition[idx] = false
|
||||
end
|
||||
if env.blocked[idx] and env.timer[idx] == env.ticks then
|
||||
actn(env, output, idx)
|
||||
env.blocked[idx] = false
|
||||
end
|
||||
end
|
||||
env.condition[#] = env.blocked[#]
|
||||
else
|
||||
env.condition[#] = false
|
||||
end
|
||||
if env.blocked[#] and env.timer[#] == env.ticks then
|
||||
%s
|
||||
env.blocked[#] = false
|
||||
end
|
||||
]]
|
||||
|
||||
-- event based execution of callback function
|
||||
local TemplEvtClbk = [[
|
||||
-- Rule #
|
||||
if env.blocked[#] == false and env.event then
|
||||
env.result[#], env.blocked[#] = %s(env, %s)
|
||||
if env.blocked[#] then
|
||||
env.timer[#] = env.ticks + %s
|
||||
end
|
||||
env.condition[#] = env.blocked[#]
|
||||
else
|
||||
env.condition[#] = false
|
||||
end
|
||||
if env.blocked[#] and env.timer[#] == env.ticks then
|
||||
%s
|
||||
env.blocked[#] = false
|
||||
end
|
||||
]]
|
||||
|
||||
-- generate the Lua code from the NUM_RULES rules
|
||||
local function generate(pos, meta, environ)
|
||||
local fs_data = minetest.deserialize(meta:get_string("fs_data")) or FS_DATA
|
||||
-- chunks are compiled as vararg functions. Parameters are available via: local a, b, c = ...
|
||||
local tbl = {"local env, output = ...\n"}
|
||||
local tbl = {}
|
||||
for idx = 1,techage.NUM_RULES do
|
||||
local cycle = integer(fs_data[idx].cycle, 0, 1000)
|
||||
local cond, result = techage.code_condition(fs_data[idx].cond, environ)
|
||||
@ -159,26 +110,21 @@ local function generate(pos, meta, environ)
|
||||
-- valid rule?
|
||||
if cycle and cond and after and actn then
|
||||
-- add rule number
|
||||
local s
|
||||
if cycle == 0 then -- event?
|
||||
if result then
|
||||
s = string.format(TemplEvt, cond, result, after, actn)
|
||||
else -- callback function
|
||||
local data = dump(fs_data[idx].cond)
|
||||
s = string.format(TemplEvtClbk, cond, data, after, actn)
|
||||
end
|
||||
local f
|
||||
if cycle == 0 then -- event
|
||||
f = TemplEvt(cond, result, after, actn, idx)
|
||||
else -- cyclic
|
||||
s = string.format(TemplCyc, cycle, cond, result, after, actn)
|
||||
f = TemplCyc(cycle, cond, result, after, actn, idx)
|
||||
end
|
||||
-- add to list of rules
|
||||
tbl[#tbl+1] = s:gsub("#", idx)
|
||||
tbl[#tbl+1] = f
|
||||
elseif cond ~= nil and actn == nil then
|
||||
output(pos, "Error in action in rule "..idx)
|
||||
elseif cond == nil and actn ~= nil then
|
||||
output(pos, "Error in condition in rule "..idx)
|
||||
end
|
||||
end
|
||||
return table.concat(tbl)
|
||||
return tbl
|
||||
end
|
||||
|
||||
local function runtime_environ(pos)
|
||||
@ -200,21 +146,12 @@ local function compile(pos, meta, number)
|
||||
number = number,
|
||||
owner = meta:get_string("owner"),
|
||||
}
|
||||
local text = generate(pos, meta, gen_environ)
|
||||
if text then
|
||||
local code, err = loadstring(text)
|
||||
if code then
|
||||
Cache[number] = {
|
||||
code = code,
|
||||
env = runtime_environ(pos),
|
||||
}
|
||||
return true
|
||||
else
|
||||
output(pos, err)
|
||||
return false
|
||||
end
|
||||
end
|
||||
return false
|
||||
local functions = generate(pos, meta, gen_environ)
|
||||
Cache[number] = {
|
||||
code = functions,
|
||||
env = runtime_environ(pos),
|
||||
}
|
||||
return true
|
||||
end
|
||||
|
||||
local function execute(pos, number, event)
|
||||
@ -226,10 +163,12 @@ local function execute(pos, number, event)
|
||||
env.event = false
|
||||
env.ticks = env.ticks + 1
|
||||
end
|
||||
local res, err = pcall(code, env, output)
|
||||
if not res then
|
||||
output(pos, err)
|
||||
return false
|
||||
for _,func in ipairs(code) do
|
||||
local res, err = pcall(func, env, output)
|
||||
if not res then
|
||||
output(pos, err)
|
||||
return false
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
@ -211,8 +211,8 @@ local function write_row(pos, payload, cycle_time)
|
||||
local mem = techage.get_mem(pos)
|
||||
nvm.text = nvm.text or {}
|
||||
mem.ticks = mem.ticks or 0
|
||||
local str = tostring(payload.str) or "oops"
|
||||
local row = tonumber(payload.row) or 1
|
||||
local str = tostring(payload.get("str")) or "oops"
|
||||
local row = tonumber(payload.get("row")) or 1
|
||||
|
||||
if mem.ticks == 0 then
|
||||
mem.ticks = cycle_time
|
||||
|
@ -39,16 +39,17 @@ techage.lua_ctlr.register_function("get_input", {
|
||||
})
|
||||
|
||||
techage.lua_ctlr.register_function("read_data", {
|
||||
cmnd = function(self, num, ident, add_data)
|
||||
cmnd = function(self, num, cmnd, data)
|
||||
num = tostring(num or "")
|
||||
return techage.send_single(self.meta.number, num, ident, add_data)
|
||||
cmnd = tostring(cmnd or "")
|
||||
if not_protected(self.meta.owner, num) then
|
||||
return techage.send_single(self.meta.number, num, cmnd, data)
|
||||
end
|
||||
end,
|
||||
help = " $read_data(num, ident, add_data)\n"..
|
||||
" Read any kind of data from another block.\n"..
|
||||
' "num" is the block number\n'..
|
||||
' "ident" specifies the data to be read\n'..
|
||||
' "add_data" is additional data (optional)\n'..
|
||||
' example: sts = $read_data("1234", "state")'
|
||||
help = " $read_data(num, cmnd, add_data)\n"..
|
||||
" This function is deprecated.\n"..
|
||||
" It will be removed in future releases.\n"..
|
||||
" Use $send_cmnd(num, cmnd, add_data) instead."
|
||||
})
|
||||
|
||||
techage.lua_ctlr.register_function("time_as_str", {
|
||||
|
Loading…
Reference in New Issue
Block a user