aboutsummaryrefslogtreecommitdiff
path: root/advtrains_interlocking/routesetting.lua
diff options
context:
space:
mode:
Diffstat (limited to 'advtrains_interlocking/routesetting.lua')
-rw-r--r--advtrains_interlocking/routesetting.lua107
1 files changed, 70 insertions, 37 deletions
diff --git a/advtrains_interlocking/routesetting.lua b/advtrains_interlocking/routesetting.lua
index 9973569..d619aac 100644
--- a/advtrains_interlocking/routesetting.lua
+++ b/advtrains_interlocking/routesetting.lua
@@ -43,15 +43,16 @@ function ilrs.set_route(signal, route, try)
local first = true
local i = 1
local rtename = route.name
- local signalname = ildb.get_tcbs(signal).signal_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
c_tcbs = ildb.get_tcbs(c_sigd)
if not c_tcbs then
if not try then atwarn("Did not find TCBS",c_sigd,"while setting route",rtename,"of",signal) end
- return false, "No TCB found at "..sigd_to_string(c_sigd)..". Please reconfigure route!"
+ return false, "No TCB found at "..sigd_to_string(c_sigd)..". Please update or reconfigure route!"
end
if i == 1 then
nodst = c_tcbs.nodst
@@ -67,35 +68,56 @@ 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
- for pts, state in pairs(c_rseg.locks) do
+ -- collect locks from rs cache and from route def
+ local c_locks = {}
+ if route.use_rscache and c_ts.rs_cache and c_rseg.next then
+ -- rscache needs to be enabled, present and next must be defined
+ start_pkey = advtrains.encode_pos(c_sigd.p)
+ end_pkey = advtrains.encode_pos(c_rseg.next.p)
+ if c_ts.rs_cache[start_pkey] and c_ts.rs_cache[start_pkey][end_pkey] then
+ for lp,lst in pairs(c_ts.rs_cache[start_pkey][end_pkey]) do
+ atdebug("Add lock from RSCache:",lp,"->",lst)
+ c_locks[lp] = lst
+ end
+ elseif not try then
+ atwarn("While setting route",rtename,"of",signal,"segment "..i..",required path from",c_tcbs,"to",c_rseg.next,"was not found in the track section's RS cache. Please check!")
+ end
+ end
+ -- add all from locks, these override the rscache
+ for lpts,lst in pairs(c_rseg.locks) do
+ atdebug("Add lock from Routedef:",lp,"->",lst,"overrides",c_locks[lp] or "none")
+ c_locks[lp] = lst
+ end
+
+ for lp, state in pairs(c_locks) do
local confl = ilrs.has_route_lock(pts, state)
- local pos = minetest.string_to_pos(pts)
+ local pos = advtrains.decode_pos(lp)
if advtrains.is_passive(pos) then
local cstate = advtrains.getstate(pos)
if cstate ~= state then
- local confl = ilrs.has_route_lock(pts)
+ local confl = ilrs.has_route_lock(lp)
if confl then
- if not try then atwarn("Encountered route lock while a real run of routesetting routine, at position",pts,"while setting route",rtename,"of",signal) end
- return false, "Lock conflict at "..pts..", Held locked by:\n"..confl, nil, pts
+ if not try then atwarn("Encountered route lock while a real run of routesetting routine, at position",pos,"while setting route",rtename,"of",signal) end
+ return false, "Lock conflict at "..minetest.pos_to_string(pos)..", Held locked by:\n"..confl, nil, lp
elseif not try then
advtrains.setstate(pos, state)
end
end
if not try then
- ilrs.add_route_lock(pts, c_ts_id, "Route '"..rtename.."' from signal '"..signalname.."'", signal)
- c_lckp[#c_lckp+1] = pts
+ ilrs.add_route_lock(lp, c_ts_id, "Route '"..rtename.."' from signal '"..signalname.."'", signal)
+ c_lckp[#c_lckp+1] = lp
end
else
if not try then atwarn("Encountered route lock misconfiguration (no passive component) while a real run of routesetting routine, at position",pts,"while setting route",rtename,"of",signal) end
- return false, "No passive component at "..pts..". Please reconfigure route!"
+ return false, "No passive component at "..minetest.pos_to_string(pos)..". Please update track section or reconfigure route!"
end
end
-- reserve ts and write locks
@@ -117,9 +139,17 @@ function ilrs.set_route(signal, route, try)
}
if c_tcbs.signal then
c_tcbs.route_committed = true
- c_tcbs.aspect = route.aspect or advtrains.interlocking.FULL_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
@@ -128,30 +158,38 @@ 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
- if lastsig then
- local tcbs = signals[i]
- local pos = tcbs.signal
- local _, assigned_by = advtrains.distant.get_main(pos)
- if (not nodst) and (not assigned_by or assigned_by == "routesetting") then
- advtrains.distant.assign(lastsig, pos, "routesetting", true)
- end
- advtrains.interlocking.update_signal_aspect(tcbs, 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
end
+-- Change 2024-01-27: pts is not an encoded pos, not a pos-to-string!
+
-- Checks whether there is a route lock that prohibits setting the component
-- to the wanted state. returns string with reasons on conflict
function ilrs.has_route_lock(pts)
@@ -217,7 +255,7 @@ function ilrs.free_route_locks_indiv(pts, ts, nocallbacks)
-- TODO use luaautomation timers?
if not nocallbacks then
minetest.after(0, ilrs.update_waiting, "lck", pts)
- minetest.after(0.5, advtrains.set_fallback_state, minetest.string_to_pos(pts))
+ minetest.after(0.5, advtrains.set_fallback_state, advtrains.decode_pos(pts))
end
end
-- frees all route locks, even manual ones set with the tool, at a specific position
@@ -250,19 +288,13 @@ 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
- if c_tcbs.signal then
- local pos = c_tcbs.signal
- local _, assigned_by = advtrains.distant.get_main(pos)
- if assigned_by == "routesetting" then
- advtrains.distant.unassign_dst(pos, true)
- end
- end
- advtrains.interlocking.update_signal_aspect(c_tcbs)
+ advtrains.interlocking.signal.update_route_aspect(c_tcbs)
c_ts_id = c_tcbs.ts_id
if not c_tcbs then
@@ -312,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
@@ -347,7 +380,7 @@ function ilrs.update_route(sigd, tcbs, newrte, cancel)
end
if has_changed_aspect then
-- FIX: prevent an minetest.after() loop caused by update_signal_aspect dispatching path invalidation, which in turn calls ARS again
- advtrains.interlocking.update_signal_aspect(tcbs)
+ advtrains.interlocking.signal.update_route_aspect(tcbs)
end
advtrains.interlocking.update_player_forms(sigd)
end