aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authororwell96 <orwell@bleipb.de>2021-02-17 19:10:40 +0100
committerorwell96 <orwell@bleipb.de>2021-02-17 19:15:20 +0100
commit1e4156d0a4e42b519ca2f64f4146c7a7faec49a3 (patch)
tree05e3bf4c32154fe639c9b1b59640cdb053076fca
parentd13a610c2e66b4ac1e585c15022ce43317e6ea4c (diff)
downloadadvtrains-1e4156d0a4e42b519ca2f64f4146c7a7faec49a3.tar.gz
advtrains-1e4156d0a4e42b519ca2f64f4146c7a7faec49a3.tar.bz2
advtrains-1e4156d0a4e42b519ca2f64f4146c7a7faec49a3.zip
LuaATC: Improve error/print logging, log only to subscribed players
-rw-r--r--advtrains_luaautomation/active_common.lua9
-rw-r--r--advtrains_luaautomation/chatcmds.lua68
-rw-r--r--advtrains_luaautomation/environment.lua55
3 files changed, 99 insertions, 33 deletions
diff --git a/advtrains_luaautomation/active_common.lua b/advtrains_luaautomation/active_common.lua
index d3985dc..f06eb51 100644
--- a/advtrains_luaautomation/active_common.lua
+++ b/advtrains_luaautomation/active_common.lua
@@ -109,8 +109,9 @@ function ac.run_in_env(pos, evtdata, customfct_p)
atwarn("LuaAutomation component at",ph,": Not an existing environment: "..(nodetbl.env or "<nil>"))
return false
end
+ local env = atlatc.envs[nodetbl.env]
if not nodetbl.code or nodetbl.code=="" then
- atwarn("LuaAutomation component at",ph,": No code to run! (insert -- to suppress warning)")
+ env:log("warning", "LuaAutomation component at",ph,": No code to run! (insert -- to suppress warning)")
return false
end
@@ -141,14 +142,14 @@ function ac.run_in_env(pos, evtdata, customfct_p)
end
local datain=nodetbl.data or {}
- local succ, dataout = atlatc.envs[nodetbl.env]:execute_code(datain, nodetbl.code, evtdata, customfct)
+ local succ, dataout = env:execute_code(datain, nodetbl.code, evtdata, customfct)
if succ then
atlatc.active.nodes[ph].data=atlatc.remove_invalid_data(dataout)
else
atlatc.active.nodes[ph].err=dataout
- atwarn("LuaAutomation ATC interface rail at",ph,": LUA Error:",dataout)
+ env:log("error", "LuaATC component at",ph,": LUA Error:",dataout)
if meta then
- meta:set_string("infotext", "LuaAutomation ATC interface rail, ERROR:"..dataout)
+ meta:set_string("infotext", "LuaATC component, ERROR:"..dataout)
end
--TODO temporary
--if customfct.atc_id then
diff --git a/advtrains_luaautomation/chatcmds.lua b/advtrains_luaautomation/chatcmds.lua
index 2d0c69d..468698b 100644
--- a/advtrains_luaautomation/chatcmds.lua
+++ b/advtrains_luaautomation/chatcmds.lua
@@ -43,12 +43,78 @@ core.register_chatcommand("env_create", {
privs = {atlatc=true},
func = function(name, param)
if not param or param=="" then return false, "Name required!" end
+ if string.find(param, "[^a-zA-Z0-9-_]") then return false, "Invalid name (only common characters)" end
if atlatc.envs[param] then return false, "Environment already exists!" end
atlatc.envs[param] = atlatc.env_new(param)
+ atlatc.envs[param].subscribers = {name}
return true, "Created environment '"..param.."'. Use '/env_setup "..param.."' to define global initialization code, or start building LuaATC components!"
end,
})
-
+core.register_chatcommand("env_subscribe", {
+ params = "<environment name>",
+ description = "Subscribe to the log of an Advtrains LuaATC environment",
+ privs = {atlatc=true},
+ func = function(name, param)
+ local env=atlatc.envs[param]
+ if not env then return false,"Invalid environment name!" end
+ for _,pname in ipairs(env.subscribers) do
+ if pname==name then
+ return false, "Already subscribed!"
+ end
+ end
+ table.insert(env.subscribers, name)
+ return true, "Subscribed to environment '"..param.."'."
+ end,
+})
+core.register_chatcommand("env_unsubscribe", {
+ params = "<environment name>",
+ description = "Unubscribe to the log of an Advtrains LuaATC environment",
+ privs = {atlatc=true},
+ func = function(name, param)
+ local env=atlatc.envs[param]
+ if not env then return false,"Invalid environment name!" end
+ for index,pname in ipairs(env.subscribers) do
+ if pname==name then
+ table.remove(env.subscribers, index)
+ return true, "Successfully unsubscribed!"
+ end
+ end
+ return false, "Not subscribed to environment '"..param.."'."
+ end,
+})
+core.register_chatcommand("env_subscriptions", {
+ params = "[environment name]",
+ description = "List Advtrains LuaATC environments you are subscribed to (no parameters) or subscribers of an environment (giving an env name).",
+ privs = {atlatc=true},
+ func = function(name, param)
+ if not param or param=="" then
+ local none=true
+ for envname, env in pairs(atlatc.envs) do
+ for _,pname in ipairs(env.subscribers) do
+ if pname==name then
+ none=false
+ minetest.chat_send_player(name, envname)
+ end
+ end
+ end
+ if none then
+ return false, "Not subscribed to any!"
+ end
+ return true
+ end
+ local env=atlatc.envs[param]
+ if not env then return false,"Invalid environment name!" end
+ local none=true
+ for index,pname in ipairs(env.subscribers) do
+ none=false
+ minetest.chat_send_player(name, pname)
+ end
+ if none then
+ return false, "No subscribers!"
+ end
+ return true
+ end,
+})
minetest.register_on_player_receive_fields(function(player, formname, fields)
diff --git a/advtrains_luaautomation/environment.lua b/advtrains_luaautomation/environment.lua
index 3e7787b..9ef320c 100644
--- a/advtrains_luaautomation/environment.lua
+++ b/advtrains_luaautomation/environment.lua
@@ -33,12 +33,12 @@ local env_proto={
self.sdata=data.sdata and atlatc.remove_invalid_data(data.sdata) or {}
self.fdata={}
self.init_code=data.init_code or ""
- self.step_code=data.step_code or ""
+ self.subscribers=data.subscribers or {}
end,
save = function(self)
-- throw any function values out of the sdata table
self.sdata = atlatc.remove_invalid_data(self.sdata)
- return {sdata = self.sdata, init_code=self.init_code, step_code=self.step_code}
+ return {sdata = self.sdata, init_code=self.init_code, subscribers=self.subscribers}
end,
}
@@ -50,14 +50,6 @@ local safe_globals = {
"tonumber", "tostring", "type", "unpack", "_VERSION"
}
---print is actually minetest.chat_send_all()
---using advtrains.print_concat_table because it's cool
-local function safe_print(t, ...)
- local str=advtrains.print_concat_table({t, ...})
- minetest.log("action", "[atlatc] "..str)
- minetest.chat_send_all(str)
-end
-
local function safe_date(f, t)
if not f then
-- fall back to old behavior
@@ -95,7 +87,6 @@ local mp=minetest.get_modpath("advtrains_luaautomation")
local static_env = {
--core LUA functions
- print = safe_print,
string = {
byte = string.byte,
char = string.char,
@@ -252,7 +243,6 @@ for _, name in pairs(safe_globals) do
static_env[name] = _G[name]
end
-
--The environment all code calls get is a table that has set static_env as metatable.
--In general, every variable is local to a single code chunk, but kept persistent over code re-runs. Data is also saved, but functions and userdata and circular references are removed
--Init code and step code's environments are not saved
@@ -265,6 +255,14 @@ local proxy_env={}
-- returns: true, fenv if successful; nil, error if error
function env_proto:execute_code(localenv, code, evtdata, customfct)
+ -- create us a print function specific for this environment
+ if not self.safe_print_func then
+ local myenv = self
+ self.safe_print_func = function(...)
+ myenv:log("info", ...)
+ end
+ end
+
local metatbl ={
__index = function(t, i)
if i=="S" then
@@ -277,6 +275,8 @@ function env_proto:execute_code(localenv, code, evtdata, customfct)
return customfct[i]
elseif localenv and localenv[i] then
return localenv[i]
+ elseif i=="print" then
+ return self.safe_print_func
end
return static_env[i]
end,
@@ -306,35 +306,39 @@ function env_proto:run_initcode()
if self.init_code and self.init_code~="" then
local old_fdata=self.fdata
self.fdata = {}
- atprint("[atlatc]Running initialization code for environment '"..self.name.."'")
+ --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
- atwarn("[atlatc]Executing InitCode for '"..self.name.."' failed:"..err)
+ self:log("error", "Executing InitCode for '"..self.name.."' failed:"..err)
self.init_err=err
if old_fdata then
self.fdata=old_fdata
- atwarn("[atlatc]The 'F' table has been restored to the previous state.")
+ self:log("warning", "The 'F' table has been restored to the previous state.")
end
end
end
end
-function env_proto:run_stepcode()
- if self.step_code and self.step_code~="" then
- local succ, err = self:execute_code({}, self.step_code, nil, {})
- if not succ then
- --TODO
- end
+
+-- log to environment subscribers. severity can be "error", "warning" or "info" (used by internal print)
+function env_proto:log(severity, ...)
+ local text=advtrains.print_concat_table({"[atlatc "..self.name.." "..severity.."]", ...})
+ minetest.log("action", text)
+ for _, pname in ipairs(self.subscribers) do
+ minetest.chat_send_player(pname, text)
end
end
+-- env.subscribers table may be directly altered by callers.
+
+
--- class interface
function atlatc.env_new(name)
local newenv={
name=name,
init_code="",
- step_code="",
- sdata={}
+ sdata={},
+ subscribers={},
}
setmetatable(newenv, {__index=env_proto})
return newenv
@@ -351,11 +355,6 @@ function atlatc.run_initcode()
env:run_initcode()
end
end
-function atlatc.run_stepcode()
- for envname, env in pairs(atlatc.envs) do
- env:run_stepcode()
- end
-end