---
advtrains_luaautomation/README.md | 7 ++++
advtrains_luaautomation/active_common.lua | 5 ++-
advtrains_luaautomation/environment.lua | 46 ++++++++++++++++++++---
advtrains_luaautomation/mod.conf | 2 +-
4 files changed, 52 insertions(+), 8 deletions(-)
diff --git a/advtrains_luaautomation/README.md b/advtrains_luaautomation/README.md
index a885075..1ee2507 100644
--- a/advtrains_luaautomation/README.md
+++ b/advtrains_luaautomation/README.md
@@ -164,6 +164,13 @@ Schedules an event of type {type="schedule", schedule=true, msg=msg} at (resp. a
Note: Using the lines scheduler is preferred over using `interrupt()`, as it's more performant and safer to use.
+#### Mail
+
+The `mail` mod provides a facility to send in-game mail.
+
+ - `sendmail(subject, body)`
+Sends the mail with the given content to all subscribers of the environment.
+
## Events
The event table is a variable created locally by the component being triggered. It is a table with the following format:
```lua
diff --git a/advtrains_luaautomation/active_common.lua b/advtrains_luaautomation/active_common.lua
index 50fb2bc..a212205 100644
--- a/advtrains_luaautomation/active_common.lua
+++ b/advtrains_luaautomation/active_common.lua
@@ -161,7 +161,7 @@ function ac.run_in_env(pos, evtdata, customfct_p, ignore_no_code)
end
local datain=nodetbl.data or {}
- local succ, dataout = env:execute_code(datain, nodetbl.code, evtdata, customfct)
+ local succ, dataout, errdet = env:execute_code(datain, nodetbl.code, evtdata, customfct)
if succ then
atlatc.active.nodes[ph].data=atlatc.remove_invalid_data(dataout)
else
@@ -170,6 +170,9 @@ function ac.run_in_env(pos, evtdata, customfct_p, ignore_no_code)
if meta then
meta:set_string("infotext", "LuaATC component, ERROR:"..dataout)
end
+ if env.sendmail then
+ env:sendmail("LuaATC error for component at "..ph, errdet)
+ end
--TODO temporary
--if customfct.atc_id then
-- advtrains.drb_dump(customfct.atc_id)
diff --git a/advtrains_luaautomation/environment.lua b/advtrains_luaautomation/environment.lua
index d85bedc..576ace1 100644
--- a/advtrains_luaautomation/environment.lua
+++ b/advtrains_luaautomation/environment.lua
@@ -282,7 +282,7 @@ function env_proto:execute_code(localenv, code, evtdata, customfct)
myenv:log("info", ...)
end
end
-
+
local metatbl ={
__index = function(t, i)
if i=="S" then
@@ -297,6 +297,12 @@ function env_proto:execute_code(localenv, code, evtdata, customfct)
return localenv[i]
elseif i=="print" then
return self.safe_print_func
+ elseif i=="sendmail" then
+ if self.sendmail then
+ return function(...)
+ return self:sendmail(...)
+ end
+ end
end
return static_env[i]
end,
@@ -311,15 +317,18 @@ function env_proto:execute_code(localenv, code, evtdata, customfct)
setmetatable(proxy_env, metatbl)
local fun, err=loadstring(code)
if not fun then
- return false, err
+ return false, err, err.."\nSyntax error; no traceback available."
end
setfenv(fun, proxy_env)
- local succ, data = pcall(fun)
+ local succ, data = xpcall(fun, function(err)
+ return {err, debug.traceback(err)}
+ end)
if succ then
- data=localenv
+ return succ, localenv
+ else
+ return succ, unpack(data)
end
- return succ, data
end
function env_proto:run_initcode()
@@ -327,7 +336,7 @@ function env_proto:run_initcode()
local old_fdata=self.fdata
self.fdata = {}
--atprint("[atlatc]Running initialization code for environment '"..self.name.."'")
- local succ, err = self:execute_code({}, self.init_code, {type="init", init=true})
+ local succ, err, errdet = self:execute_code({}, self.init_code, {type="init", init=true})
if not succ then
self:log("error", "Executing InitCode for '"..self.name.."' failed:"..err)
self.init_err=err
@@ -335,6 +344,9 @@ function env_proto:run_initcode()
self.fdata=old_fdata
self:log("warning", "The 'F' table has been restored to the previous state.")
end
+ if self.sendmail then
+ self:sendmail("InitCode error", errdet)
+ end
end
end
end
@@ -348,6 +360,28 @@ function env_proto:log(severity, ...)
end
end
+if mail then
+ local function format_sender(name)
+ return ("atlatc/%s"):format(name)
+ end
+ if mail.version == nil then
+ function env_proto:sendmail(subject, body)
+ for _, pname in ipairs(self.subscribers) do
+ mail.send(format_sender(self.name), pname, subject, body)
+ end
+ end
+ else
+ function env_proto:sendmail(subject, body)
+ return mail.send {
+ from = format_sender(self.name),
+ to = table.concat(self.subscribers, ","),
+ subject = subject,
+ body = body
+ }
+ end
+ end
+end
+
-- env.subscribers table may be directly altered by callers.
diff --git a/advtrains_luaautomation/mod.conf b/advtrains_luaautomation/mod.conf
index a737603..2fc210d 100644
--- a/advtrains_luaautomation/mod.conf
+++ b/advtrains_luaautomation/mod.conf
@@ -4,4 +4,4 @@ description=Lua control interface to Advanced Trains
author=orwell96
depends=advtrains
-optional_depends=advtrains_interlocking,advtrains_line_automation,mesecons_switch
+optional_depends=advtrains_interlocking,advtrains_line_automation,mesecons_switch,mail
--
2.43.0