aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--advtrains/advtrains_luaautomation/active_common.lua7
-rw-r--r--advtrains/advtrains_luaautomation/atc_rail.lua2
-rw-r--r--advtrains/advtrains_luaautomation/chatcmds.lua70
-rw-r--r--advtrains/advtrains_luaautomation/environment.lua42
-rw-r--r--advtrains/advtrains_luaautomation/init.lua2
-rw-r--r--advtrains/advtrains_luaautomation/passive.lua8
6 files changed, 125 insertions, 6 deletions
diff --git a/advtrains/advtrains_luaautomation/active_common.lua b/advtrains/advtrains_luaautomation/active_common.lua
index b94a260..474838e 100644
--- a/advtrains/advtrains_luaautomation/active_common.lua
+++ b/advtrains/advtrains_luaautomation/active_common.lua
@@ -84,7 +84,7 @@ function ac.on_receive_fields(pos, formname, fields, player)
end
end
-function ac.run_in_env(pos, evtdata, customfct)
+function ac.run_in_env(pos, evtdata, customfct_p)
local ph=minetest.hash_node_position(pos)
local nodetbl = ac.nodes[ph] or {}
@@ -100,6 +100,11 @@ function ac.run_in_env(pos, evtdata, customfct)
return false, "No code to run!"
end
+ local customfct=customfct_p or {}
+ customfct.interrupt=function(t, imesg)
+ atlatc.interrupt.add(t, pos, {type="int", int=true, message=imesg})
+ end
+
local datain=nodetbl.data or {}
local succ, dataout = atlatc.envs[nodetbl.env]:execute_code(datain, nodetbl.code, evtdata, customfct)
if succ then
diff --git a/advtrains/advtrains_luaautomation/atc_rail.lua b/advtrains/advtrains_luaautomation/atc_rail.lua
index 2af03cf..b2a8aad 100644
--- a/advtrains/advtrains_luaautomation/atc_rail.lua
+++ b/advtrains/advtrains_luaautomation/atc_rail.lua
@@ -78,7 +78,7 @@ advtrains.register_tracks("default", {
advtrains = {
on_train_enter = function(pos, train_id)
--do async. Event is fired in train steps
- atlatc.interrupt.add(0, pos, {type="train", id=train_id})
+ atlatc.interrupt.add(0, pos, {type="train", train=true, id=train_id})
end,
},
luaautomation = {
diff --git a/advtrains/advtrains_luaautomation/chatcmds.lua b/advtrains/advtrains_luaautomation/chatcmds.lua
index e69de29..1a3f167 100644
--- a/advtrains/advtrains_luaautomation/chatcmds.lua
+++ b/advtrains/advtrains_luaautomation/chatcmds.lua
@@ -0,0 +1,70 @@
+--chatcmds.lua
+--Registers commands to modify the init and step code for LuaAutomation
+
+local function get_init_form(env)
+ local err = env.init_err or ""
+ local code = env.init_code or ""
+ atprint(err)
+ local form = "size[10,10]button[0,0;2,1;run;Run InitCode]button[2,0;2,1;cls;Clear S]"
+ .."button[4,0;2,1;save;Save] button[6,0;2,1;del;Delete Env.] textarea[0.2,1;10,10;code;Environment initialization code;"..minetest.formspec_escape(code).."]"
+ .."label[0,9.8;"..err.."]"
+ return form
+end
+
+core.register_chatcommand("env_setup", {
+ params = "<environment name>",
+ description = "Set up and modify AdvTrains LuaAutomation environment",
+ privs = {atlatc=true},
+ func = function(name, param)
+ local env=atlatc.envs[param]
+ if not env then return false,"Invalid environment name!" end
+ minetest.show_formspec(name, "atlatc_envsetup_"..param, get_init_form(env))
+ return true
+ end,
+})
+
+core.register_chatcommand("env_create", {
+ params = "<environment name>",
+ description = "Create an AdvTrains LuaAutomation environment",
+ privs = {atlatc=true},
+ func = function(name, param)
+ if not param or param=="" then return false, "Name required!" end
+ if atlatc.envs[param] then return false, "Environment already exists!" end
+ atlatc.envs[param] = atlatc.env_new(param)
+ return true, "Created environment '"..param.."'. Use '/env_setup "..param.."' to define global initialization code, or start building LuaATC components!"
+ end,
+})
+
+
+minetest.register_on_player_receive_fields(function(player, formname, fields)
+
+ local pname=player:get_player_name()
+ if not minetest.check_player_privs(pname, {atlatc=true}) then return end
+
+ local envname=string.match(formname, "^atlatc_delconfirm_(.+)$")
+ if envname and fields.sure=="YES" then
+ atlatc.envs[envname]=nil
+ minetest.chat_send_player(pname, "Environment deleted!")
+ return
+ end
+
+ envname=string.match(formname, "^atlatc_envsetup_(.+)$")
+ if not envname then return end
+
+ local env=atlatc.envs[envname]
+ if not env then return end
+
+ if fields.del then
+ minetest.show_formspec(pname, "atlatc_delconfirm_"..envname, "field[sure;"..minetest.formspec_escape("SURE TO DELETE ENVIRONMENT "..envname.."? Type YES (all uppercase) to continue or just quit form to cancel.")..";]")
+ return
+ end
+
+ env.init_err=nil
+ if fields.code then
+ env.init_code=fields.code
+ end
+ if fields.run then
+ env:run_initcode()
+ minetest.show_formspec(pname, formname, get_init_form(env))
+ end
+end)
diff --git a/advtrains/advtrains_luaautomation/environment.lua b/advtrains/advtrains_luaautomation/environment.lua
index d04563a..c7b801c 100644
--- a/advtrains/advtrains_luaautomation/environment.lua
+++ b/advtrains/advtrains_luaautomation/environment.lua
@@ -25,6 +25,28 @@ function atlatc.remove_invalid_data(o, nested)
nested[o] = nil
return o
end
+function atlatc.replace_function_envs(o, fenv, nested)
+ if o==nil then return nil end
+ local valid_dt={["nil"]=true, boolean=true, number=true, string=true}
+ if type(o) ~= "table" then
+ --check valid data type
+ if type(o)=="function" then
+ setfenv(o, fenv)
+ end
+ return o
+ end
+ -- Contains table -> true/nil of currently nested tables
+ nested = nested or {}
+ if nested[o] then
+ return nil
+ end
+ nested[o] = true
+ for k, v in pairs(o) do
+ v = atlatc.replace_function_envs(v, fenv, nested)
+ end
+ nested[o] = nil
+ return o
+end
local env_proto={
@@ -149,7 +171,15 @@ local static_env = {
POS = function(x,y,z) return {x=x, y=y, z=z} end,
getstate = p_api_getstate,
setstate = p_api_setstate,
-
+ --interrupts are handled per node, position unknown.
+ --however external interrupts can be set here.
+ interrupt_pos = function(pos, imesg)
+ if not type(pos)=="table" or not pos.x or not pos.y or not pos.z then
+ debug.sethook()
+ error("Invalid position supplied to interrupt_pos")
+ end
+ atlatc.interrupt.add(0, pos, {type="ext_int", ext_int=true, message=imesg})
+ end,
}
for _, name in pairs(safe_globals) do
@@ -168,7 +198,6 @@ end
function env_proto:execute_code(fenv, code, evtdata, customfct)
local metatbl ={
__index = function(t, i)
- print("index metamethod:",i)
if i=="S" then
return self.sdata
elseif i=="F" then
@@ -193,6 +222,9 @@ function env_proto:execute_code(fenv, code, evtdata, customfct)
if not fun then
return false, err
end
+ --set function environment for all functions residing in F, so they get the right variables. Else it's a huge mess...
+ atlatc.replace_function_envs(self.fdata, fenv)
+
setfenv(fun, fenv)
local succ, data = pcall(fun)
if succ then
@@ -203,9 +235,11 @@ end
function env_proto:run_initcode()
if self.init_code and self.init_code~="" then
- local succ, err = self:execute_code(self.init_code, nil, {}, "Global init code")
+ self.fdata = {}
+ atprint("[atlatc]Running initialization code for environment '"..self.name.."'")
+ local succ, err = self:execute_code({}, self.init_code, {type="init", init=true})
if not succ then
- --TODO
+ self.init_err=err
end
end
end
diff --git a/advtrains/advtrains_luaautomation/init.lua b/advtrains/advtrains_luaautomation/init.lua
index 12e1b1d..37e5714 100644
--- a/advtrains/advtrains_luaautomation/init.lua
+++ b/advtrains/advtrains_luaautomation/init.lua
@@ -26,6 +26,8 @@ dofile(mp.."/active_common.lua")
dofile(mp.."/atc_rail.lua")
dofile(mp.."/operation_panel.lua")
dofile(mp.."/p_mesecon_iface.lua")
+dofile(mp.."/chatcmds.lua")
+
local filename=minetest.get_worldpath().."/advtrains_luaautomation"
local file, err = io.open(filename, "r")
diff --git a/advtrains/advtrains_luaautomation/passive.lua b/advtrains/advtrains_luaautomation/passive.lua
index 78b8c2d..e32bee9 100644
--- a/advtrains/advtrains_luaautomation/passive.lua
+++ b/advtrains/advtrains_luaautomation/passive.lua
@@ -2,6 +2,10 @@
-- API to passive components, as described in passive_api.txt
local function getstate(pos)
+ if not type(pos)=="table" or not pos.x or not pos.y or not pos.z then
+ debug.sethook()
+ error("Invalid position supplied to getstate")
+ end
local node=advtrains.ndb.get_node(pos)
local ndef=minetest.registered_nodes[node.name]
if ndef and ndef.luaautomation and ndef.luaautomation.getstate then
@@ -16,6 +20,10 @@ local function getstate(pos)
end
local function setstate(pos, newstate)
+ if not type(pos)=="table" or not pos.x or not pos.y or not pos.z then
+ debug.sethook()
+ error("Invalid position supplied to setstate")
+ end
local node=advtrains.ndb.get_node(pos)
local ndef=minetest.registered_nodes[node.name]
if ndef and ndef.luaautomation and ndef.luaautomation.setstate then