From dcdd3ea702494e9e5bfeba96a72999f35aa2c91a Mon Sep 17 00:00:00 2001 From: ywang Date: Sun, 30 May 2021 12:16:09 +0200 Subject: round speed limit downward if needed; add basic distant signal implementation --- advtrains_interlocking/distant_signals.lua | 83 ++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 advtrains_interlocking/distant_signals.lua (limited to 'advtrains_interlocking/distant_signals.lua') diff --git a/advtrains_interlocking/distant_signals.lua b/advtrains_interlocking/distant_signals.lua new file mode 100644 index 0000000..0da1c10 --- /dev/null +++ b/advtrains_interlocking/distant_signals.lua @@ -0,0 +1,83 @@ +local interlocking = advtrains.interlocking +local ildb = advtrains.interlocking.db + +local function update_distant(tcbs) + if not (tcbs and tcbs.signal) then return end + if not tcbs.aspect then tcbs.aspect = table.copy(interlocking.DANGER) end + local asp = tcbs.aspect + if tcbs.distant_of then + asp.dst = (ildb.get_tcbs(tcbs.distant_of[1]).aspect or interlocking.DANGER).main + end + interlocking.update_signal_aspect(tcbs) + if tcbs.distant then + local dst = tcbs.distant + for i = 1, #dst do + local s = ildb.get_tcbs(dst[i]) + if not s.aspect then s.aspect = table.copy(interlocking.DANGER) end + s.aspect.dst = asp.main + interlocking.update_signal_aspect(s) + end + end +end + +local function unassign_distant(dsts) + if not dsts then return end + local dof = dsts.distant_of + if not dof then return end + if dsts.signal and dsts.aspect then + dsts.aspect.dst = nil + interlocking.update_signal_aspect(dsts) + end + local sigd, idx = dof[1], dof[2] + local tcbs = ildb.get_tcbs(sigd) + local dst = tcbs.distant + dsts.distant_of = nil + if idx == #dst then + dst[#dst] = nil + else + local ent = dst[#dst] + dst[idx] = ent + dst[#dst] = nil + local repl = ildb.get_tcbs(ent) + repl.distant_of[2] = idx + end +end + +local function assign_distant(sigd, dstd) + if not sigd then return end + if not dstd then return end + local tcbs = ildb.get_tcbs(sigd) + local dsts = ildb.get_tcbs(dstd) + unassign_distant(dsts) + if not (tcbs.signal and dsts.signal) then return end + local dst = tcbs.distant + if not dst then + dst = {} + tcbs.distant = dst + end + local newidx = #dst+1 + dsts.distant_of = {sigd, newidx} + dst[newidx] = dstd + update_distant(dsts) +end + +local function remove_distant(tcbs) + if not tcbs then return end + if tcbs.distant_of then + unassign_distant(tcbs) + end + if tcbs.distant then + local dst = tcbs.distant + for i = #dst, 1, -1 do + local s = ildb.get_tcbs(dst[i]) + unassign_distant(s) + end + end +end + +interlocking.distant = { + assign = assign_distant, + unassign = unassign_distant, + remove = remove_distant, + update = update_distant, +} -- cgit v1.2.3