aboutsummaryrefslogtreecommitdiff
path: root/advtrains_interlocking
diff options
context:
space:
mode:
authororwell96 <orwell@bleipb.de>2018-06-29 16:16:55 +0200
committerorwell96 <orwell@bleipb.de>2018-06-29 16:16:55 +0200
commit820503ba81b709cecd86d621dd68e7701fe10222 (patch)
treeae73d7a852b5606e78533eddc907862c1bf50783 /advtrains_interlocking
parent86fa42050057af4e4129b8347c10d330842e4489 (diff)
downloadadvtrains-820503ba81b709cecd86d621dd68e7701fe10222.tar.gz
advtrains-820503ba81b709cecd86d621dd68e7701fe10222.tar.bz2
advtrains-820503ba81b709cecd86d621dd68e7701fe10222.zip
Implement trains blocking sections
Diffstat (limited to 'advtrains_interlocking')
-rw-r--r--advtrains_interlocking/database.lua4
-rw-r--r--advtrains_interlocking/tcb_ts_ui.lua11
-rw-r--r--advtrains_interlocking/train_related.lua150
3 files changed, 162 insertions, 3 deletions
diff --git a/advtrains_interlocking/database.lua b/advtrains_interlocking/database.lua
index e9e484c..f4a6871 100644
--- a/advtrains_interlocking/database.lua
+++ b/advtrains_interlocking/database.lua
@@ -382,7 +382,7 @@ end
-- Utilize the traverser to find the track section at the specified position
-- Returns:
--- ts_id - the first found ts
+-- ts_id, origin - the first found ts and the sigd of the found tcb
-- nil - there were no TCBs in TRAVERSER_MAX range of the position, or track ends were reached
-- false - the first found TCB stated End-Of-Interlocking
function ildb.get_ts_at_pos(pos)
@@ -397,7 +397,7 @@ function ildb.get_ts_at_pos(pos)
local tcbs = ildb.get_tcbs(found_tcbs[1])
local ts
if tcbs.ts_id then
- return tcbs.ts_id
+ return tcbs.ts_id, found_tcbs[1]
else
return false
end
diff --git a/advtrains_interlocking/tcb_ts_ui.lua b/advtrains_interlocking/tcb_ts_ui.lua
index 7e4d904..0ebe767 100644
--- a/advtrains_interlocking/tcb_ts_ui.lua
+++ b/advtrains_interlocking/tcb_ts_ui.lua
@@ -244,6 +244,15 @@ function advtrains.interlocking.show_ts_form(ts_id, pname, sel_tcb)
form = form.."button[5.5,5;4,1;del_tcb;Unlink selected TCB]"
hint = 2
end
+
+ -- occupying trains
+ if ts.trains and #ts.trains>0 then
+ form = form.."label[0.5,6.1;Trains on this section:]"
+ form = form.."textlist[0.5,6.7;3,2;trnlist;"..table.concat(ts.trains, ",").."]"
+ else
+ form = form.."label[0.5,6.1;No trains on this section.]"
+ end
+
if hint == 1 then
form = form.."label[0.5,0.75;Use the 'Join' button to designate rail crosses and link not listed far-away TCBs]"
elseif hint == 2 then
@@ -327,7 +336,7 @@ minetest.register_entity("advtrains_interlocking:tcbmarker", {
})
function advtrains.interlocking.show_tcb_marker(pos)
- atdebug("showing tcb marker",pos)
+ --atdebug("showing tcb marker",pos)
local tcb = advtrains.interlocking.db.get_tcb(pos)
if not tcb then return end
local node_ok, conns, rhe = advtrains.get_rail_info_at(pos, advtrains.all_tracktypes)
diff --git a/advtrains_interlocking/train_related.lua b/advtrains_interlocking/train_related.lua
index 3e1c05b..3d7e280 100644
--- a/advtrains_interlocking/train_related.lua
+++ b/advtrains_interlocking/train_related.lua
@@ -1,2 +1,152 @@
-- train_related.lua
-- Occupation of track sections - mainly implementation of train callbacks
+
+--[[
+Track section occupation is saved as follows
+
+In train:
+train.il_sections = {
+ [n] = {ts_id = <...> (origin = <sigd>)}
+}
+-- "origin" is the TCB (signal describer) the train initially entered this section
+
+In track section
+ts.trains = {
+ [n] = <train_id>
+}
+
+When any inconsistency is detected, we will assume the most restrictive setup.
+It will be possible to indicate a section "free" via the GUI.
+]]
+
+local ildb = advtrains.interlocking.db
+
+
+local function itexist(tbl, com)
+ for _,item in ipairs(tbl) do
+ if (item==com) then
+ return true
+ end
+ end
+ return false
+end
+local function itkexist(tbl, ikey, com)
+ for _,item in ipairs(tbl) do
+ if item[ikey] == com then
+ return true
+ end
+ end
+ return false
+end
+
+local function itremove(tbl, com)
+ local i=1
+ while i <= #tbl do
+ if tbl[i] == com then
+ table.remove(tbl, i)
+ else
+ i = i + 1
+ end
+ end
+end
+local function itkremove(tbl, ikey, com)
+ local i=1
+ while i <= #tbl do
+ if tbl[i][ikey] == com then
+ table.remove(tbl, i)
+ else
+ i = i + 1
+ end
+ end
+end
+
+local function setsection(tid, train, ts_id, ts, origin)
+ -- train
+ if not train.il_sections then train.il_sections = {} end
+ if not itkexist(train.il_sections, "ts_id", ts_id) then
+ table.insert(train.il_sections, {ts_id = ts_id, origin = origin})
+ end
+
+ -- ts
+ if not ts.trains then ts.trains = {} end
+ if not itexist(ts.trains, tid) then
+ table.insert(ts.trains, tid)
+ end
+
+end
+
+local function freesection(tid, train, ts_id, ts)
+ -- train
+ if not train.il_sections then train.il_sections = {} end
+ itkremove(train.il_sections, "ts_id", ts_id)
+
+ -- ts
+ if not ts.trains then ts.trains = {} end
+ itremove(ts.trains, tid)
+
+end
+
+
+-- This is regular operation
+-- The train is on a track and drives back and forth
+
+-- 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
+ end
+ end
+end)
+
+
+-- this time, of course, only clear the backside (cp connid)
+advtrains.tnc_register_on_leave(function(pos, id, train, index)
+ local tcb = ildb.get_tcb(pos)
+ if tcb and train.path_cp[index] then
+ local connid = train.path_cp[index]
+ local ts = tcb[connid].ts_id and ildb.get_ts(tcb[connid].ts_id)
+ if ts then
+ freesection(id, train, tcb[connid].ts_id, ts)
+ end
+ end
+end)
+
+-- those callbacks are needed to account for created and removed trains (also regarding coupling)
+
+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)
+ if ts_id then
+ local ts = ildb.get_ts(ts_id)
+ if ts then
+ setsection(id, train, ts_id, ts, origin)
+ else
+ atwarn("ILDB corruption: TCB",origin," has invalid TS reference")
+ end
+ elseif ts_id==nil then
+ atwarn("Train",id,": Unable to determine whether to block a track section!")
+ else
+ atdebug("Train",id,": Outside of interlocked area!")
+ end
+end)
+
+advtrains.te_register_on_remove(function(id, train)
+ if train.il_sections then
+ for idx, item in ipairs(train.il_sections) do
+
+ local ts = item.ts_id and ildb.get_ts(item.ts_id)
+
+ if ts and ts.trains then
+ itremove(ts.trains, id)
+ end
+ end
+ train.il_sections = nil
+ end
+end)