TrainRoutePlanner::TrainRoutingState::~TrainRoutingState()
{
- if(!--occupied_tracks->refcount)
+ if(occupied_tracks && !--occupied_tracks->refcount)
delete occupied_tracks;
}
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)
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;