Add LuaAutomation interface functions for interlocking routesetting and aspect requesting.

This allows to incorporate interlocking to automated systems
master
orwell96 2018-08-24 22:39:13 +02:00
parent 5039c958a2
commit d837e7e5e9
6 changed files with 102 additions and 17 deletions

View File

@ -364,5 +364,5 @@ minetest.register_chatcommand("at_rp_discard",
--TODO on route setting
-- unify luaautomation get/setstate interface to the core
-- routes should end at signals. complete route setting by punching a signal, and command as exceptional route completion
-- Create simpler way to advance a route to the next tcb/signal on simple sections without turnouts

View File

@ -20,13 +20,6 @@ ilrs.rte_callbacks = {
lck = {}
}
-- Requests the given route
-- This function will try to set the designated route.
-- If this is not possible, route is inserted in the subscriber list for
-- the problematic lock points
function ilrs.request_route(signal, tcbs, routeid)
end
-- main route setting. First checks if everything can be set as designated,
-- then (if "try" is not set) actually sets it

View File

@ -55,17 +55,20 @@ Every attempt to overwrite any of the predefined values results in an error.
POS(x,y,z)
Shorthand function to create a position vector {x=?, y=?, z=?} with less characters
In the following functions, all parameters named 'pos' designate a position. You can use either:
- a default Minetest position vector (like {x=34, y=2, z=-18})
- the POS(34,2,-18) shorthand
- A string, the passive component name. See 'passive component naming'.
getstate(pos)
Get the state of the passive component at position 'pos'. See section on passive components for more info.
pos can be either a position vector (created by POS()) or a string, the name of this passive component.
setstate(pos, newstate)
Set the state of the passive component at position 'pos'.
pos can be either a position vector (created by POS()) or a string, the name of this passive component.
is_passive(pos)
Checks whether there is a passive component at the position pos (and/or whether a passive component with this name exists)
pos can be either a position vector (created by POS()) or a string, the name of this passive component.
interrupt(time, message)
Cause LuaAutomation to trigger an 'int' event on this component after the given time in seconds with the specified 'message' field. 'message' can be of any Lua data type.
@ -79,6 +82,38 @@ digiline_send(channel, message)
Make this active component send a digiline message on the specified channel.
Not available in init code!
-- The next 4 functions are available when advtrains_interlocking is enabled: --
can_set_route(pos, route_name)
Returns whether it is possible to set the route designated by route_name from the signal at pos.
set_route(pos, route_name)
Requests the given route from the signal at pos. Has the same effect as clicking "Set Route" in the signalling dialog.
cancel_route(pos)
Cancels the route that is set from the signal at pos. Has the same effect as clicking "Cancel Route" in the signalling dialog.
get_aspect(pos)
Returns the signal aspect of the signal at pos. A signal aspect has the following format:
aspect = {
main = { -- the next track section in line. Shows blocked for shunt routes
free = <boolean>,
speed = <int km/h>,
},
shunt = { -- whether a "shunting allowed" aspect should be shown
free = <boolean>,
}
dst = { -- the aspect of the next main signal on (at end of) route
free = <boolean>,
speed = <int km/h>,
}
info = {
call_on = <boolean>, -- Call-on route, expect train in track ahead
dead_end = <boolean>, -- Route ends on a dead end (e.g. bumper)
}
}
As of August 2018, only the aspect.main.free field is ever used by the interlocking system.
## Components and events
The event table is a table of the following format:

View File

@ -1,2 +1,3 @@
advtrains
advtrains_interlocking?
mesecons_switch?

View File

@ -154,14 +154,65 @@ local static_env = {
--however external interrupts can be set here.
interrupt_pos = function(parpos, imesg)
local pos=atlatc.pcnaming.resolve_pos(parpos)
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,
}
-- If interlocking is present, enable route setting functions
if advtrains.interlocking then
local function gen_checks(signal, route_name, noroutesearch)
assertt(route_name, "string")
local pos = atlatc.pcnaming.resolve_pos(signal)
local sigd = advtrains.interlocking.db.get_sigd_for_signal(pos)
if not sigd then
error("There's no signal at "..minetest.pos_to_string(pos))
end
local tcbs = advtrains.interlocking.db.get_tcbs(sigd)
if not tcbs then
error("Inconsistent configuration, no tcbs for signal at "..minetest.pos_to_string(pos))
end
local routeid, route
if not noroutesearch then
for routeidt, routet in ipairs(tcbs.routes) do
if routet.name == route_name then
routeid = routeidt
route = routet
break
end
end
if not route then
error("No route called "..route_name.." at "..minetest.pos_to_string(pos))
end
end
return pos, sigd, tcbs, routeid, route
end
static_env.can_set_route = function(signal, route_name)
local pos, sigd, tcbs, routeid, route = gen_checks(signal, route_name)
-- if route is already set on signal, return whether it's committed
if tcbs.routeset == routeid then
return tcbs.route_committed
end
-- actually try setting route (parameter 'true' designates try-run
local ok = advtrains.interlocking.route.set_route(sigd, route, true)
return ok
end
static_env.set_route = function(signal, route_name)
local pos, sigd, tcbs, routeid, route = gen_checks(signal, route_name)
return advtrains.interlocking.route.update_route(sigd, tcbs, routeid)
end
static_env.cancel_route = function(signal)
local pos, sigd, tcbs, routeid, route = gen_checks(signal, "", true)
return advtrains.interlocking.route.update_route(sigd, tcbs, nil, true)
end
static_env.get_aspect = function(signal)
local pos = atlatc.pcnaming.resolve_pos(signal)
return advtrains.interlocking.signal_get_aspect(pos)
end
end
for _, name in pairs(safe_globals) do
static_env[name] = _G[name]
end

View File

@ -12,9 +12,14 @@ function atlatc.pcnaming.save()
return atlatc.pcnaming.name_map
end
function atlatc.pcnaming.resolve_pos(posorname)
if type(posorname)=="table" then return posorname end
return atlatc.pcnaming.name_map[posorname]
function atlatc.pcnaming.resolve_pos(pos, func_name)
if type(pos)=="string" then
local e = atlatc.pcnaming.name_map[pos]
if e then return e end
elseif type(pos)=="table" and pos.x and pos.y and pos.z then
return pos
end
error("Invalid position supplied to " .. (func_name or "???")..": " .. dump(pos))
end
minetest.register_craftitem("advtrains_luaautomation:pcnaming",{