Simplify Signal Aspect Table (H#132) [breaks compatibility with signal API]

This commit is contained in:
orwell96 2020-01-30 08:45:16 +01:00
parent 573d6b06b2
commit 119a09b784
8 changed files with 146 additions and 190 deletions

View File

@ -12,18 +12,10 @@ end
local function aspect(b) local function aspect(b)
return { return {
main = { main = (not b) and 0, -- b ? false : 0
free = b, shunt = false,
speed = -1, proceed_as_main = true,
}, dst = false,
shunt = {
free = false,
proceed_as_main = true
},
dst = {
free = true,
speed = -1,
},
info = {} info = {}
} }
end end
@ -81,7 +73,7 @@ for r,f in pairs({on={as="off", ls="green", als="red"}, off={as="on", ls="red",
-- new signal API -- new signal API
advtrains = { advtrains = {
set_aspect = function(pos, node, asp) set_aspect = function(pos, node, asp)
if asp.main.free then if asp.main != 0 then
advtrains.ndb.swap_node(pos, {name = "advtrains:retrosignal_on"..rotation, param2 = node.param2}, true) advtrains.ndb.swap_node(pos, {name = "advtrains:retrosignal_on"..rotation, param2 = node.param2}, true)
else else
advtrains.ndb.swap_node(pos, {name = "advtrains:retrosignal_off"..rotation, param2 = node.param2}, true) advtrains.ndb.swap_node(pos, {name = "advtrains:retrosignal_off"..rotation, param2 = node.param2}, true)
@ -140,7 +132,7 @@ for r,f in pairs({on={as="off", ls="green", als="red"}, off={as="on", ls="red",
-- new signal API -- new signal API
advtrains = { advtrains = {
set_aspect = function(pos, node, asp) set_aspect = function(pos, node, asp)
if asp.main.free then if asp.main != 0 then
advtrains.ndb.swap_node(pos, {name = "advtrains:signal_on"..rotation, param2 = node.param2}, true) advtrains.ndb.swap_node(pos, {name = "advtrains:signal_on"..rotation, param2 = node.param2}, true)
else else
advtrains.ndb.swap_node(pos, {name = "advtrains:signal_off"..rotation, param2 = node.param2}, true) advtrains.ndb.swap_node(pos, {name = "advtrains:signal_off"..rotation, param2 = node.param2}, true)
@ -208,7 +200,7 @@ for r,f in pairs({on={as="off", ls="green", als="red"}, off={as="on", ls="red",
-- new signal API -- new signal API
advtrains = { advtrains = {
set_aspect = function(pos, node, asp) set_aspect = function(pos, node, asp)
if asp.main.free then if asp.main != 0 then
advtrains.ndb.swap_node(pos, {name = "advtrains:signal_wall_"..loc.."_on", param2 = node.param2}, true) advtrains.ndb.swap_node(pos, {name = "advtrains:signal_wall_"..loc.."_on", param2 = node.param2}, true)
else else
advtrains.ndb.swap_node(pos, {name = "advtrains:signal_wall_"..loc.."_off", param2 = node.param2}, true) advtrains.ndb.swap_node(pos, {name = "advtrains:signal_wall_"..loc.."_off", param2 = node.param2}, true)

View File

@ -73,17 +73,17 @@ advtrains.tnc_register_on_approach(function(pos, id, train, index, has_entered,
--interpreting aspect and determining speed to proceed --interpreting aspect and determining speed to proceed
if travsht then if travsht then
--shunt move --shunt move
if asp.shunt.free then if asp.shunt then
nspd = SHUNT_SPEED_MAX nspd = SHUNT_SPEED_MAX
elseif asp.shunt.proceed_as_main and asp.main.free then elseif asp.shunt.proceed_as_main and asp.main != 0 then
nspd = asp.main.speed nspd = asp.main
travsht = false travsht = false
end end
else else
--train move --train move
if asp.main.free then if asp.main != 0 then
nspd = asp.main.speed nspd = asp.main
elseif asp.shunt.free then elseif asp.shunt then
nspd = SHUNT_SPEED_MAX nspd = SHUNT_SPEED_MAX
travsht = true travsht = true
end end

View File

@ -6,10 +6,10 @@
local setaspect = function(pos, node, asp) local setaspect = function(pos, node, asp)
if not asp.main.free then if asp.main == 0 then
advtrains.ndb.swap_node(pos, {name="advtrains_interlocking:ds_danger"}) advtrains.ndb.swap_node(pos, {name="advtrains_interlocking:ds_danger"})
else else
if asp.dst.free and asp.main.speed == -1 then if asp.dst != 0 and asp.main == -1 then
advtrains.ndb.swap_node(pos, {name="advtrains_interlocking:ds_free"}) advtrains.ndb.swap_node(pos, {name="advtrains_interlocking:ds_free"})
else else
advtrains.ndb.swap_node(pos, {name="advtrains_interlocking:ds_slow"}) advtrains.ndb.swap_node(pos, {name="advtrains_interlocking:ds_slow"})
@ -22,18 +22,10 @@ local setaspect = function(pos, node, asp)
end end
local suppasp = { local suppasp = {
main = { main = {0, 6, -1},
free = nil, dst = {0, false},
speed = {6, -1}, shunt = false,
}, proceed_as_main = true,
dst = {
free = nil,
speed = nil,
},
shunt = {
free = false,
proceed_as_main = true,
},
info = { info = {
call_on = false, call_on = false,
dead_end = false, dead_end = false,
@ -74,10 +66,7 @@ minetest.register_node("advtrains_interlocking:ds_free", {
supported_aspects = suppasp, supported_aspects = suppasp,
get_aspect = function(pos, node) get_aspect = function(pos, node)
return { return {
main = { main = -1,
free = true,
speed = -1,
}
} }
end, end,
}, },
@ -98,10 +87,7 @@ minetest.register_node("advtrains_interlocking:ds_slow", {
supported_aspects = suppasp, supported_aspects = suppasp,
get_aspect = function(pos, node) get_aspect = function(pos, node)
return { return {
main = { main = 6,
free = true,
speed = 6,
}
} }
end, end,
}, },

View File

@ -7,17 +7,9 @@ local function sigd_to_string(sigd)
end end
local asp_generic_free = { local asp_generic_free = {
main = { main = -1,
free = true, shunt = false,
speed = -1, dst = false,
},
shunt = {
free = false,
},
dst = {
free = true,
speed = -1,
},
info = {} info = {}
} }

View File

@ -4,28 +4,38 @@
--[[ --[[
Signal aspect table: Signal aspect table:
asp = { asp = {
main = { main = <int speed>,
free = <boolean>, -- Main signal aspect, tells state and permitted speed of next section
speed = <int km/h>, -- 0 = section is blocked
}, -- >0 = section is free, speed limit is this value
shunt = { -- -1 = section is free, maximum speed permitted
free = <boolean>, -- false = Signal doesn't provide main signal information, retain current speed limit.
shunt = <boolean>,
-- Whether train may proceed as shunt move, on sight -- Whether train may proceed as shunt move, on sight
-- main aspect takes precedence over this -- main aspect takes precedence over this
proceed_as_main = <boolean>, -- When main==0, train switches to shunt move and is restricted to speed 8
-- If an approaching train is a shunt move and "main.free" is set, proceed_as_main = <boolean>,
-- If an approaching train is a shunt move and 'shunt' is false,
-- the train may proceed as a train move under the "main" aspect -- the train may proceed as a train move under the "main" aspect
-- if the main aspect permits it (i.e. main!=0)
-- If this is not set, shunt moves are NOT allowed to switch to -- If this is not set, shunt moves are NOT allowed to switch to
-- a train move, and must stop even if "main.free" is set. -- a train move, and must stop even if "main" would permit passing.
-- This is intended to be used for "Halt for shunt moves" signs. -- This is intended to be used for "Halt for shunt moves" signs.
}
dst = { dst = <int speed>,
free = <boolean>, -- Distant signal aspect, tells state and permitted speed of the section after next section
speed = <int km/h>, -- The character of these information is purely informational
} -- At this time, this field is not actively used
-- 0 = section is blocked
-- >0 = section is free, speed limit is this value
-- -1 = section is free, maximum speed permitted
-- false = Signal doesn't provide distant signal information.
info = { info = {
-- the character of call_on and dead_end is purely informative
call_on = <boolean>, -- Call-on route, expect train in track ahead (not implemented yet) call_on = <boolean>, -- Call-on route, expect train in track ahead (not implemented yet)
dead_end = <boolean>, -- Route ends on a dead end (e.g. bumper) (not implemented yet) dead_end = <boolean>, -- Route ends on a dead end (e.g. bumper) (not implemented yet)
w_speed = <integer>, w_speed = <integer>,
-- "Warning speed restriction". Supposed for short-term speed -- "Warning speed restriction". Supposed for short-term speed
-- restrictions which always override any other restrictions -- restrictions which always override any other restrictions
@ -33,12 +43,6 @@ asp = {
-- (Example: german Langsamfahrstellen-Signale) -- (Example: german Langsamfahrstellen-Signale)
} }
} }
-- For "speed" and "w_speed" fields, a value of -1 means that the
-- restriction is lifted. If they are omitted, the value imposed at
-- the last aspect received remains valid.
-- The "dst" subtable can be completely omitted when no explicit dst
-- aspect should be signalled to the train. In this case, the last
-- signalled dst aspect remains valid.
== How signals actually work in here == == How signals actually work in here ==
Each signal (in the advtrains universe) is some node that has at least the Each signal (in the advtrains universe) is some node that has at least the
@ -87,22 +91,18 @@ advtrains = {
false: always shows "blocked", unchangable false: always shows "blocked", unchangable
true: always shows "free", unchangable true: always shows "free", unchangable
-- Any of the "speed" fields should contain a list of possible values -- Any of the "speed" fields should contain a list of possible values
-- to be set as restriction. If omitted, this signal should never -- to be set as restriction. If omitted, the value of the described
-- set the corresponding "speed" field in the aspect, which means -- field is always assumed to be false (no information)
-- that the previous speed limit stays valid -- A speed of 0 means that the signal can show a "blocked" aspect
-- (which is probably the case for most signals)
-- If the signal can signal "no information" on one of the fields
-- (thus false is an acceptable value), include false in the list
-- If your signal can only display a single speed (may it be -1), -- If your signal can only display a single speed (may it be -1),
-- always enclose that single value into a list. (such as {-1}) -- always enclose that single value into a list. (such as {-1})
main = { main = {<speed1>, ..., <speedn>} or nil,
free = <boolean/nil>, dst = {<speed1>, ..., <speedn>} or nil,
speed = {<speed1>, ..., <speedn>} or nil, shunt = <boolean/nil>,
},
dst = {
free = <boolean/nil>,
speed = {<speed1>, ..., <speedn>} or nil,
},
shunt = {
free = <boolean/nil>,
},
info = { info = {
call_on = <boolean/nil>, call_on = <boolean/nil>,
dead_end = <boolean/nil>, dead_end = <boolean/nil>,
@ -110,28 +110,36 @@ advtrains = {
} }
}, },
Example for supported_aspects:
supported_aspects = {
main = {0, 6, -1}, -- can show either "Section blocked", "Proceed at speed 6" or "Proceed at maximum speed"
dst = {0, false}, -- can show only if next signal shows "blocked", no other information.
shunt = false, -- shunting by this signal is never allowed.
info = {
call_on = false,
dead_end = false,
w_speed = nil,
} -- none of the information can be shown by the signal
},
get_aspect = function(pos, node) get_aspect = function(pos, node)
-- This function gets called by the train safety system. It -- This function gets called by the train safety system. It
should return the aspect that this signal actually displays, should return the aspect that this signal actually displays,
not preferably the input of set_aspect. not preferably the input of set_aspect.
-- For regular, full-featured light signals, they will probably -- For regular, full-featured light signals, they will probably
honor all entries in the original aspect, however, e.g. honor all entries in the original aspect, however, e.g.
simple shunt signals always return main.free=true regardless of simple shunt signals always return main=false regardless of
the set_aspect input because they can not signal "Halt" to the set_aspect input because they can not signal "Halt" to
train moves. train moves.
-- advtrains.interlocking.DANGER contains a default "all-danger" aspect. -- advtrains.interlocking.DANGER contains a default "all-danger" aspect.
-- If your signal does not cover certain sub-tables of the aspect, -- If your signal does not cover certain sub-tables of the aspect,
the following reasonable defaults are automatically assumed: the following reasonable defaults are automatically assumed:
main = { main = false (unchanged)
free = true, dst = false (unchanged)
} shunt = false (shunting not allowed)
dst = { info = {} (no further information)
free = true,
}
shunt = {
free = false,
proceed_as_main = false,
}
end, end,
} }
on_rightclick = advtrains.interlocking.signal_rc_handler on_rightclick = advtrains.interlocking.signal_rc_handler
@ -155,48 +163,14 @@ This function will query get_aspect to retrieve the new aspect.
]]-- ]]--
local DANGER = { local DANGER = {
main = { main = 0,
free = false, dst = false,
speed = 0, shunt = false,
},
shunt = {
free = false,
},
dst = {
free = false,
speed = 0,
},
info = {} info = {}
} }
advtrains.interlocking.DANGER = DANGER advtrains.interlocking.DANGER = DANGER
local function fillout_aspect(asp) local function fillout_aspect(asp)
if not asp.main then
asp.main = {
free = true,
}
elseif type(asp.main) ~= "table" then
asp.main = {
free = asp.main~=0,
speed = asp.main,
}
end
if not asp.dst then
asp.dst = {
free = true,
}
end
if not asp.shunt then
asp.shunt = {
free = false,
proceed_as_main = false,
}
elseif type(asp.shunt) ~= "table" then
asp.shunt = {
free = asp.shunt,
proceed_as_main = asp.proceed_as_main,
}
end
if not asp.info then if not asp.info then
asp.info = {} asp.info = {}
end end
@ -458,8 +432,10 @@ function advtrains.interlocking.show_signal_aspect_selector(pname, p_suppasp, p_
local form = "size[7,5]label[0.5,0.5;Select Signal Aspect:]" local form = "size[7,5]label[0.5,0.5;Select Signal Aspect:]"
form = form.."label[0.5,1;"..purpose.."]" form = form.."label[0.5,1;"..purpose.."]"
--TODO
form = form.."label[0.5,1.5;== Main Signal ==]" form = form.."label[0.5,1.5;== Main Signal ==]"
if suppasp.main.free == nil then if suppasp.main == 0 then
local st = 2 local st = 2
if isasp and not isasp.main.free then st=1 end if isasp and not isasp.main.free then st=1 end
form = form.."dropdown[0.5,2;2;main_free;danger,free;"..st.."]" form = form.."dropdown[0.5,2;2;main_free;danger,free;"..st.."]"

View File

@ -95,24 +95,47 @@ Cancels the route that is set from the signal at pos. Has the same effect as cli
get_aspect(pos) get_aspect(pos)
Returns the signal aspect of the signal at pos. A signal aspect has the following format: Returns the signal aspect of the signal at pos. A signal aspect has the following format:
aspect = { asp = {
main = { -- the next track section in line. Shows blocked for shunt routes main = <int speed>,
free = <boolean>, -- Main signal aspect, tells state and permitted speed of next section
speed = <int km/h>, -- 0 = section is blocked
}, -- >0 = section is free, speed limit is this value
shunt = { -- whether a "shunting allowed" aspect should be shown -- -1 = section is free, maximum speed permitted
free = <boolean>, -- false = Signal doesn't provide main signal information, retain current speed limit.
} shunt = <boolean>,
dst = { -- the aspect of the next main signal on (at end of) route -- Whether train may proceed as shunt move, on sight
free = <boolean>, -- main aspect takes precedence over this
speed = <int km/h>, -- When main==0, train switches to shunt move and is restricted to speed 8
} proceed_as_main = <boolean>,
-- If an approaching train is a shunt move and 'shunt' is false,
-- the train may proceed as a train move under the "main" aspect
-- if the main aspect permits it (i.e. main!=0)
-- If this is not set, shunt moves are NOT allowed to switch to
-- a train move, and must stop even if "main" would permit passing.
-- This is intended to be used for "Halt for shunt moves" signs.
dst = <int speed>,
-- Distant signal aspect, tells state and permitted speed of the section after next section
-- The character of these information is purely informational
-- At this time, this field is not actively used
-- 0 = section is blocked
-- >0 = section is free, speed limit is this value
-- -1 = section is free, maximum speed permitted
-- false = Signal doesn't provide distant signal information.
info = { info = {
call_on = <boolean>, -- Call-on route, expect train in track ahead -- the character of call_on and dead_end is purely informative
dead_end = <boolean>, -- Route ends on a dead end (e.g. bumper) call_on = <boolean>, -- Call-on route, expect train in track ahead (not implemented yet)
dead_end = <boolean>, -- Route ends on a dead end (e.g. bumper) (not implemented yet)
w_speed = <integer>,
-- "Warning speed restriction". Supposed for short-term speed
-- restrictions which always override any other restrictions
-- imposed by "speed" fields, until lifted by a value of -1
-- (Example: german Langsamfahrstellen-Signale)
} }
} }
As of August 2018, only the aspect.main.free field is ever used by the interlocking system. As of January 2020, the 'dst', 'call_on' and 'dead_end' fields are not used.
# Lines # Lines

View File

@ -6,14 +6,14 @@
local setaspectf = function(rot) local setaspectf = function(rot)
return function(pos, node, asp) return function(pos, node, asp)
if not asp.main.free then if asp.main == 0 then
if asp.shunt.free then if asp.shunt then
advtrains.ndb.swap_node(pos, {name="advtrains_signals_ks:hs_shunt_"..rot, param2 = node.param2}) advtrains.ndb.swap_node(pos, {name="advtrains_signals_ks:hs_shunt_"..rot, param2 = node.param2})
else else
advtrains.ndb.swap_node(pos, {name="advtrains_signals_ks:hs_danger_"..rot, param2 = node.param2}) advtrains.ndb.swap_node(pos, {name="advtrains_signals_ks:hs_danger_"..rot, param2 = node.param2})
end end
else else
if asp.dst.free and asp.main.speed == -1 then if asp.dst != 0 and asp.main == -1 then
advtrains.ndb.swap_node(pos, {name="advtrains_signals_ks:hs_free_"..rot, param2 = node.param2}) advtrains.ndb.swap_node(pos, {name="advtrains_signals_ks:hs_free_"..rot, param2 = node.param2})
else else
advtrains.ndb.swap_node(pos, {name="advtrains_signals_ks:hs_slow_"..rot, param2 = node.param2}) advtrains.ndb.swap_node(pos, {name="advtrains_signals_ks:hs_slow_"..rot, param2 = node.param2})
@ -22,19 +22,12 @@ local setaspectf = function(rot)
end end
end end
local suppasp = { local suppasp = {
main = { main = {0, 6, -1},
free = nil, dst = {0, false},
speed = {6, -1}, shunt = nil,
}, proceed_as_main = true,
dst = {
free = nil,
speed = nil,
},
shunt = {
free = nil,
proceed_as_main = true,
},
info = { info = {
call_on = false, call_on = false,
dead_end = false, dead_end = false,
@ -45,7 +38,7 @@ local suppasp = {
--Rangiersignal --Rangiersignal
local setaspectf_ra = function(rot) local setaspectf_ra = function(rot)
return function(pos, node, asp) return function(pos, node, asp)
if asp.shunt.free then if asp.shunt then
advtrains.ndb.swap_node(pos, {name="advtrains_signals_ks:ra_shuntd_"..rot, param2 = node.param2}) advtrains.ndb.swap_node(pos, {name="advtrains_signals_ks:ra_shuntd_"..rot, param2 = node.param2})
else else
advtrains.ndb.swap_node(pos, {name="advtrains_signals_ks:ra_danger_"..rot, param2 = node.param2}) advtrains.ndb.swap_node(pos, {name="advtrains_signals_ks:ra_danger_"..rot, param2 = node.param2})
@ -58,17 +51,11 @@ local setaspectf_ra = function(rot)
end end
local suppasp_ra = { local suppasp_ra = {
main = { main = { false },
free = true, dst = { false },
}, shunt = nil,
dst = { proceed_as_main = false,
free = nil,
speed = nil,
},
shunt = {
free = nil,
proceed_as_main = false,
},
info = { info = {
call_on = false, call_on = false,
dead_end = false, dead_end = false,
@ -90,9 +77,9 @@ for _, rtab in ipairs({
local rot = rtab.rot local rot = rtab.rot
for typ, prts in pairs({ for typ, prts in pairs({
danger = {asp = advtrains.interlocking.DANGER, n = "slow", ici=true}, danger = {asp = advtrains.interlocking.DANGER, n = "slow", ici=true},
slow = {asp = { main = { free = true, speed = 6 }, shunt = {proceed_as_main = true}} , n = "free"}, slow = {asp = { main = 6, proceed_as_main = true} , n = "free"},
free = {asp = { main = { free = true, speed = -1 }, shunt = {proceed_as_main = true}} , n = "shunt"}, free = {asp = { main = -1, proceed_as_main = true} , n = "shunt"},
shunt = {asp = { main = {free = false}, shunt = {free = true} } , n = "danger"}, shunt = {asp = { main = 0, shunt = true} , n = "danger"},
}) do }) do
minetest.register_node("advtrains_signals_ks:hs_"..typ.."_"..rot, { minetest.register_node("advtrains_signals_ks:hs_"..typ.."_"..rot, {
description = "Ks Main Signal", description = "Ks Main Signal",
@ -136,8 +123,8 @@ for _, rtab in ipairs({
--Rangiersignale: --Rangiersignale:
for typ, prts in pairs({ for typ, prts in pairs({
danger = {asp = { main = {free = true}, shunt = {free = false} }, n = "shuntd", ici=true}, danger = {asp = { main = false, shunt = false }, n = "shuntd", ici=true},
shuntd = {asp = { main = {free = true}, shunt = {free = true} } , n = "danger"}, shuntd = {asp = { main = false, shunt = true } , n = "danger"},
}) do }) do
minetest.register_node("advtrains_signals_ks:ra_"..typ.."_"..rot, { minetest.register_node("advtrains_signals_ks:ra_"..typ.."_"..rot, {
description = "Ks Shunting Signal", description = "Ks Shunting Signal",
@ -181,13 +168,13 @@ for _, rtab in ipairs({
--Schilder: --Schilder:
for typ, prts in pairs({ for typ, prts in pairs({
-- Speed restrictions: -- Speed restrictions:
["8"] = {asp = { main = {free = true, speed = 8}, shunt = {free = true} }, n = "12", ici=true}, ["8"] = {asp = { main = 8, shunt = true }, n = "12", ici=true},
["12"] = {asp = { main = {free = true, speed = 12}, shunt = {free = true} }, n = "16"}, ["12"] = {asp = { main = 12, shunt = true }, n = "16"},
["16"] = {asp = { main = {free = true, speed = 16}, shunt = {free = true} }, n = "e"}, ["16"] = {asp = { main = 16, shunt = true }, n = "e"},
-- Speed restriction lifted -- Speed restriction lifted
["e"] = {asp = { main = {free = true, speed = -1}, shunt = {free = true} }, n = "hfs"}, ["e"] = {asp = { main = -1, shunt = true }, n = "hfs"},
-- Halt for shunt moves: -- Halt for shunt moves:
["hfs"] = {asp = { main = {free = true}, shunt = {free = false} }, n = "8"}, ["hfs"] = {asp = { main = false, shunt = false }, n = "8"},
}) do }) do
minetest.register_node("advtrains_signals_ks:sign_"..typ.."_"..rot, { minetest.register_node("advtrains_signals_ks:sign_"..typ.."_"..rot, {
description = "Signal Sign", description = "Signal Sign",

View File

@ -1,5 +1,5 @@
-- Ks Signals for advtrains -- Ks Signals for advtrains
-- will implement the advtrains signal API (which does not exist yet) -- will implement the advtrains signal API
local function place_degrotate(pos, placer, itemstack, pointed_thing) local function place_degrotate(pos, placer, itemstack, pointed_thing)
local yaw = placer:get_look_horizontal() local yaw = placer:get_look_horizontal()