aboutsummaryrefslogtreecommitdiff
path: root/advtrains/speed.lua
blob: b77b22b43c26deb41996578fe04873695920ceac (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
--- Auxiliary functions for the reworked speed restriction system.
-- For this library, the speed limit may be represented using
--
-- * A non-negative number representing a speed limit in m/s
-- * `-1` or `nil`, which lifts the speed limit
--
-- The use of other values (in particular, `nan` and `inf`) may result in undefined behavior.
--
-- Please note the difference between the meaning of `nil` in this library and in signal aspect tables.

--- Check if `a` is more strict than `b`
-- @function lessp
-- @param a an object representing a speed limit
-- @param b an object representing a speed limit
local function s_lessp(a, b)
	if not a or a == -1 then
		return false
	elseif not b or b == -1 then
		return true
	else
		return a < b
	end
end

--- Check if `a` is less strict than `b`
-- @function greaterp
-- @param a an object representing a speed limit
-- @param b an object representing a speed limit
local function s_greaterp(a, b)
	return s_lessp(b, a)
end

--- Check if `a` is not more strict than `b`
-- @function not_lessp
-- @param a an object representing a speed limit
-- @param b an object representing a speed limit
local function s_not_lessp(a, b)
	return not s_lessp(a, b)
end

--- Check if `a` is not less strict than `b`
-- @function not_greaterp
-- @param a an object representing a speed limit
-- @param b an object representing a speed limit
local function s_not_greaterp(a, b)
	return not s_greaterp(a, b)
end

--- Check if `a` and `b` represent equivalent speed limits
-- @function equalp
-- @param a an object representing a speed limit
-- @param b an object representing a speed limit
local function s_equalp(a, b)
	return (a or -1) == (b or -1)
end

--- Check if `a` and `b` do not represent equivalent speed limits
-- @function not_equalp
-- @param a an object representing a speed limit
-- @param b an object representing a speed limit
local function s_not_equalp(a, b)
	return (a or -1) ~= (b or -1)
end

--- Returns the speed limit that is less strict
-- @function max
-- @param a an object representing a speed limit
-- @param b an object representing a speed limit
local function s_max(a, b)
	if s_lessp(a, b) then
		return b
	else
		return a
	end
end

--- Returns the speed limit that is more strict
-- @function min
-- @param a an object representing a speed limit
-- @param b an object representing a speed limit
local function s_min(a, b)
	if s_lessp(a, b) then
		return a
	else
		return b
	end
end

--- Returns the strictest speed limit in a table
-- @param tbl a table of speed limits
local function get_speed_restriction_from_table (tbl)
	local strictest = -1
	for _, v in pairs(tbl) do
		strictest = s_min(strictest, v)
	end
	if strictest == -1 then
		return nil
	end
	return strictest
end

--- Update a value in the speed limit table
-- @param tbl the `speed_restriction` field of a train table
-- @param rtype the type of speed limit
-- @param rval the speed limit of the given type
local function set_speed_restriction (tbl, rtype, rval)
	if rval then
		tbl[rtype or "main"] = rval
	end
	return tbl
end

--- Set the speed limit of a train
-- @function set_restriction
-- @param train the train object
-- @param rtype the type of speed limit
-- @param rval the speed limit of the given type
local function set_speed_restriction_for_train (train, rtype, rval)
	local t = train.speed_restrictions_t or {main = train.speed_restriction}
	train.speed_restrictions_t = set_speed_restriction(t, rtype, rval)
	train.speed_restriction = get_speed_restriction_from_table(t)
end

--- Set the speed limit of a train based on a signal aspect
-- @function merge_aspect
-- @param train the train object
-- @param asp the signal aspect table
local function merge_speed_restriction_from_aspect_to_train (train, asp)
	return set_speed_restriction_for_train(train, asp.type, asp.main)
end

return {
	lessp = s_lessp,
	greaterp = s_greaterp,
	not_lessp = s_not_lessp,
	not_greaterp = s_not_greaterp,
	equalp = s_equalp,
	not_equalp = s_not_equalp,
	max = s_max,
	min = s_min,
	set_restriction = set_speed_restriction_for_train,
	merge_aspect = merge_speed_restriction_from_aspect_to_train,
}