aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--advtrains_interlocking/database.lua18
-rw-r--r--advtrains_interlocking/route_ui.lua13
-rw-r--r--advtrains_interlocking/routesetting.lua10
-rw-r--r--advtrains_interlocking/smartroute.lua23
-rwxr-xr-xadvtrains_interlocking/tcb_ts_ui.lua10
-rw-r--r--advtrains_interlocking/tool.lua16
6 files changed, 69 insertions, 21 deletions
diff --git a/advtrains_interlocking/database.lua b/advtrains_interlocking/database.lua
index 3104a20..f84f60b 100644
--- a/advtrains_interlocking/database.lua
+++ b/advtrains_interlocking/database.lua
@@ -351,7 +351,7 @@ end
-- Returns:
-- ts_id - the track section that was found
-- nil - No track section exists
-function ildb.check_and_repair_ts_at_pos(pos, tcb_connid, notify_pname)
+function ildb.check_and_repair_ts_at_pos(pos, tcb_connid, notify_pname, force_create)
--atdebug("check_and_repair_ts_at_pos", pos, tcb_connid)
-- check prereqs
if ildb.get_tcb(pos) then
@@ -378,7 +378,7 @@ function ildb.check_and_repair_ts_at_pos(pos, tcb_connid, notify_pname)
-- inconsistency is found, repair it
--atdebug("check_and_repair_ts_at_pos: Inconsistency is found!")
tsrepair_notify(notify_pname, "Track section inconsistent here, repairing...")
- return ildb.repair_ts_merge_all(all_tcbs, false, notify_pname)
+ return ildb.repair_ts_merge_all(all_tcbs, force_create, notify_pname)
-- Step2 check is no longer necessary since we just created that new section
end
end
@@ -386,9 +386,13 @@ function ildb.check_and_repair_ts_at_pos(pos, tcb_connid, notify_pname)
-- only one found (it is either nil or a ts id)
--atdebug("check_and_repair_ts_at_pos: TS consistent id=",ts_id,"")
if not ts_id then
- tsrepair_notify(notify_pname, "No track section found here.")
- return
- -- All TCBs agreed that there is no section here.
+ if force_create and next(all_tcbs) then --ensure at least one tcb is in list
+ return ildb.repair_ts_merge_all(all_tcbs, force_create, notify_pname)
+ else
+ --tsrepair_notify(notify_pname, "No track section found here.")
+ return nil
+ -- All TCBs agreed that there is no section here
+ end
end
local ts = ildb.get_ts(ts_id)
@@ -403,9 +407,9 @@ function ildb.check_and_repair_ts_at_pos(pos, tcb_connid, notify_pname)
if #ts.tc_breaks ~= #all_tcbs then
--atdebug("check_and_repair_ts_at_pos: Partition is found!")
tsrepair_notify(notify_pname, "Track section partition found, repairing...")
- return ildb.repair_ts_merge_all(all_tcbs, false, notify_pname)
+ return ildb.repair_ts_merge_all(all_tcbs, force_create, notify_pname)
end
- tsrepair_notify(notify_pname, "Found section", ts.name or ts_id, "here.")
+ --tsrepair_notify(notify_pname, "Found section", ts.name or ts_id, "here.")
return ts_id
end
diff --git a/advtrains_interlocking/route_ui.lua b/advtrains_interlocking/route_ui.lua
index b75f9d7..7dddc6e 100644
--- a/advtrains_interlocking/route_ui.lua
+++ b/advtrains_interlocking/route_ui.lua
@@ -75,8 +75,17 @@ function atil.show_route_edit_form(pname, sigd, routeid, sel_rpartidx)
end
end
end
+ -- sanity check, is section at next the same as the current?
+ local nvar = c_rseg.next
+ if nvar then
+ local re_tcbs = ildb.get_tcbs({p = nvar.p, s = (nvar.s==1) and 2 or 1})
+ if not re_tcbs or not re_tcbs.ts_id or re_tcbs.ts_id~=c_ts_id then
+ itab(i, "-!- At "..sigd_to_string(c_sigd)..".Section Start and End do not match!", "err", nil)
+ break
+ end
+ end
-- advance
- c_sigd = c_rseg.next
+ c_sigd = nvar
i = i + 1
end
if c_sigd then
@@ -135,6 +144,8 @@ function atil.show_route_edit_form(pname, sigd, routeid, sel_rpartidx)
-- checkbox for call-on
form = form..string.format("checkbox[4.5,4.0;se_callon;Call-on (section may be occupied);%s]", rseg.call_on)
end
+ elseif sel_rpart and sel_rpart.err then
+ form = form.."textarea[4.5,2.5;4,4;errorta;Error:;"..tab[sel_rpartidx].."]"
else
form = form..F.label(4.5, 2, "<< Select a route part to edit options")
end
diff --git a/advtrains_interlocking/routesetting.lua b/advtrains_interlocking/routesetting.lua
index 95ca63c..15c42aa 100644
--- a/advtrains_interlocking/routesetting.lua
+++ b/advtrains_interlocking/routesetting.lua
@@ -124,9 +124,17 @@ function ilrs.set_route(signal, route, try)
return false, "No passive component at "..minetest.pos_to_string(pos)..". Please update track section or reconfigure route!"
end
end
+ -- sanity check, is section at next the same as the current?
+ local nvar = c_rseg.next
+ if nvar then
+ local re_tcbs = ildb.get_tcbs({p = nvar.p, s = (nvar.s==1) and 2 or 1})
+ if not re_tcbs or not re_tcbs.ts_id or re_tcbs.ts_id~=c_ts_id then
+ if not try then atwarn("Encountered inconsistent ts (front~=back) while a real run of routesetting routine, at position",pts,"while setting route",rtename,"of",signal) end
+ return false, "TCB at "..minetest.pos_to_string(nvar.p).." has different section than previous TCB. Please update track section or reconfigure route!"
+ end
+ end
-- reserve ts and write locks
if not try then
- local nvar = c_rseg.next
if not route[i+1] then
-- We shouldn't use the "next" value of the final route segment, because this can lead to accidental route-cancelling of already set routes from another signal.
nvar = nil
diff --git a/advtrains_interlocking/smartroute.lua b/advtrains_interlocking/smartroute.lua
index 07cdf46..a26f2d1 100644
--- a/advtrains_interlocking/smartroute.lua
+++ b/advtrains_interlocking/smartroute.lua
@@ -30,7 +30,7 @@ end
--route search implementation
-- Note this is similar to recursively_find_routes in database.lua, there used for the rscache
-local function recursively_find_routes(s_pos, s_connid, searching_shunt, tcbseq, mark_pos, result_table, scan_limit, tscnt_limit)
+local function recursively_find_routes(s_pos, s_connid, searching_shunt, tcbseq, mark_pos, result_table, scan_limit, tscnt_limit, cur_ts_id, notify_pname)
atdebug("(SmartRoute) Recursively restarting at ",s_pos, s_connid, "limit left", scan_limit,"tscnt",tscnt_limit)
local ti = advtrains.get_track_iterator(s_pos, s_connid, scan_limit, false)
local pos, connid, bconnid = ti:next_branch()
@@ -52,7 +52,7 @@ local function recursively_find_routes(s_pos, s_connid, searching_shunt, tcbseq,
--atdebug("Going in direction",oconnid,"state",state)
recursively_find_routes(pos, oconnid, searching_shunt,
table.copy(tcbseq), table.copy(mark_pos),
- result_table, ti.limit, tscnt_limit)
+ result_table, ti.limit, tscnt_limit, cur_ts_id, notify_pname)
end
return
end
@@ -62,6 +62,13 @@ local function recursively_find_routes(s_pos, s_connid, searching_shunt, tcbseq,
local fsigd = { p = pos, s = connid }
atdebug("(SmartRoute) Encounter TCB ",fsigd)
tcbseq[#tcbseq+1] = fsigd
+ -- TS validity check: ensure that the TS the back connid refers to is the same as the one at the start
+ local re_ts_id = tcb[bconnid].ts_id
+ if re_ts_id ~= cur_ts_id then
+ atwarn("(SmartRoute) Found TS Inconsistency: entered in section",cur_ts_id,"but TCB backref is section",re_ts_id)
+ ildb.check_and_repair_ts_at_pos(pos, bconnid, notify_pname)
+ -- nothing needs to be updated on our side
+ end
-- check if this is a possible route endpoint
local tcbs = tcb[connid]
if tcbs.signal then
@@ -93,6 +100,9 @@ local function recursively_find_routes(s_pos, s_connid, searching_shunt, tcbseq,
if tscnt_limit <= 0 then
break
end
+ -- update the cur_ts_id
+ cur_ts_id = tcb[connid].ts_id
+ atdebug("(SmartRoute) Now in section:",cur_ts_id)
end
-- Go forward
last_pos = pos
@@ -116,9 +126,9 @@ end
-- Maximum scan length for track iterator
local TS_MAX_SCAN = 1000
-function sr.rescan(pname, sigd, tscnt_limit, searching_shunt)
+function sr.rescan(pname, sigd, tcbs, tscnt_limit, searching_shunt, pname)
local result_table = {}
- recursively_find_routes(sigd.p, sigd.s, is_startsignal_shunt, {}, {}, result_table, TS_MAX_SCAN, tscnt_limit)
+ recursively_find_routes(sigd.p, sigd.s, searching_shunt, {}, {}, result_table, TS_MAX_SCAN, tscnt_limit, tcbs.ts_id, pname)
return result_table
end
@@ -128,9 +138,12 @@ function sr.propose_next(pname, sigd, tscnt_limit, searching_shunt)
if not tcbs or not tcbs.routes then
minetest.chat_send_player(pname, "Smartroute: TCBS or routes don't exist here!")
return
+ elseif not tcbs.ts_id then
+ minetest.chat_send_player(pname, "Smartroute: No track section directly ahead!")
+ return
end
-- Step 1: search for routes using the current settings
- local found_routes = sr.rescan(pname, sigd, tscnt_limit, searching_shunt)
+ local found_routes = sr.rescan(pname, sigd, tcbs, tscnt_limit, searching_shunt, pname)
-- Step 2: remove routes for endpoints for which routes already exist
local ex_endpts = {} -- key = sigd_to_string
for rtid, route in ipairs(tcbs.routes) do
diff --git a/advtrains_interlocking/tcb_ts_ui.lua b/advtrains_interlocking/tcb_ts_ui.lua
index abcdf61..4f755af 100755
--- a/advtrains_interlocking/tcb_ts_ui.lua
+++ b/advtrains_interlocking/tcb_ts_ui.lua
@@ -776,8 +776,16 @@ function advtrains.interlocking.check_route_valid(route, sigd)
end
end
end
+ -- sanity check, is section at next the same as the current?
+ local nvar = c_rseg.next
+ if nvar then
+ local re_tcbs = ildb.get_tcbs({p = nvar.p, s = (nvar.s==1) and 2 or 1})
+ if not re_tcbs or not re_tcbs.ts_id or re_tcbs.ts_id~=c_ts_id then
+ return false, "TCB at "..minetest.pos_to_string(nvar.p).." has different section than previous TCB."
+ end
+ end
-- advance
- c_sigd = c_rseg.next
+ c_sigd = nvar
i = i + 1
end
-- check end TCB
diff --git a/advtrains_interlocking/tool.lua b/advtrains_interlocking/tool.lua
index 4ebc56c..560e129 100644
--- a/advtrains_interlocking/tool.lua
+++ b/advtrains_interlocking/tool.lua
@@ -3,7 +3,7 @@
local ilrs = advtrains.interlocking.route
-local function node_right_click(pos, pname)
+local function node_right_click(pos, pname, player)
if advtrains.is_passive(pos) then
local form = "size[7,5]label[0.5,0.5;Route lock inspector]"
local pts = advtrains.encode_pos(pos)
@@ -33,7 +33,7 @@ local function node_right_click(pos, pname)
return
end
- local ts_id = advtrains.interlocking.db.check_and_repair_ts_at_pos(pos)
+ local ts_id = advtrains.interlocking.db.check_and_repair_ts_at_pos(pos, nil, pname)
if ts_id then
advtrains.interlocking.show_ts_form(ts_id, pname)
else
@@ -41,7 +41,7 @@ local function node_right_click(pos, pname)
end
end
-local function node_left_click(pos, pname)
+local function node_left_click(pos, pname, player)
local node_ok, conns, rail_y=advtrains.get_rail_info_at(pos)
if not node_ok then
minetest.chat_send_player(pname, "Node is not a track!")
@@ -52,8 +52,12 @@ local function node_left_click(pos, pname)
advtrains.interlocking.show_tcb_marker(pos)
return
end
+
+ -- create track section if aux1 button down
+ local pc = player:get_player_control()
+ local force_create = pc.aux1
- local ts_id = advtrains.interlocking.db.check_and_repair_ts_at_pos(pos, nil, pname)
+ local ts_id = advtrains.interlocking.db.check_and_repair_ts_at_pos(pos, nil, pname, force_create)
if ts_id then
advtrains.interlocking.db.update_rs_cache(ts_id)
advtrains.interlocking.highlight_track_section(pos)
@@ -80,7 +84,7 @@ minetest.register_craftitem("advtrains_interlocking:tool",{
end
if pointed_thing.type=="node" then
local pos=pointed_thing.under
- node_right_click(pos, pname)
+ node_right_click(pos, pname, player)
end
end,
on_use = function(itemstack, player, pointed_thing)
@@ -94,7 +98,7 @@ minetest.register_craftitem("advtrains_interlocking:tool",{
end
if pointed_thing.type=="node" then
local pos=pointed_thing.under
- node_left_click(pos, pname)
+ node_left_click(pos, pname, player)
end
end
})