diff options
author | Singularis <singularis@volny.cz> | 2025-04-21 07:21:53 +0200 |
---|---|---|
committer | orwell <orwell@bleipb.de> | 2025-05-27 20:22:01 +0200 |
commit | 95a5586e0fe196e2291acaf128b8d1b4f8a32510 (patch) | |
tree | 6cc5ff9a64e533c8d9262f965e2246dfa2b3da24 /advtrains_interlocking/train_sections.lua | |
parent | 1d6913cec797b3848c93e8c6b16c3b6b2711d38c (diff) | |
download | advtrains-95a5586e0fe196e2291acaf128b8d1b4f8a32510.tar.gz advtrains-95a5586e0fe196e2291acaf128b8d1b4f8a32510.tar.bz2 advtrains-95a5586e0fe196e2291acaf128b8d1b4f8a32510.zip |
[advtrains] přechod na Advtrains 2.5.0 (první pokus)
- [ch_core/lib] drobná oprava
- [advtrains_attachment_offset_patch] použití initial_properties
Diffstat (limited to 'advtrains_interlocking/train_sections.lua')
-rw-r--r-- | advtrains_interlocking/train_sections.lua | 93 |
1 files changed, 58 insertions, 35 deletions
diff --git a/advtrains_interlocking/train_sections.lua b/advtrains_interlocking/train_sections.lua index 757f36a..a1ee87f 100644 --- a/advtrains_interlocking/train_sections.lua +++ b/advtrains_interlocking/train_sections.lua @@ -40,83 +40,99 @@ local function itkexist(tbl, ikey, com) return false end -local function itremove(tbl, com) +local function itremove(tbl, com, once) local i=1 while i <= #tbl do if tbl[i] == com then table.remove(tbl, i) + if once then return end else i = i + 1 end end end -local function itkremove(tbl, ikey, com) +local function itkremove(tbl, ikey, com, once) local i=1 while i <= #tbl do if tbl[i][ikey] == com then table.remove(tbl, i) + if once then return end else i = i + 1 end end end -local function setsection(tid, train, ts_id, ts, sigd) +local function setsection(tid, train, ts_id, ts, sigd, only_if_not_exist) -- train if not train.il_sections then train.il_sections = {} end - if not itkexist(train.il_sections, "ts_id", ts_id) then + if only_if_not_exist then + -- called for the back connid on enter, only to ensure that section is blocked if train was so far not registered + if not itkexist(train.il_sections, "ts_id", ts_id) then + table.insert(train.il_sections, {ts_id = ts_id, origin = sigd}) + end + else + -- insert always, this leads to duplicate entries if the train enters the same section a second time table.insert(train.il_sections, {ts_id = ts_id, origin = sigd}) end -- ts if not ts.trains then ts.trains = {} end - if not itexist(ts.trains, tid) then + if only_if_not_exist then + -- called for the back connid on enter, only to ensure that section is blocked if train was so far not registered + if not itexist(ts.trains, tid) then + table.insert(ts.trains, tid) + end + else table.insert(ts.trains, tid) end -- routes - local tcbs = advtrains.interlocking.db.get_tcbs(sigd) + local tcbs + if sigd then + tcbs = advtrains.interlocking.db.get_tcbs(sigd) + end -- route setting - clear route state if ts.route then --atdebug(tid,"enters",ts_id,"examining Routestate",ts.route) - if not sigd_equal(ts.route.entry, sigd) then + if sigd and not sigd_equal(ts.route.entry, sigd) then -- Train entered not from the route. Locate origin and cancel route! atwarn("Train",tid,"hit route",ts.route.rsn,"!") 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 - 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 + if tcbs and 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 + tcbs.route_rsn = 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 -local function freesection(tid, train, ts_id, ts) +local function freesection(tid, train, ts_id, ts, clear_all) -- train if not train.il_sections then train.il_sections = {} end - itkremove(train.il_sections, "ts_id", ts_id) + itkremove(train.il_sections, "ts_id", ts_id, not clear_all) -- ts if not ts.trains then ts.trains = {} end - itremove(ts.trains, tid) + itremove(ts.trains, tid, not clear_all) + -- route locks if ts.route_post then advtrains.interlocking.route.free_route_locks(ts_id, ts.route_post.locks) if ts.route_post.next then @@ -138,12 +154,18 @@ end -- This sets the section for both directions, to be failsafe advtrains.tnc_register_on_enter(function(pos, id, train, index) local tcb = ildb.get_tcb(pos) - if tcb then - for connid=1,2 do - local ts = tcb[connid].ts_id and ildb.get_ts(tcb[connid].ts_id) - if ts then - setsection(id, train, tcb[connid].ts_id, ts, {p=pos, s=connid}) - end + if tcb and train.path_cp[index] and train.path_cn[index] then + -- forward conn + local connid = train.path_cn[index] + local ts = tcb[connid] and tcb[connid].ts_id and ildb.get_ts(tcb[connid].ts_id) + if ts then + setsection(id, train, tcb[connid].ts_id, ts, {p=pos, s=connid}) + end + -- backward conn (safety only) + connid = train.path_cp[index] + ts = tcb[connid] and tcb[connid].ts_id and ildb.get_ts(tcb[connid].ts_id) + if ts then + setsection(id, train, tcb[connid].ts_id, ts, {p=pos, s=connid}, true) end end end) @@ -153,8 +175,9 @@ end) advtrains.tnc_register_on_leave(function(pos, id, train, index) local tcb = ildb.get_tcb(pos) if tcb and train.path_cp[index] then + -- backward conn local connid = train.path_cp[index] - local ts = tcb[connid].ts_id and ildb.get_ts(tcb[connid].ts_id) + local ts = tcb[connid] and tcb[connid].ts_id and ildb.get_ts(tcb[connid].ts_id) if ts then freesection(id, train, tcb[connid].ts_id, ts) end @@ -167,13 +190,13 @@ advtrains.te_register_on_create(function(id, train) -- let's see what track sections we find here local index = atround(train.index) local pos = advtrains.path_get(train, index) - local ts_id, origin = ildb.get_ts_at_pos(pos) + local ts_id = ildb.check_and_repair_ts_at_pos(pos, 1) -- passing connid 1 - that always exists if ts_id then local ts = ildb.get_ts(ts_id) if ts then - setsection(id, train, ts_id, ts, origin) + setsection(id, train, ts_id, ts, nil, true) else - atwarn("ILDB corruption: TCB",origin," has invalid TS reference") + atwarn("While placing train, TS didnt exist ",ts_id) end -- Make train a shunt move train.is_shunt = true |