if(r && !cur_blocks.empty())
{
+ BlockRef &first = cur_blocks.front();
BlockRef &last = (rsv_blocks.empty() ? cur_blocks.back() : rsv_blocks.back());
BlockRef next = last.next();
- const Block::Endpoint &ep = next.block->get_endpoints()[next.entry];
- if(!r->get_tracks().count(ep.track))
- routes.push_front(Route::find(*ep.track, ep.track_ep, *r));
-
- /* XXX This is sort of a hack, but it keeps divert() happy. Need to come
- up with a better solution when there is time. */
- routes.push_front(create_lead_route());
+ const Block::Endpoint &first_ep = first.block->get_endpoints()[first.entry];
+ const Block::Endpoint &next_ep = next.block->get_endpoints()[next.entry];
+ if(!r->has_track(*next_ep.track))
+ {
+ Route *lead = Route::find(*next_ep.track, next_ep.track_ep, *r);
+ create_lead_route(lead, lead);
+ routes.push_front(lead);
+ }
+ else if(!r->has_track(*first_ep.track))
+ routes.push_front(create_lead_route(0, r));
}
reserve_more();
signal_route_changed.emit(get_route());
}
-void Train::go_to(const Track &to)
+void Train::go_to(Track &to)
{
for(list<BlockRef>::const_iterator i=cur_blocks.begin(); i!=cur_blocks.end(); ++i)
- if(i->block->get_tracks().count(const_cast<Track *>(&to)))
+ if(i->block->has_track(to))
{
signal_arrived.emit();
set_route(0);
BlockRef next = last.next();
const Block::Endpoint &ep = next.block->get_endpoints()[next.entry];
- set_route(Route::find(*ep.track, ep.track_ep, to));
+ Route *route = Route::find(*ep.track, ep.track_ep, to);
+ create_lead_route(route, route);
+ set_route(route);
}
bool Train::divert(Track &from)
unsigned ep = track->get_endpoint_by_link(from);
- set<const Track *> tracks;
+ set<Track *> tracks;
for(list<RouteRef>::iterator i=routes.begin(); i!=routes.end(); ++i)
tracks.insert(i->route->get_tracks().begin(), i->route->get_tracks().end());
Route *diversion = 0;
Track *next = track->get_link(track->traverse(ep, path));
for(list<RouteRef>::iterator i=route; (end==routes.end() && i!=routes.end()); ++i)
- if(i->route->get_tracks().count(next))
+ if(i->route->has_track(*next))
end = i;
if(end!=routes.end())
break;
- else if(!diversion->get_tracks().count(next))
+ else if(!diversion->has_track(*next))
throw Exception("Pathfinder returned a bad route");
ep = next->get_endpoint_by_link(*track);
Track *track = veh.get_track();
list<BlockRef>::iterator block = cur_blocks.begin();
bool in_rsv = false;
- while(block!=rsv_blocks.end() && !block->block->get_tracks().count(track))
+ while(block!=rsv_blocks.end() && !block->block->has_track(*track))
{
++block;
if(block==cur_blocks.end())
entry = next->get_endpoint_by_link(*track);
track = next;
- if(!block->block->get_tracks().count(track))
+ if(!block->block->has_track(*track))
{
++block;
if(block==cur_blocks.end())
bool ok = false;
for(list<BlockRef>::const_iterator i=cur_blocks.begin(); (!ok && i!=cur_blocks.end()); ++i)
- ok = i->block->get_tracks().count(track);
+ ok = i->block->has_track(*track);
float d = get_real_speed(current_speed)*(dt/Time::sec);
if(ok)
// Check if we've reached the next route
if(routes.size()>1)
{
- const set<const Track *> &rtracks = (++routes.begin())->route->get_tracks();
+ const set<Track *> &rtracks = (++routes.begin())->route->get_tracks();
for(list<BlockRef>::iterator j=rsv_blocks.begin(); j!=i; ++j)
if(rtracks.count(j->block->get_endpoints()[j->entry].track))
{
list<BlockRef>::iterator end = cur_blocks.begin();
for(list<BlockRef>::iterator i=cur_blocks.begin(); i!=cur_blocks.end(); ++i)
{
- if(i->block->get_tracks().count(veh.get_track()))
+ if(i->block->has_track(*veh.get_track()))
break;
if(i->block->get_sensor_id())
{
break;
}
}
- else if(!routes.empty() && routes.front().route->get_tracks().count(entry_ep.track))
+ else if(!routes.empty() && routes.front().route->has_track(*entry_ep.track))
cur_route = routes.begin();
if(link->get_endpoints().size()<2)
return 0;
list<BlockRef>::const_iterator block = cur_blocks.begin();
- while(block!=rsv_blocks.end() && !block->block->get_tracks().count(track))
+ while(block!=rsv_blocks.end() && !block->block->has_track(*track))
{
++block;
if(block==cur_blocks.end())
Track *next = track->get_link(track->traverse(entry));
- if(!block->block->get_tracks().count(next))
+ if(!block->block->has_track(*next))
{
if(back)
{
i->entry = i->block->traverse(i->entry);
}
-bool Train::advance_route(list<RouteRef>::iterator &iter, const Track &track)
+bool Train::advance_route(list<RouteRef>::iterator &iter, Track &track)
{
- while(iter!=routes.end() && !iter->route->get_tracks().count(&track))
+ while(iter!=routes.end() && !iter->route->has_track(track))
++iter;
if(iter==routes.end())
return false;
list<RouteRef>::iterator next = iter;
++next;
- if(next!=routes.end() && next->diversion && next->route->get_tracks().count(&track))
+ if(next!=routes.end() && next->diversion && next->route->has_track(track))
iter = next;
return true;
}
-Route *Train::create_lead_route()
+Route *Train::create_lead_route(Route *lead, const Route *target)
{
- Route *lead = new Route(layout);
- lead->set_name("Lead");
- lead->set_temporary(true);
+ if(!lead)
+ {
+ lead = new Route(layout);
+ lead->set_name("Lead");
+ lead->set_temporary(true);
+ }
+ set<Track *> tracks;
for(list<BlockRef>::iterator i=cur_blocks.begin(); i!=rsv_blocks.end(); )
{
- // XXX Make Route eat non-const tracks to get rid of this idiocy and various const_casts
const set<Track *> &btracks = i->block->get_tracks();
- set<const Track *> tracks(btracks.begin(), btracks.end());
- lead->add_tracks(tracks);
+ for(set<Track *>::const_iterator j=btracks.begin(); j!=btracks.end(); ++j)
+ if(!target || !target->has_track(**j))
+ tracks.insert(*j);
if(++i==cur_blocks.end())
i = rsv_blocks.begin();
}
+ lead->add_tracks(tracks);
+
return lead;
}
-bool Train::is_valid_diversion(const Route &diversion, const Track &from, unsigned from_ep)
+bool Train::is_valid_diversion(const Route &diversion, Track &from, unsigned from_ep)
{
float diversion_len = 0;
- const Track *track = &from;
+ Track *track = &from;
unsigned ep = from_ep;
- while(diversion.get_tracks().count(track))
+ while(diversion.has_track(*track))
{
unsigned path = 0;
if(track->get_turnout_id())
path = diversion.get_turnout(track->get_turnout_id());
diversion_len += track->get_type().get_path_length(path);
- const Track *next = track->get_link(track->traverse(ep, path));
+ Track *next = track->get_link(track->traverse(ep, path));
ep = next->get_endpoint_by_link(*track);
track = next;
if(!advance_route(route, from))
return false;
- set<const Track *> visited;
+ set<Track *> visited;
float route_len = 0;
track = &from;
ep = from_ep;
path = route->route->get_turnout(track->get_turnout_id());
route_len += track->get_type().get_path_length(path);
- if(track!=&from && diversion.get_tracks().count(track))
+ if(track!=&from && diversion.has_track(*track))
break;
if(visited.count(track))
return false;
visited.insert(track);
- const Track *next = track->get_link(track->traverse(ep, path));
+ Track *next = track->get_link(track->traverse(ep, path));
ep = next->get_endpoint_by_link(*track);
track = next;