aboutsummaryrefslogtreecommitdiff
path: root/advtrains_interlocking/signal_aspects.lua
blob: 5c4948bd4d9b5aa25131b63d626865b94e9b3d2a (plain)
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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
local type2defs = {}

local function register_type2(def)
	local t = {type = 2}
	local name = def.name
	if type2defs[name] then
		return error("Name " .. name .. " already used")
	elseif type(name) ~= "string" then
		return error("Name is not a string")
	end
	t.name = name

	local label = def.label or name
	if type(label) ~= "string" then
		return error("Label is not a string")
	end
	t.label = label

	local mainasps = {}
	for idx, asp in ipairs(def.main) do
		local t = {}
		local name = asp.name
		if type(name) ~= "string" then
			return error("Aspect name is not a string")
		end
		t.name = name

		local label = asp.label or name
		if type(label) ~= "string" then
			return error("Aspect label is not a string")
		end
		t.label = label

		t.main = asp.main
		t.shunt = asp.shunt
		t.proceed_as_main = asp.proceed_as_main
		mainasps[idx] = t
		mainasps[name] = idx
	end
	t.main = mainasps

	type2defs[name] = t
end

local function get_type2_definition(name)
	return type2defs[name]
end

local function get_type2_danger(group)
	local def = type2defs[group]
	if not def then
		return nil
	end
	local main = def.main
	return main[#main]
end

local function get_type2_dst(group, name)
	local def = type2defs[group]
	if not def then
		return nil
	end
	local aspidx = name
	if type(name) ~= "number" then
		aspidx = def.main[name] or 1
	end
	return def.main[math.max(1, aspidx-1)].name
end

local function type2main_to_type1(name, asp)
	local def = type2defs[name]
	if not def then
		return nil
	end
	local aspidx
	if type(asp) == "number" then
		aspidx = asp
	else
		aspidx = def.main[asp] or 2
	end
	local asptbl = def.main[aspidx]
	if not asptbl then
		return nil
	end
	if type(asp) == "number" then
		asp = asptbl.name
	end
	local dst = def.main[math.min(#def.main, aspidx+1)].main

	local t = {
		main = asptbl.main,
		shunt = asptbl.shunt,
		proceed_as_main = asptbl.proceed_as_main,
		type2name = asp,
		type2group = name,
		dst = dst,
	}
	if aspidx > 1 and aspidx < #asptbl then
		t.dst = asptbl[aspidx+1].main
	end
	return t
end

local function type1_to_type2main(asp, group)
	local def = type2defs[group]
	if not def then
		return nil
	end
	if group == asp.type2group and def.main[asp.type2name] then
		return asp.type2name
	end
	local t_main = def.main
	local idx
	if not asp.main or asp.main == -1 then
		idx = 1
	elseif asp.main == 0 then
		idx = #t_main
	else
		idx = math.max(#t_main-1, 1)
	end
	return t_main[idx].name
end

local function equalp(asp1, asp2)
	if asp1 == asp2 then -- same reference
		return true
	elseif asp1.type2group and asp1.type2group == asp2.type2group then -- type2 with the same group
		return asp1.type2name == asp2.type2name
	else
		for _, k in pairs {"main", "shunt", "dst"} do
			if asp1[k] ~= asp2[k] then
				return false
			end
		end
	end
	return true
end

local function not_equalp(asp1, asp2)
	return not equalp(asp1, asp2)
end

return {
	register_type2 = register_type2,
	get_type2_definition = get_type2_definition,
	get_type2_dst = get_type2_dst,
	type2main_to_type1 = type2main_to_type1,
	type1_to_type2main = type1_to_type2main,
	equalp = equalp,
	not_equalp = not_equalp,
}