+ BlockIter fncb = train.get_last_critical_block().next();
+
+ state = ON_THE_WAY;
+ reserving_route = routes.begin();
+ if(!routes.empty())
+ {
+ /* Find the route that should be used for the next allocated block. We
+ can't rely on the resync code in block_reserved since we may need to
+ clear the stop marker to continue allocation. */
+ const BlockAllocator &allocator = train.get_block_allocator();
+ TrackIter track = allocator.first().track_iter();
+ list<SequencePoint>::iterator seq_begin = sequence_points.begin();
+ for(; track; track=track.next())
+ {
+ if(!advance_to_track(reserving_route, track))
+ {
+ state = (allocator.is_block_current(track->get_block()) ? ADVANCED_TO_END : RESERVED_TO_END);
+ break;
+ }
+ if(&track->get_block()==fncb.block())
+ break;
+
+ if(seq_begin!=sequence_points.end() && seq_begin->block==&track->get_block())
+ {
+ // Assume any sequence points within critical blocks to be cleared
+ current_sequence = seq_begin->sequence_out;
+ ++seq_begin;
+ }
+ }
+
+ sequence_points.erase(sequence_points.begin(), seq_begin);
+
+ if(!sequence_points.empty())
+ {
+ const SequencePoint &sp = sequence_points.front();
+ if(sp.block==fncb.block() && !sp.is_cleared())
+ state = SEQUENCE_CHECK_PENDING;
+ }
+ }
+
+ /* Refresh from the first non-critical block to pick up any changes in the
+ route. Set stop marker first in case a stopping state was set within the
+ critical blocks. */
+ if(state!=ON_THE_WAY)
+ train.stop_at(&*fncb.flip());
+ train.refresh_blocks_from(*fncb);
+ // If we don't need to stop, clear a possible previous stop marker.
+ if(state==ON_THE_WAY)
+ train.stop_at(0);
+
+ const Route *route = get_route();
+ signal_route_changed.emit(route);
+ signal_event.emit(Message("route-changed", route));
+}
+
+void TrainRouter::set_destination(const TrackChain &d)
+{
+ if(waypoints.empty())
+ waypoints.push_back(Waypoint(d));
+ else
+ waypoints.back() = Waypoint(d);
+ waypoints_changed = true;
+ metrics_stale = true;