aboutsummaryrefslogtreecommitdiff
path: root/advtrains
diff options
context:
space:
mode:
Diffstat (limited to 'advtrains')
-rw-r--r--advtrains/helpers.lua50
1 files changed, 39 insertions, 11 deletions
diff --git a/advtrains/helpers.lua b/advtrains/helpers.lua
index bef4903..6d22bc5 100644
--- a/advtrains/helpers.lua
+++ b/advtrains/helpers.lua
@@ -342,9 +342,10 @@ function advtrains.get_matching_conn(conn, nconns)
return connlku[nconns][conn]
end
-function advtrains.random_id()
+function advtrains.random_id(lenp)
local idst=""
- for i=0,5 do
+ local len = lenp or 6
+ for i=1,len do
idst=idst..(math.random(0,9))
end
return idst
@@ -476,6 +477,14 @@ end
-- Metatable:
local trackiter_mt = {
+ -- Internal State:
+ -- branches: A list of {pos, connid, limit} for where to restart
+ -- pos: The *next* position that the track iterator will return
+ -- bconnid: The connid of the connection of the rail at pos that points backward
+ -- tconns: The connections of the rail at pos
+ -- limit: the current limit
+ -- visited: a key-boolean table of already visited rails
+
-- get whether there are still unprocessed branches
has_next_branch = function(self)
return #self.branches > 0
@@ -491,13 +500,18 @@ local trackiter_mt = {
self.tconns = adj_conns
self.limit = br.limit - 1
self.visited[advtrains.encode_pos(br.pos)] = true
+ self.last_track_already_visited = false
return br.pos, br.connid
end,
-- get the next track along the current branch,
-- potentially adding branching tracks to the unprocessed branches list
- -- returns status, track_pos, track_connid
- -- status is true(ok), false(track has ended), nil(traversing limit has been reached) (when status~=true, track_pos and track_connid are nil)
+ -- returns track_pos, track_connid, track_backwards_connid
+ -- On error, returns nil, reason; reason is one of "track_end", "limit_hit", "already_visited"
next_track = function(self)
+ if self.last_track_already_visited then
+ -- see comment below
+ return nil, "already_visited"
+ end
local pos = self.pos
if not pos then
-- last run found track end. Return false
@@ -507,12 +521,17 @@ local trackiter_mt = {
if self.limit <= 0 then
return nil, "limit_hit"
end
- if self.visited[advtrains.encode_pos(pos)] then
- -- node was already seen. do not continue
- return nil, "already_visited"
- end
-- select next conn (main conn to follow is the associated connection)
+ local old_bconnid = self.bconnid
local mconnid = advtrains.get_matching_conn(self.bconnid, #self.tconns)
+ if self.visited[advtrains.encode_pos(pos)] then
+ -- node was already seen
+ -- Due to special requirements for the track section updater, return this first already visited track once
+ -- but do not process any further rails on this branch
+ -- The next call will then throw already_visited error
+ self.last_track_already_visited = true
+ return pos, mconnid, old_bconnid
+ end
-- If there are more connections, add these to branches
for nconnid,_ in ipairs(self.tconns) do
if nconnid~=mconnid and nconnid~=self.bconnid then
@@ -526,7 +545,16 @@ local trackiter_mt = {
self.tconns = adj_conns
self.limit = self.limit - 1
self.visited[advtrains.encode_pos(pos)] = true
- return pos, mconnid
+ self.last_track_already_visited = false
+ return pos, mconnid, old_bconnid
+ end,
+
+ add_branch = function(self, pos, connid)
+ table.insert(self.branches, {pos = pos, connid = connid, limit=self.limit})
+ end,
+
+ is_visited = function(self, pos)
+ return self.visited[advtrains.encode_pos(pos)]
end,
}
@@ -569,8 +597,8 @@ while ti:has_next_branch() do
repeat
<do something with the track>
if <track satisfies an abort condition> then break end --for example, when traversing should stop at TCBs this can check if there is a tcb here
- ok, pos, connid = ti:next_track()
- until not ok -- this stops the loop when either the track end is reached or the limit is hit
+ pos, connid = ti:next_track()
+ until not pos -- this stops the loop when either the track end is reached or the limit is hit
-- while loop continues with the next branch ( diverging branch of one of the switches/crossings) until no more are left
end