aboutsummaryrefslogtreecommitdiff
path: root/advtrains_interlocking/route_ui.lua
diff options
context:
space:
mode:
authororwell96 <orwell@bleipb.de>2019-01-09 18:03:40 +0100
committerorwell96 <orwell@bleipb.de>2019-01-09 18:03:40 +0100
commita751d1da9c57a40a0df4e8793a1cc46cb7985e12 (patch)
tree2a5a24eb61256e182645a996ecea1496c620ac83 /advtrains_interlocking/route_ui.lua
parentc3c96274be0c4beeef62a21f226e830d1d72675a (diff)
downloadadvtrains-a751d1da9c57a40a0df4e8793a1cc46cb7985e12.tar.gz
advtrains-a751d1da9c57a40a0df4e8793a1cc46cb7985e12.tar.bz2
advtrains-a751d1da9c57a40a0df4e8793a1cc46cb7985e12.zip
Add Automatic Routesetting UI
Settings have no effect so far
Diffstat (limited to 'advtrains_interlocking/route_ui.lua')
-rw-r--r--advtrains_interlocking/route_ui.lua196
1 files changed, 196 insertions, 0 deletions
diff --git a/advtrains_interlocking/route_ui.lua b/advtrains_interlocking/route_ui.lua
new file mode 100644
index 0000000..245b082
--- /dev/null
+++ b/advtrains_interlocking/route_ui.lua
@@ -0,0 +1,196 @@
+-- route_ui.lua
+-- User interface for showing and editing routes
+
+local atil = advtrains.interlocking
+local ildb = atil.db
+
+-- TODO duplicate
+local lntrans = { "A", "B" }
+local function sigd_to_string(sigd)
+ return minetest.pos_to_string(sigd.p).." / "..lntrans[sigd.s]
+end
+
+-- The ARS data are saved in a table format, but are entered in text format. Utility functions to transform between both.
+local function ars_to_text(arstab)
+ if not arstab then
+ return ""
+ end
+
+ local txt = {}
+
+ for i, arsent in ipairs(arstab) do
+ if arsent.ln then
+ txt[#txt+1] = "LN "..arsent.ln
+ elseif arsent.rc then
+ txt[#txt+1] = "RC "..arsent.rc
+ elseif arsent.c then
+ txt[#txt+1] = "#"..arsent.c
+ end
+ end
+
+ if arstab.default then
+ return "*\n" .. table.concat(txt, "\n")
+ end
+ return table.concat(txt, "\n")
+end
+
+local function text_to_ars(t)
+ if t=="" then
+ return nil
+ elseif t=="*" then
+ return {default=true}
+ end
+ local arstab = {}
+ for line in string.gmatch(t, "[^\r\n]+") do
+ if line=="*" then
+ arstab.default = true
+ else
+ local c, v = string.match(line, "^(..)%s(.*)$")
+ if c and v then
+ local tt=string.upper(c)
+ if tt=="LN" then
+ arstab[#arstab+1] = {ln=v}
+ elseif tt=="RC" then
+ arstab[#arstab+1] = {rc=v}
+ end
+ else
+ local ct = string.match(line, "^#(.*)$")
+ if ct then arstab[#arstab+1] = {c = ct} end
+ end
+ end
+ end
+ return arstab
+end
+
+
+
+function atil.show_route_edit_form(pname, sigd, routeid)
+
+ if not minetest.check_player_privs(pname, {train_operator=true, interlocking=true}) then
+ minetest.chat_send_player(pname, "Insufficient privileges to use this!")
+ return
+ end
+
+ local tcbs = atil.db.get_tcbs(sigd)
+ if not tcbs then return end
+ local route = tcbs.routes[routeid]
+ if not route then return end
+
+ local form = "size[9,10]label[0.5,0.2;Route overview]"
+ form = form.."field[0.8,1.2;5.2,1;name;Route name;"..route.name.."]"
+ form = form.."button[5.5,0.9;1,1;setname;Set]"
+
+ -- construct textlist for route information
+ local tab = {}
+ local function itab(t)
+ tab[#tab+1] = string.gsub(t, ",", " ")
+ end
+ itab("TCB "..sigd_to_string(sigd).." ("..tcbs.signal_name..") Route #"..routeid)
+
+ -- this code is partially copy-pasted from routesetting.lua
+ -- we start at the tc designated by signal
+ local c_sigd = sigd
+ local i = 1
+ local c_tcbs, c_ts_id, c_ts, c_rseg, c_lckp
+ while c_sigd and i<=#route do
+ c_tcbs = ildb.get_tcbs(c_sigd)
+ c_ts_id = c_tcbs.ts_id
+ if not c_ts_id then
+ itab("-!- No track section adjacent to "..sigd_to_string(c_sigd)..". Please reconfigure route!")
+ end
+ c_ts = ildb.get_ts(c_ts_id)
+
+ c_rseg = route[i]
+ c_lckp = {}
+
+ itab(""..i.." Entry "..sigd_to_string(c_sigd).." -> Sec. "..c_ts.name.." -> Exit "..(c_rseg.next and sigd_to_string(c_rseg.next) or "END"))
+
+ for pts, state in pairs(c_rseg.locks) do
+
+ local pos = minetest.string_to_pos(pts)
+ itab(" Lock: "..pts.." -> "..state)
+ if not advtrains.is_passive(pos) then
+ itab("-!- No passive component at "..pts..". Please reconfigure route!")
+ end
+ end
+ -- advance
+ c_sigd = c_rseg.next
+ i = i + 1
+ end
+ if c_sigd then
+ local e_tcbs = ildb.get_tcbs(c_sigd)
+ itab("Route end: "..sigd_to_string(c_sigd).." ("..(e_tcbs.signal_name or "-")..")")
+ else
+ itab("Route ends on dead-end")
+ end
+
+ form = form.."textlist[0.5,2;7,4;rtelog;"..table.concat(tab, ",").."]"
+
+ form = form.."button[0.5,6;2,1;back;<<< Back to signal]"
+ form = form.."button[3.5,6;2,1;aspect;Signal Aspect]"
+ form = form.."button[5.5,6;2,1;delete;Delete Route]"
+
+ atdebug(route.ars)
+ form = form.."textarea[1,7.3;5.2,3;ars;ARS Rule List;"..ars_to_text(route.ars).."]"
+ form = form.."button[6,7.7;1,1;savears;Save]"
+
+ minetest.show_formspec(pname, "at_il_routeedit_"..minetest.pos_to_string(sigd.p).."_"..sigd.s.."_"..routeid, form)
+
+end
+
+
+minetest.register_on_player_receive_fields(function(player, formname, fields)
+ local pname = player:get_player_name()
+ if not minetest.check_player_privs(pname, {train_operator=true, interlocking=true}) then
+ return
+ end
+
+ local pts, connids, routeids = string.match(formname, "^at_il_routeedit_([^_]+)_(%d)_(%d+)$")
+ local pos, connid, routeid
+ if pts then
+ pos = minetest.string_to_pos(pts)
+ connid = tonumber(connids)
+ routeid = tonumber(routeids)
+ if not connid or connid<1 or connid>2 then return end
+ if not routeid then return end
+ end
+ if pos and connid and routeid and not fields.quit then
+ local sigd = {p=pos, s=connid}
+ local tcbs = ildb.get_tcbs(sigd)
+ if not tcbs then return end
+ local route = tcbs.routes[routeid]
+ if not route then return end
+
+ if fields.setname and fields.name then
+ route.name = fields.name
+ end
+
+ if fields.aspect then
+ local suppasp = advtrains.interlocking.signal_get_supported_aspects(tcbs.signal)
+
+ local callback = function(pname, asp)
+ route.aspect = asp
+ advtrains.interlocking.show_route_edit_form(pname, sigd, routeid)
+ end
+
+ advtrains.interlocking.show_signal_aspect_selector(pname, suppasp, route.name, callback, rte.aspect)
+ return
+ end
+ if fields.delete then
+ -- if something set the route in the meantime, make sure this doesn't break.
+ atil.route.update_route(sigd, tcbs, nil, true)
+ table.remove(tcbs.routes, routeid)
+ advtrains.interlocking.show_signalling_form(sigd, pname)
+ end
+
+ if fields.ars and fields.savears then
+ route.ars = text_to_ars(fields.ars)
+ atdebug(route.ars)
+ end
+
+ if fields.back then
+ advtrains.interlocking.show_signalling_form(sigd, pname)
+ end
+
+ end
+end)