1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
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,
}
|