From: Mikko Rasa Date: Sun, 30 Mar 2014 13:20:28 +0000 (+0300) Subject: Continue TrainRoutePlanner refactoring X-Git-Url: http://git.tdb.fi/?a=commitdiff_plain;h=19274ec3b805af126e562c805e0c14baa14c5833;p=r2c2.git Continue TrainRoutePlanner refactoring This moves even more logic into the data structures, and cleans up step management. --- diff --git a/source/libr2c2/trainrouteplanner.cpp b/source/libr2c2/trainrouteplanner.cpp index f517afd..c115d92 100644 --- a/source/libr2c2/trainrouteplanner.cpp +++ b/source/libr2c2/trainrouteplanner.cpp @@ -38,79 +38,17 @@ void TrainRoutePlanner::plan() 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::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 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(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); } @@ -255,6 +193,26 @@ bool TrainRoutePlanner::TrainRoutingState::is_occupied(Track &trk) const 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(router.get_n_waypoints())) + waypoint = -1; + } + + return false; +} + void TrainRoutePlanner::TrainRoutingState::advance(float distance) { offset += distance; @@ -298,6 +256,55 @@ TrainRoutePlanner::RoutingStep::RoutingStep(RoutingStep *p): prev(p) { } +void TrainRoutePlanner::RoutingStep::create_successors(list &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; diff --git a/source/libr2c2/trainrouteplanner.h b/source/libr2c2/trainrouteplanner.h index f50669c..de88302 100644 --- a/source/libr2c2/trainrouteplanner.h +++ b/source/libr2c2/trainrouteplanner.h @@ -70,6 +70,7 @@ private: Msp::Time::TimeDelta get_time_to_next_track() const; bool is_occupied(Track &) const; + bool check_arrival(); void advance(float); void advance_track(unsigned); }; @@ -83,6 +84,7 @@ private: RoutingStep(); RoutingStep(RoutingStep *); + void create_successors(std::list &); bool update_states(); bool check_deadlocks() const; int get_occupant(Track &) const; @@ -102,10 +104,7 @@ public: 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 &); };