break;
}
- if(update_states(*i))
- {
- int next_train = i->find_next_train();
- if(next_train>=0)
- add_steps(*i, next_train);
- }
+ add_steps(*i);
}
if(goal)
create_routes(*goal);
}
-bool TrainRoutePlanner::update_states(RoutingStep &step)
-{
- RoutingStep next(&step);
- if(!next.update_states())
- return true;
- if(next.check_deadlocks())
- return false;
-
- list<RoutingStep>::iterator i;
- for(i=steps.begin(); (i!=steps.end() && !(next<*i)); ++i) ;
- steps.insert(i, next);
-
- return false;
-}
-
-void TrainRoutePlanner::add_steps(RoutingStep &step, unsigned train_index)
+void TrainRoutePlanner::add_steps(RoutingStep &step)
{
- TrainRoutingState &train = step.trains[train_index];
- Time::TimeDelta dt = train.get_time_to_next_track();
- TrackIter next_track = train.track.next(train.path);
-
list<RoutingStep> new_steps;
-
- RoutingStep next(&step);
- next.advance(dt);
- TrainRouter &router = *train.info->router;
- if(train.waypoint<0 && router.is_destination(*train.track) && !router.is_destination(*next_track))
- {
- next.trains[train_index].state = ARRIVED;
- new_steps.push_back(next);
- }
- else
- {
- if(train.waypoint>=0 && router.is_waypoint(train.waypoint, *train.track) && !router.is_waypoint(train.waypoint, *next_track))
- {
- ++next.trains[train_index].waypoint;
- if(next.trains[train_index].waypoint>=static_cast<int>(router.get_n_waypoints()))
- next.trains[train_index].waypoint = -1;
- }
-
- next.trains[train_index].advance_track(0);
-
- const TrackType::Endpoint &next_entry_ep = next_track.endpoint();
- for(unsigned i=0; next_entry_ep.paths>>i; ++i)
- if(next_entry_ep.has_path(i))
- {
- next.trains[train_index].path = i;
- if(next.is_viable())
- new_steps.push_back(next);
- }
-
- if(next_entry_ep.paths!=next_track->get_type().get_paths())
- {
- RoutingStep wait(&step);
- wait.advance(dt);
- wait.trains[train_index].state = WAITING;
- if(wait.is_viable())
- new_steps.push_back(wait);
- }
- }
-
+ step.create_successors(new_steps);
new_steps.sort();
steps.merge(new_steps);
}
return false;
}
+bool TrainRoutePlanner::TrainRoutingState::check_arrival()
+{
+ TrainRouter &router = *info->router;
+ TrackIter next_track = track.next(path);
+
+ if(waypoint<0 && router.is_destination(*track) && !router.is_destination(*next_track))
+ {
+ state = ARRIVED;
+ return true;
+ }
+ else if(waypoint>=0 && router.is_waypoint(waypoint, *track) && !router.is_waypoint(waypoint, *next_track))
+ {
+ ++waypoint;
+ if(waypoint>=static_cast<int>(router.get_n_waypoints()))
+ waypoint = -1;
+ }
+
+ return false;
+}
+
void TrainRoutePlanner::TrainRoutingState::advance(float distance)
{
offset += distance;
prev(p)
{ }
+void TrainRoutePlanner::RoutingStep::create_successors(list<RoutingStep> &new_steps)
+{
+ RoutingStep next(this);
+ if(next.update_states())
+ {
+ if(next.check_deadlocks())
+ return;
+
+ new_steps.push_back(next);
+ return;
+ }
+
+ int train_index = find_next_train();
+ if(train_index<0)
+ return;
+
+ TrainRoutingState &train = next.trains[train_index];
+
+ Time::TimeDelta dt = train.get_time_to_next_track();
+ next.advance(dt);
+
+ if(train.check_arrival())
+ {
+ new_steps.push_back(next);
+ return;
+ }
+
+ TrackIter next_track = train.track.next(train.path);
+ train.advance_track(0);
+
+ const TrackType::Endpoint &next_entry_ep = next_track.endpoint();
+ for(unsigned i=0; next_entry_ep.paths>>i; ++i)
+ if(next_entry_ep.has_path(i))
+ {
+ train.path = i;
+ if(next.is_viable())
+ new_steps.push_back(next);
+ }
+
+ if(next_entry_ep.paths!=next_track->get_type().get_paths())
+ {
+ RoutingStep wait(this);
+ wait.advance(dt);
+ wait.trains[train_index].state = WAITING;
+ if(wait.is_viable())
+ new_steps.push_back(wait);
+ }
+}
+
bool TrainRoutePlanner::RoutingStep::update_states()
{
bool changes = false;
Msp::Time::TimeDelta get_time_to_next_track() const;
bool is_occupied(Track &) const;
+ bool check_arrival();
void advance(float);
void advance_track(unsigned);
};
RoutingStep();
RoutingStep(RoutingStep *);
+ void create_successors(std::list<RoutingStep> &);
bool update_states();
bool check_deadlocks() const;
int get_occupant(Track &) const;
void plan();
private:
- bool update_states(RoutingStep &);
- void add_steps(RoutingStep &, unsigned);
- void add_waiting_step(RoutingStep &, unsigned);
- void add_steps(RoutingStep &, TrainRoutingState &train);
+ void add_steps(RoutingStep &);
void create_routes(RoutingStep &);
};