void TrainRoutePlanner::plan()
{
- RoutingStep *goal = 0;
+ const RoutingStep *goal = 0;
for(list<RoutingStep>::iterator i=steps.begin(); i!=steps.end(); ++i)
{
if(i->is_goal())
create_routes(*goal);
}
-void TrainRoutePlanner::add_steps(RoutingStep &step)
+void TrainRoutePlanner::add_steps(const RoutingStep &step)
{
list<RoutingStep> new_steps;
step.create_successors(new_steps);
steps.merge(new_steps);
}
-void TrainRoutePlanner::create_routes(RoutingStep &goal)
+void TrainRoutePlanner::create_routes(const RoutingStep &goal)
{
for(vector<TrainRoutingInfo>::iterator i=routed_trains.begin(); i!=routed_trains.end(); ++i)
{
i->route->set_temporary(true);
}
- for(RoutingStep *i=&goal; i; i=i->prev)
+ for(const RoutingStep *i=&goal; i; i=i->prev)
{
- for(vector<TrainRoutingState>::iterator j=i->trains.begin(); j!=i->trains.end(); ++j)
+ for(vector<TrainRoutingState>::const_iterator j=i->trains.begin(); j!=i->trains.end(); ++j)
{
if(j->state==WAITING || j->state==BLOCKED)
j->info->waits.push_front(&*j);
for(vector<TrainRoutingInfo>::iterator i=routed_trains.begin(); i!=routed_trains.end(); ++i)
{
i->router->set_route(i->route);
- TrainRoutingState *current_wait = 0;
- for(list<TrainRoutingState *>::iterator j=i->waits.begin(); j!=i->waits.end(); ++j)
+ const TrainRoutingState *current_wait = 0;
+ for(list<const TrainRoutingState *>::const_iterator j=i->waits.begin(); j!=i->waits.end(); ++j)
if(!current_wait || (*j)->track.track()!=current_wait->track.track())
{
Block &block = (*j)->track.next()->get_block();
return ((track->get_type().get_path_length(path)-offset)/info->speed)*Time::sec+delay;
}
-bool TrainRoutePlanner::TrainRoutingState::is_occupied(Track &trk) const
+bool TrainRoutePlanner::TrainRoutingState::is_occupying(Track &trk) const
{
OccupiedTrack *occ = occupied_tracks;
for(unsigned n=occ->n_tracks; n>0; --n, occ=occ->next)
prev(0)
{ }
-TrainRoutePlanner::RoutingStep::RoutingStep(RoutingStep *p):
+TrainRoutePlanner::RoutingStep::RoutingStep(const RoutingStep *p):
time(p->time),
trains(p->trains),
prev(p)
{ }
-void TrainRoutePlanner::RoutingStep::create_successors(list<RoutingStep> &new_steps)
+void TrainRoutePlanner::RoutingStep::create_successors(list<RoutingStep> &new_steps) const
{
RoutingStep next(this);
if(next.update_states())
bool TrainRoutePlanner::RoutingStep::check_deadlocks() const
{
- for(unsigned i=0; i<trains.size(); ++i)
+ for(vector<TrainRoutingState>::const_iterator i=trains.begin(); i!=trains.end(); ++i)
{
- const TrainRoutingState &train = trains[i];
- if(train.state!=BLOCKED)
+ if(i->state!=BLOCKED)
continue;
- if(train.blocked_by<0)
+ if(i->blocked_by<0)
return true;
- if(trains[train.blocked_by].blocked_by==static_cast<int>(i))
- return true;
+ int slow = i->blocked_by;
+ int fast = trains[slow].blocked_by;
+ while(fast>=0 && trains[fast].blocked_by>=0)
+ {
+ if(fast==slow)
+ return true;
+
+ slow = trains[slow].blocked_by;
+ fast = trains[trains[fast].blocked_by].blocked_by;
+ }
}
return false;
int TrainRoutePlanner::RoutingStep::get_occupant(Track &track) const
{
for(unsigned i=0; i<trains.size(); ++i)
- if(trains[i].is_occupied(track))
+ if(trains[i].is_occupying(track))
return i;
return -1;