1 //
2 // Copyright (C) 2009 Nick Gasson
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16 //
17
18 #include "IterateTrack.hpp"
19
20 #include <cassert>
21
22 // Find the next piece of track
next() const23 TrackIterator TrackIterator::next() const
24 {
25 if (status == TRACK_NO_MORE)
26 return *this;
27
28 track::Direction dir;
29 track::Position pos;
30 tie(pos, dir) = track->next_position(token);
31
32 return iterate_track(map, pos, dir);
33 }
34
35 // Build an iterator object for a given track segment
iterate_track(IMapPtr a_map,track::Position a_position,track::Direction a_direction)36 TrackIterator iterate_track(IMapPtr a_map, track::Position a_position,
37 track::Direction a_direction)
38 {
39 TrackIterator it;
40 it.map = a_map;
41 it.status = TRACK_OK ;
42
43 if (a_map->is_valid_track(a_position)) {
44 it.track = a_map->track_at(a_position);
45 it.token = it.track->get_travel_token(a_position, a_direction);
46 }
47 else {
48 // Fell off the end
49 it.track = ITrackSegmentPtr();
50 it.status = TRACK_NO_MORE;
51 return it;
52 }
53
54 // Are we sitting on a station?
55 typedef vector<Point<int> > PointList;
56 PointList endpoints;
57 it.track->get_endpoints(endpoints);
58
59 IStationPtr station;
60 for (PointList::const_iterator p = endpoints.begin();
61 p != endpoints.end(); ++p)
62 if ((it.station = a_map->station_at(make_point((*p).x, (*p).y)))) {
63 it.status = TRACK_STATION;
64 break;
65 }
66
67 if (it.token.num_exits > 1) {
68 assert(it.track->has_multiple_states());
69 it.status = TRACK_CHOICE;
70 }
71 else
72 assert(it.token.num_exits == 1);
73
74 return it;
75 }
76