void TrainRouter::set_destination(const TrackChain &d)
{
if(waypoints.empty())
- waypoints.push_back(&d);
+ waypoints.push_back(Waypoint(d));
else
- waypoints.back() = &d;
+ waypoints.back() = Waypoint(d);
waypoints_changed = true;
metrics_stale = true;
}
-void TrainRouter::add_waypoint(const TrackChain &wp)
+void TrainRouter::add_waypoint(const TrackChain &chain, TrackChain::Direction dir)
{
- waypoints.push_back(&wp);
+ waypoints.push_back(Waypoint(chain, dir));
waypoints_changed = true;
metrics_stale = true;
}
-const TrackChain &TrainRouter::get_waypoint(unsigned index) const
+const TrainRouter::Waypoint &TrainRouter::get_waypoint(unsigned index) const
{
if(index>=waypoints.size())
throw out_of_range("TrainRouter::is_waypoint");
- return *waypoints[index];
+ return waypoints[index];
}
const TrainRouteMetric &TrainRouter::get_metric(int index) const
}
else if(msg.type=="add-waypoint")
{
- if(msg.value.check_type<TrackChain *>())
+ if(msg.value.check_type<Waypoint>())
+ {
+ Waypoint wp = msg.value.value<Waypoint>();
+ add_waypoint(*wp.chain, wp.direction);
+ }
+ else if(msg.value.check_type<TrackChain *>())
add_waypoint(*msg.value.value<TrackChain *>());
else
add_waypoint(*msg.value.value<const TrackChain *>());
if(arrival==ADVANCED_TO_END && !train.get_speed())
{
- signal_arrived.emit(waypoints.back());
- signal_event.emit(Message("arrived", waypoints.back()));
+ signal_arrived.emit(waypoints.back().chain);
+ signal_event.emit(Message("arrived", waypoints.back().chain));
arrival = ARRIVED;
}
else if(arrival==ARRIVED && !train.get_block_allocator().is_active())
void TrainRouter::train_advanced(Block &block)
{
- BlockIter b_iter = train.get_block_allocator().iter_for(block);
-
if(!waypoints.empty())
{
// A waypoint is considered reached when the train has advanced through it.
- const TrackChain &wp = *waypoints.front();
+ BlockIter b_iter = train.get_block_allocator().iter_for(block);
+ const Waypoint &wp = waypoints.front();
TrackIter t_iter = b_iter.track_iter();
- if(wp.has_track(*t_iter))
+ if(wp.chain->has_track(*t_iter))
{
- for(; t_iter; t_iter=t_iter.next())
+ while(1)
{
- if(!wp.has_track(*t_iter))
+ TrackIter next = t_iter.next();
+ if(!next)
+ break;
+
+ if(!wp.chain->has_track(*next))
{
+ if(wp.direction!=TrackChain::UNSPECIFIED)
+ if(t_iter!=wp.chain->iter_for(*t_iter, wp.direction))
+ break;
+
if(waypoints.size()==1)
{
if(arrival==RESERVED_TO_END)
}
else
{
+ const TrackChain *chain = wp.chain;
waypoints.erase(waypoints.begin());
metrics_stale = true;
- signal_waypoint_reached.emit(&wp);
- signal_event.emit(Message("waypoint-reached", &wp));
+ signal_waypoint_reached.emit(chain);
+ signal_event.emit(Message("waypoint-reached", chain));
}
break;
}
- else if(!block.has_track(*t_iter))
+ else if(!block.has_track(*next))
break;
+
+ t_iter = next;
}
}
}
if(waypoints.empty())
return;
- for(vector<const TrackChain *>::const_iterator i=waypoints.begin(); i!=waypoints.end(); ++i)
- metrics.push_back(new TrainRouteMetric(**i));
+ for(vector<Waypoint>::const_iterator i=waypoints.begin(); i!=waypoints.end(); ++i)
+ metrics.push_back(new TrainRouteMetric(*i->chain, i->direction));
for(unsigned i=metrics.size()-1; i-->0; )
metrics[i]->chain_to(*metrics[i+1]);
}
+TrainRouter::Waypoint::Waypoint(const TrackChain &c, TrackChain::Direction d):
+ chain(&c),
+ direction(d)
+{ }
+
+
TrainRouter::SequencePoint::SequencePoint(Block &b, unsigned o):
block(&b),
preceding_train(0),