diff options
| -rw-r--r-- | advtrains/advtrains_luaautomation/active_common.lua | 7 | ||||
| -rw-r--r-- | advtrains/advtrains_luaautomation/atc_rail.lua | 2 | ||||
| -rw-r--r-- | advtrains/advtrains_luaautomation/chatcmds.lua | 70 | ||||
| -rw-r--r-- | advtrains/advtrains_luaautomation/environment.lua | 42 | ||||
| -rw-r--r-- | advtrains/advtrains_luaautomation/init.lua | 2 | ||||
| -rw-r--r-- | advtrains/advtrains_luaautomation/passive.lua | 8 | 
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  | 
