aboutsummaryrefslogtreecommitdiff
path: root/advtrains_interlocking
diff options
context:
space:
mode:
authororwell <orwell@bleipb.de>2024-06-12 00:25:14 +0200
committerorwell <orwell@bleipb.de>2024-06-12 00:25:14 +0200
commitdcceb65ff04573375016f2460edcbd349e506a4e (patch)
tree413ca8ce482a75bb7612888dd02a23870e118714 /advtrains_interlocking
parent72cae1327527672afe2bbb47662d42a44f086942 (diff)
downloadadvtrains-dcceb65ff04573375016f2460edcbd349e506a4e.tar.gz
advtrains-dcceb65ff04573375016f2460edcbd349e506a4e.tar.bz2
advtrains-dcceb65ff04573375016f2460edcbd349e506a4e.zip
Respect route_role of signals during routesetting, assign distant signals in routes
Diffstat (limited to 'advtrains_interlocking')
-rw-r--r--advtrains_interlocking/routesetting.lua46
-rw-r--r--advtrains_interlocking/signal_api.lua22
-rwxr-xr-xadvtrains_interlocking/tcb_ts_ui.lua3
-rw-r--r--advtrains_interlocking/train_sections.lua33
4 files changed, 65 insertions, 39 deletions
diff --git a/advtrains_interlocking/routesetting.lua b/advtrains_interlocking/routesetting.lua
index 51709dc..d619aac 100644
--- a/advtrains_interlocking/routesetting.lua
+++ b/advtrains_interlocking/routesetting.lua
@@ -45,6 +45,7 @@ function ilrs.set_route(signal, route, try)
local rtename = route.name
local signalname = (ildb.get_tcbs(signal).signal_name or "") .. sigd_to_string(signal)
local c_tcbs, c_ts_id, c_ts, c_rseg, c_lckp
+ -- signals = { { pos = ., tcbs_ref = <tcbs>, role = "main_distant", masp_override = nil, dst_type = "next_main" or "none" }
local signals = {}
local nodst
while c_sigd and i<=#route do
@@ -67,11 +68,11 @@ function ilrs.set_route(signal, route, try)
if c_ts.route then
if not try then atwarn("Encountered ts lock during a real run of routesetting routine, at ts=",c_ts_id,"while setting route",rtename,"of",signal) end
- return false, "Section '"..c_ts.name.."' already has route set from "..sigd_to_string(c_ts.route.origin)..":\n"..c_ts.route.rsn, c_ts_id, nil
+ return false, "Section '"..(c_ts.name or c_ts_id).."' already has route set from "..sigd_to_string(c_ts.route.origin)..":\n"..c_ts.route.rsn, c_ts_id, nil
end
if c_ts.trains and #c_ts.trains>0 then
if not try then atwarn("Encountered ts occupied during a real run of routesetting routine, at ts=",c_ts_id,"while setting route",rtename,"of",signal) end
- return false, "Section '"..c_ts.name.."' is occupied!", c_ts_id, nil
+ return false, "Section '"..(c_ts.name or c_ts_id).."' is occupied!", c_ts_id, nil
end
-- collect locks from rs cache and from route def
@@ -138,9 +139,17 @@ function ilrs.set_route(signal, route, try)
}
if c_tcbs.signal then
c_tcbs.route_committed = true
- c_tcbs.aspect = advtrains.interlocking.signal.MASP_FREE
c_tcbs.route_origin = signal
- signals[#signals+1] = c_tcbs
+ -- determine route role
+ local ndef = advtrains.ndb.get_ndef(c_tcbs.signal)
+ local sig_table = {
+ pos = c_tcbs.signal,
+ tcbs_ref = c_tcbs,
+ role = ndef and ndef.advtrains and ndef.advtrains.route_role,
+ masp_override = c_rseg.masp_override, --TODO implement masp_override on UI side
+ dst_type = "next_main", --TODO allow user differentiate
+ }
+ signals[#signals+1] = sig_table
end
end
-- advance
@@ -149,18 +158,31 @@ function ilrs.set_route(signal, route, try)
i = i + 1
end
- -- Distant signaling
- local lastsig = nil
+ -- Get reference to signal at end of route
+ local last_mainsig = nil
if c_sigd then
local e_tcbs = ildb.get_tcbs(c_sigd)
local pos = e_tcbs and e_tcbs.signal
if pos then
- lastsig = pos
+ last_mainsig = pos
end
end
for i = #signals, 1, -1 do
- -- TODO add logic for distant signal assign
- advtrains.interlocking.signal.update_route_aspect(signals[i], i ~= 1)
+ -- note the signals are iterated backwards. Switch depending on the role
+ local sig = signals[i]
+ -- apply mainaspect
+ sig.tcbs_ref.route_aspect = sig.masp_override or "_default"
+ if sig.role == "distant" or sig.role == "distant_repeater" or sig.role == "main_distant" then
+ -- assign the remote as the last mainsig
+ sig.tcbs_ref.route_remote = last_mainsig
+ end
+ if sig.role == "main" or sig.role == "main_distant" or sig.role == "end" then
+ -- record this as the new last mainsig
+ last_mainsig = sig.pos
+ end
+ -- for shunt signals nothing happens
+ -- update the signal aspect on map
+ advtrains.interlocking.signal.update_route_aspect(sig.tcbs_ref, i ~= 1)
end
return true
@@ -266,7 +288,8 @@ function ilrs.cancel_route_from(sigd)
--atdebug("cancelling",c_ts.route.rsn)
-- clear signal aspect and routesetting state
c_tcbs.route_committed = nil
- c_tcbs.aspect = nil
+ c_tcbs.route_aspect = nil
+ c_tcbs.route_remote = nil
c_tcbs.routeset = nil
c_tcbs.route_auto = nil
c_tcbs.route_origin = nil
@@ -321,7 +344,8 @@ function ilrs.update_route(sigd, tcbs, newrte, cancel)
advtrains.interlocking.route.cancel_route_from(sigd)
end
tcbs.route_committed = nil
- tcbs.aspect = nil
+ tcbs.route_aspect = nil
+ tcbs.route_remote = nil
has_changed_aspect = true
tcbs.routeset = nil
tcbs.route_auto = nil
diff --git a/advtrains_interlocking/signal_api.lua b/advtrains_interlocking/signal_api.lua
index b1e8b20..65fc787 100644
--- a/advtrains_interlocking/signal_api.lua
+++ b/advtrains_interlocking/signal_api.lua
@@ -96,11 +96,12 @@ ndef.advtrains = {
-- Returns the aspect info table (main, shunt, dst etc.)
distant_support = true or false
-- If true, signal is considered in distant signalling. If false or nil, rem_aspect and rem_aspinfo are never set.
- route_role = one of "main", "shunt", "distant", "distant_repeater", "end"
+ route_role = one of "main", "main_distant", "shunt", "distant", "distant_repeater", "end"
-- Determines how the signal behaves when routes are set. Only in effect when signal is assigned to a TCB.
-- main: The signal is a possible endpoint for a train move route. Distant signals before it refer to it.
-- shunt: The signal is a possible endpoint for a shunt move route. Ignored for distant signals.
-- distant, distant_repeater: When route is set, signal is always assigned its first main aspect. The next signal with role="main" is set as the remote signal. (currently no further distinction)
+ -- main_distant: Combination of main and distant - like "main", but additionally gets assigned to the next main like a "distant"
-- end: like main, but signifies that it marks an end of track and trains cannot continue further. (currently no practical implications above main)
}
@@ -329,9 +330,17 @@ function signal.get_aspect_info(pos)
local masp, remote, node, ndef = signal.get_aspect_internal(pos, aspt)
-- call into ndef
if ndef.advtrains and ndef.advtrains.get_aspect_info then
- local ai = ndef.advtrains.get_aspect_info(pos, masp)
- atdebug(pos,"aspectinfo",ai)
- return ai
+ local ai = ndef.advtrains.get_aspect_info
+ if type(ai)=="function" then
+ ai = ai(pos, masp)
+ end
+ if type(ai)=="table" then
+ atdebug(pos,"aspectinfo",ai)
+ return ai
+ else
+ error("For node "..node.name..": ndef.advtrains.get_aspect_info must be function or table")
+ end
+
end
end
@@ -380,8 +389,9 @@ end
--
function signal.update_route_aspect(tcbs, skip_dst_notify)
if tcbs.signal then
- local asp = tcbs.aspect or signal.MASP_HALT
- signal.set_aspect(tcbs.signal, asp.name, asp.speed, asp.remote, skip_dst_notify)
+ local asp = tcbs.route_aspect or "_halt"
+ local rem = tcbs.route_remote
+ signal.set_aspect(tcbs.signal, asp, rem, skip_dst_notify)
end
end
diff --git a/advtrains_interlocking/tcb_ts_ui.lua b/advtrains_interlocking/tcb_ts_ui.lua
index caf22e3..60be5f3 100755
--- a/advtrains_interlocking/tcb_ts_ui.lua
+++ b/advtrains_interlocking/tcb_ts_ui.lua
@@ -756,7 +756,8 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
local signal_pos = tcbs.signal
ildb.set_sigd_for_signal(signal_pos, nil)
tcbs.signal = nil
- tcbs.aspect = nil
+ tcbs.route_aspect = nil
+ tcbs.route_remote = nil
minetest.close_formspec(pname, formname)
minetest.chat_send_player(pname, "Signal has been unassigned. Name and routes are kept for reuse.")
return
diff --git a/advtrains_interlocking/train_sections.lua b/advtrains_interlocking/train_sections.lua
index 260f5a4..41da747 100644
--- a/advtrains_interlocking/train_sections.lua
+++ b/advtrains_interlocking/train_sections.lua
@@ -86,31 +86,22 @@ local function setsection(tid, train, ts_id, ts, sigd)
advtrains.interlocking.route.cancel_route_from(ts.route.origin)
atwarn("Route was cancelled.")
else
- -- train entered route regularily. Reset route and signal
- tcbs.route_committed = nil
- tcbs.route_comitted = nil -- TODO compatibility cleanup
- tcbs.aspect = nil
- tcbs.route_origin = nil
- if tcbs.signal then
- local spos = tcbs.signal
- local _, setter = advtrains.distant.get_main(spos)
- if setter == "routesetting" then
- advtrains.distant.unassign_dst(spos, true)
- end
- end
- advtrains.interlocking.update_signal_aspect(tcbs)
- if tcbs.signal and sigd_equal(ts.route.entry, ts.route.origin) then
- if tcbs.route_auto and tcbs.routeset then
- --atdebug("Resetting route (",ts.route.origin,")")
- advtrains.interlocking.route.update_route(ts.route.origin, tcbs)
- else
- tcbs.routeset = nil
- end
- end
+ -- train entered route regularily.
end
ts.route = nil
end
if tcbs.signal then
+ -- Reset route and signal
+ -- Note that the hit-route case is already handled by cancel_route_from
+ -- this code only handles signal at entering tcb and also triggers for non-route ts
+ tcbs.route_committed = nil
+ tcbs.route_aspect = nil
+ tcbs.route_remote = nil
+ tcbs.route_origin = nil
+ if not tcbs.route_auto then
+ tcbs.routeset = nil
+ end
+ advtrains.interlocking.signal.update_route_aspect(tcbs)
advtrains.interlocking.route.update_route(sigd, tcbs)
end
end