-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathiterators.lua
More file actions
116 lines (100 loc) · 2.93 KB
/
Copy pathiterators.lua
File metadata and controls
116 lines (100 loc) · 2.93 KB
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
-- luacheck: no max comment line length
---
-- @module iterators
local assertions = require("luatypechecks.assertions")
local checks = require("luatypechecks.checks")
local Vector2D = require("luamath.vector2d")
local DistanceLimit = require("luaplot.distancelimit")
local iterators = {}
---
-- ⚠️. It is an analog of the 'next' function but for the 'ipairs' one.
-- It is used for iterating in Lua 5.2.
-- @tparam tab indexable
-- @tparam number index [0, ∞)
-- @treturn[1] number next index
-- @treturn[1] any next item
-- @treturn[2] nil when the next index out of range
function iterators.inext(indexable, index)
assertions.is_true(
checks.is_sequence(indexable)
or checks.has_metamethods(indexable, {"__index"})
)
assertions.is_number(index)
local next_index = index + 1
local next_item = indexable[next_index]
if next_item == nil then
return
end
return next_index, next_item
end
---
-- @tparam tab indexable_one
-- @tparam tab indexable_two
-- @tparam number index [1, ∞)
-- @tparam[opt=false] bool modulo
-- @treturn number vertical difference for Vector2D items, otherwise item difference
function iterators.difference(indexable_one, indexable_two, index, modulo)
modulo = modulo or false
assertions.is_true(
checks.is_sequence(indexable_one)
or checks.has_metamethods(indexable_one, {"__index"})
)
assertions.is_true(
checks.is_sequence(indexable_two)
or checks.has_metamethods(indexable_two, {"__index"})
)
assertions.is_number(index)
assertions.is_boolean(modulo)
local item_one = indexable_one[index]
local item_two = indexable_two[index]
local difference = item_one - item_two
if checks.is_instance(difference, Vector2D) then
difference = difference.y
end
if modulo then
difference = math.abs(difference)
end
return difference
end
---
-- @tparam tab indexable_one
-- @tparam tab indexable_two
-- @tparam number index [1, ∞)
-- @tparam[opt=false] bool modulo
-- @tparam {DistanceLimit,...} limits
-- @treturn any
function iterators.select_by_distance(
indexable_one,
indexable_two,
index,
modulo,
limits
)
-- handle the call form with the optional `modulo` argument omitted
if limits == nil then
modulo, limits = nil, modulo
end
modulo = modulo or false
assertions.is_true(
checks.is_sequence(indexable_one)
or checks.has_metamethods(indexable_one, {"__index"})
)
assertions.is_true(
checks.is_sequence(indexable_two)
or checks.has_metamethods(indexable_two, {"__index"})
)
assertions.is_number(index)
assertions.is_boolean(modulo)
assertions.is_sequence(limits, checks.make_instance_checker(DistanceLimit))
local suitable_value
local distance =
iterators.difference(indexable_one, indexable_two, index, modulo)
for _, limit in ipairs(limits) do
if distance <= limit.maximal_distance then
suitable_value = limit.suitable_value
break
end
end
return suitable_value
end
return iterators