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