aboutsummaryrefslogtreecommitdiff
path: root/advtrains_interlocking/distant.lua
diff options
context:
space:
mode:
Diffstat (limited to 'advtrains_interlocking/distant.lua')
-rw-r--r--advtrains_interlocking/distant.lua137
1 files changed, 137 insertions, 0 deletions
diff --git a/advtrains_interlocking/distant.lua b/advtrains_interlocking/distant.lua
new file mode 100644
index 0000000..ffa9e08
--- /dev/null
+++ b/advtrains_interlocking/distant.lua
@@ -0,0 +1,137 @@
+local db_distant = {}
+local db_distant_of = {}
+
+local A = advtrains.interlocking.aspects
+local pts = advtrains.encode_pos
+local stp = advtrains.decode_pos
+
+local function db_load(x)
+ if type(x) ~= "table" then
+ return
+ end
+ db_distant = x.distant
+ db_distant_of = x.distant_of
+end
+
+local function db_save()
+ return {
+ distant = db_distant,
+ distant_of = db_distant_of,
+ }
+end
+
+local update_signal, update_main, update_dst
+
+local function unassign_dst(dst, force)
+ local pts_dst = pts(dst)
+ local main = db_distant_of[pts_dst]
+ db_distant_of[pts_dst] = nil
+ if main then
+ local pts_main = main[1]
+ local t = db_distant[pts_main]
+ if t then
+ t[pts_dst] = nil
+ end
+ end
+ if not force then
+ update_dst(dst)
+ end
+end
+
+local function unassign_main(main, force)
+ local pts_main = pts(main)
+ local t = db_distant[pts_main]
+ if not t then
+ return
+ end
+ for pts_dst in pairs(t) do
+ local realmain = db_distant_of[pts_dst]
+ if realmain and realmain[1] == pts_main then
+ db_distant_of[pts_dst] = nil
+ if not force then
+ local dst = stp(pts_dst)
+ update_dst(dst)
+ end
+ end
+ end
+ db_distant[pts_main] = nil
+end
+
+local function unassign_all(pos, force)
+ unassign_main(pos)
+ unassign_dst(pos, force)
+end
+
+local function assign(main, dst, by)
+ local pts_main = pts(main)
+ local pts_dst = pts(dst)
+ local t = db_distant[pts_main]
+ if not t then
+ t = {}
+ db_distant[pts_main] = t
+ end
+ if not by then
+ by = "manual"
+ end
+ unassign_dst(dst, true)
+ t[pts_dst] = by
+ db_distant_of[pts_dst] = {pts_main, by}
+ update_dst(dst)
+end
+
+local function pre_occupy(dst, by)
+ local pts_dst = pts(dst)
+ unassign_dst(dst)
+ db_distant_of[pts_dst] = {nil, by}
+end
+
+local function get_distant(main)
+ local pts_main = pts(main)
+ return db_distant[pts_main] or {}
+end
+
+local function get_main(dst)
+ local pts_dst = pts(dst)
+ local main = db_distant_of[pts_dst]
+ if not main then
+ return
+ end
+ if main[1] then
+ return stp(main[1]), unpack(main, 2)
+ else
+ return unpack(main)
+ end
+end
+
+update_main = function(main)
+ local pts_main = pts(main)
+ local t = get_distant(main)
+ for pts_dst in pairs(t) do
+ local dst = stp(pts_dst)
+ advtrains.interlocking.signal_readjust_aspect(dst)
+ end
+end
+
+update_dst = function(dst)
+ advtrains.interlocking.signal_readjust_aspect(dst)
+end
+
+update_signal = function(pos)
+ update_main(pos)
+ update_dst(pos)
+end
+
+advtrains.distant = {
+ load = db_load,
+ save = db_save,
+ assign = assign,
+ unassign_dst = unassign_dst,
+ unassign_main = unassign_main,
+ unassign_all = unassign_all,
+ get_distant = get_distant,
+ get_dst = get_distant,
+ get_main = get_main,
+ update_main = update_main,
+ update_dst = update_dst,
+ update_signal = update_signal,
+}