diff options
author | orwell <orwell@bleipb.de> | 2024-12-10 23:07:06 +0100 |
---|---|---|
committer | orwell <orwell@bleipb.de> | 2024-12-10 23:07:06 +0100 |
commit | 67ace4bde0edd0d40c63168758ac4b4878135946 (patch) | |
tree | 1b1d266024532334fe9db483b923e511c652d10a /advtrains_interlocking/smartroute.lua | |
parent | 361970cdaf734828397cf22fa1db6ffc885eba10 (diff) | |
download | advtrains-67ace4bde0edd0d40c63168758ac4b4878135946.tar.gz advtrains-67ace4bde0edd0d40c63168758ac4b4878135946.tar.bz2 advtrains-67ace4bde0edd0d40c63168758ac4b4878135946.zip |
Smartroute: Never replace already existing intact routes, change colorcoding, other fixes
Diffstat (limited to 'advtrains_interlocking/smartroute.lua')
-rw-r--r-- | advtrains_interlocking/smartroute.lua | 118 |
1 files changed, 69 insertions, 49 deletions
diff --git a/advtrains_interlocking/smartroute.lua b/advtrains_interlocking/smartroute.lua index 770c379..07cdf46 100644 --- a/advtrains_interlocking/smartroute.lua +++ b/advtrains_interlocking/smartroute.lua @@ -6,6 +6,23 @@ local ildb = atil.db local sr = {} +-- Start the SmartRoute process. This searches for routes and tries to match them with existing routes, showing them in a form +function sr.start(pname, sigd) + -- is start signal a shunt signal? This becomes default setting for searching_shunt + local is_startsignal_shunt = false + local tcbs = ildb.get_tcbs(sigd) + if tcbs.signal then + local ndef = advtrains.ndb.get_ndef(tcbs.signal) + if ndef and ndef.advtrains then + if ndef.advtrains.route_role == "shunt" then + is_startsignal_shunt = true + end + end + end + sr.propose_next(pname, sigd, 10, is_startsignal_shunt) -- TODO set tscnt_limit to 2 initially and then increase it. Do this when form is implemented +end + + local function otherside(s) if s==1 then return 2 else return 1 end end @@ -13,8 +30,8 @@ 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) - --atdebug("Recursively restarting at ",s_pos, s_connid, "limit left", scan_limit) +local function recursively_find_routes(s_pos, s_connid, searching_shunt, tcbseq, mark_pos, result_table, scan_limit, tscnt_limit) + 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() pos, connid, bconnid = ti:next_track()-- step once to get ahead of previous turnout @@ -25,7 +42,7 @@ local function recursively_find_routes(s_pos, s_connid, searching_shunt, tcbseq, mark_pos[pts] = true local node = advtrains.ndb.get_node_or_nil(pos) - atdebug("(SmartRoute) Walk ",pos, "nodename", node.name, "entering at conn",bconnid) + --atdebug("(SmartRoute) Walk ",pos, "nodename", node.name, "entering at conn",bconnid) local ndef = minetest.registered_nodes[node.name] if ndef.advtrains and ndef.advtrains.node_state_map then -- Stop, this is a switchable node. Find out which conns we can go at @@ -33,7 +50,9 @@ local function recursively_find_routes(s_pos, s_connid, searching_shunt, tcbseq, local out_conns = ildb.get_possible_out_connids(node.name, bconnid) for oconnid, state in pairs(out_conns) do --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) + recursively_find_routes(pos, oconnid, searching_shunt, + table.copy(tcbseq), table.copy(mark_pos), + result_table, ti.limit, tscnt_limit) end return end @@ -68,12 +87,18 @@ local function recursively_find_routes(s_pos, s_connid, searching_shunt, tcbseq, end end end + -- decrease tscnt + tscnt_limit = tscnt_limit - 1 + atdebug("(SmartRoute) Remaining TS Count:",tscnt_limit) + if tscnt_limit <= 0 then + break + end end -- Go forward last_pos = pos pos, connid, bconnid = ti:next_track() until not pos -- this stops the loop when either the track end is reached or the limit is hit - --atdebug("recursively_find_routes: Reached track end or limit at", last_pos, ". This path is not saved, returning") + atdebug("(SmartRoute) Reached track end or limit at", last_pos, ". This path is not saved, returning") end local function build_route_from_foundroute(froute, name) @@ -91,59 +116,54 @@ end -- Maximum scan length for track iterator local TS_MAX_SCAN = 1000 -function sr.init(pname, sigd) - -- is start signal a shunt signal? - local is_startsignal_shunt = false +function sr.rescan(pname, sigd, tscnt_limit, searching_shunt) + local result_table = {} + recursively_find_routes(sigd.p, sigd.s, is_startsignal_shunt, {}, {}, result_table, TS_MAX_SCAN, tscnt_limit) + return result_table +end + +-- Propose to pname the smartroute actions in a form, with the current settings as passed to this function +function sr.propose_next(pname, sigd, tscnt_limit, searching_shunt) local tcbs = ildb.get_tcbs(sigd) - if tcbs.signal then - local ndef = advtrains.ndb.get_ndef(tcbs.signal) - if ndef and ndef.advtrains then - if ndef.advtrains.route_role == "shunt" then - is_startsignal_shunt = true - end + if not tcbs or not tcbs.routes then + minetest.chat_send_player(pname, "Smartroute: TCBS or routes don't exist here!") + return + end + -- Step 1: search for routes using the current settings + local found_routes = sr.rescan(pname, sigd, tscnt_limit, searching_shunt) + -- 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 + local valid = advtrains.interlocking.check_route_valid(route, sigd) + local endpoint = route[#route].next -- 'next' field of the last route segment (the segment with index==len) + if valid and endpoint then + local endstr = advtrains.interlocking.sigd_to_string(endpoint) + atdebug("(Smartroute) Find existing endpoint:",route.name,"ends at",endstr) + ex_endpts[endstr] = route.name + else + atdebug("(Smartroute) Find existing endpoint:",route.name," not considered, endpoint",endpoint,"valid",valid) end end - local result_table = {} - recursively_find_routes(sigd.p, sigd.s, is_startsignal_shunt, {}, {}, result_table, TS_MAX_SCAN) - - atdebug("Smartroute search finished:",result_table) - - -- Short-circuit logic right now for testing - -- go through and delete all routes that are autogenerated - local i = 1 - while i<=#tcbs.routes do - if tcbs.routes[i].smartroute_generated then - table.remove(tcbs.routes, i) + local new_frte = {} + for _,froute in ipairs(found_routes) do + local endpoint = froute.tcbseq[#froute.tcbseq] + local endstr = advtrains.interlocking.sigd_to_string(endpoint) + if not ex_endpts[endstr] then + new_frte[#new_frte+1] = froute else - i=i+1 + atdebug("(Smartroute) Throwing away",froute.name,"because endpoint",endstr,"already reached by route",ex_endpts[endstr]) end end - -- just plainly create routes! - for idx, froute in ipairs(result_table) do + + -- All remaining routes will be shown to user now. + -- TODO: show a form. Right now still shortcircuit + local sel_rte = #tcbs.routes+1 + for idx, froute in ipairs(new_frte) do tcbs.routes[#tcbs.routes+1] = build_route_from_foundroute(froute) end - atwarn("Smartroute done!") + atdebug("Smartroute done!") + advtrains.interlocking.show_signalling_form(sigd, pname, sel_rte) end - ---[[ - player1 = { - origin = <sigd> - found_routes = { - { tcbseq = {<sigd1>, <sigd2>, <end_sigd>}, mark_pos = { table with keys being encoded_pos of rails constituting route }, to_end_of_track = false, shunt_route = false } - } - } -]]-- -local player_smartroute = {} - -minetest.register_on_punchnode(function(pos, node, player, pointed_thing) - local pname = player:get_player_name() - if not minetest.check_player_privs(pname, "interlocking") then - return - end - -- TODO -end) - - advtrains.interlocking.smartroute = sr |