From 66c2c7ca5a4bd369293959bc211b040834343381 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Fri, 15 Feb 2013 12:18:49 +0200 Subject: [PATCH] Remove diversion logic It was flawed in many ways and rarely produced useful results. A better system to replace it will be implemented in the future. --- source/libr2c2/train.cpp | 195 ++------------------------------------- source/libr2c2/train.h | 14 +-- 2 files changed, 12 insertions(+), 197 deletions(-) diff --git a/source/libr2c2/train.cpp b/source/libr2c2/train.cpp index 599f2dc..eb5724b 100644 --- a/source/libr2c2/train.cpp +++ b/source/libr2c2/train.cpp @@ -318,106 +318,11 @@ bool Train::go_to(const Zone &to) return set_route(route); } -bool Train::divert(Track &from) -{ - if(!from.get_turnout_id()) - throw invalid_argument("Train::divert"); - if(routes.empty()) - return false; - - unsigned path = 0; - unsigned entry = 0; - list::iterator route = routes.begin(); - - // Follow our routes to find out where we're entering the turnout - for(TrackLoopIter track = blocks.front().track_iter();;) - { - if(!advance_route(route, *track)) - return false; - - if(&*track==&from) - { - Block &block = track->get_block(); - if(block.get_train()==this && !free_block(block)) - return false; - - int route_path = route->route->get_turnout(from.get_turnout_id()); - - // Check that more than one path is available - unsigned ep_paths = track.endpoint().paths; - if(!(ep_paths&(ep_paths-1))) - return false; - - // Choose some other path - for(int i=0; ep_paths>>i; ++i) - if((ep_paths&(1<route->get_path(*track)); - - if(!track || track.looped()) - return false; - } - - TrackIter track = TrackIter(&from, entry).next(path); - if(!track) - return false; - - set tracks; - for(list::iterator i=routes.begin(); i!=routes.end(); ++i) - tracks.insert(i->route->get_tracks().begin(), i->route->get_tracks().end()); - RefPtr diversion = Route::find(track, tracks); - if(!diversion) - return false; - - diversion->set_name("Diversion"); - diversion->add_track(from); - diversion->set_turnout(from.get_turnout_id(), path); - - if(!is_valid_diversion(*diversion, TrackIter(&from, entry))) - return false; - - // Follow the diversion route until we get back to the original route - list::iterator end = routes.end(); - while(1) - { - for(list::iterator i=route; (end==routes.end() && i!=routes.end()); ++i) - if(i->route->has_track(*track)) - end = i; - - if(end!=routes.end()) - break; - else if(!diversion->has_track(*track)) - throw logic_error("bad diversion"); - - track = track.next(diversion->get_path(*track)); - } - - if(route==end) - // We are rejoining the same route we diverted from, duplicate it - routes.insert(end, *route); - else - { - ++route; - routes.erase(route, end); - } - routes.insert(end, RouteRef(diversion.release(), from.get_turnout_id())); - - return true; -} - const Route *Train::get_route() const { if(routes.empty()) return 0; - return routes.front().route; + return routes.front(); } void Train::place(Block &block, unsigned entry) @@ -690,10 +595,10 @@ void Train::save(list &st) const if(!routes.empty()) { - list::const_iterator i = routes.begin(); - for(; (i!=routes.end() && i->route->is_temporary()); ++i) ; + list::const_iterator i = routes.begin(); + for(; (i!=routes.end() && (*i)->is_temporary()); ++i) ; if(i!=routes.end()) - st.push_back((DataFile::Statement("route"), i->route->get_name())); + st.push_back((DataFile::Statement("route"), (*i)->get_name())); } // XXX Need more generic way of saving AI state @@ -795,13 +700,13 @@ void Train::block_state_changed(Block &block, Block::State state) // Check if we've reached the next route if(routes.size()>1) { - const Route &route = *(++routes.begin())->route; + const Route &route = **(++routes.begin()); for(BlockList::iterator j=cur_blocks_end; j!=end; ++j) if(route.has_track(*j->track_iter())) { routes.pop_front(); // XXX Exceptions? - signal_route_changed.emit(routes.front().route); + signal_route_changed.emit(routes.front()); break; } } @@ -886,7 +791,7 @@ void Train::reserve_more() dist += (*i)->get_path_length(i->entry()); } - list::iterator cur_route = routes.begin(); + list::iterator cur_route = routes.begin(); advance_route(cur_route, *start.track_iter()); float approach_margin = 50*layout.get_catalogue().get_scale(); @@ -894,8 +799,6 @@ void Train::reserve_more() BlockIter block = start; list::iterator good_end = blocks.end(); - Track *divert_track = 0; - bool try_divert = false; Train *blocking_train = 0; BlockList contested_blocks; @@ -904,7 +807,7 @@ void Train::reserve_more() while(1) { BlockIter last = block; - block = block.next(cur_route!=routes.end() ? cur_route->route : 0); + block = block.next(cur_route!=routes.end() ? *cur_route : 0); if(!block || block->get_endpoints().size()<2) { if(!blocking_train) @@ -960,7 +863,6 @@ void Train::reserve_more() { yield_to(*blocking_train); pending_block = contested_blocks.front().block(); - try_divert = divert_track; break; } } @@ -1021,9 +923,6 @@ void Train::reserve_more() contested_blocks.push_back(block); continue; } - else if(divert_track && (entry_conflict || exit_conflict || !other_train->is_active())) - // We are blocked, but there's a diversion possibility - try_divert = true; if(!reserved) { @@ -1032,17 +931,6 @@ void Train::reserve_more() } } - if(block->get_turnout_id()) - { - const TrackType::Endpoint &track_ep = track.endpoint(); - bool multiple_paths = (track_ep.paths&(track_ep.paths-1)); - - if(multiple_paths && cur_route!=routes.end() && cur_route->diversion!=block->get_turnout_id()) - /* There's multiple paths to be taken and we are on a route - take - note of the diversion possibility */ - divert_track = &*track; - } - if(!contested_blocks.empty() && contested_blocks.front()==block) contested_blocks.pop_front(); @@ -1071,9 +959,6 @@ void Train::reserve_more() // Make any sensorless blocks at the beginning immediately current while(cur_blocks_end!=clear_blocks_end && !(*cur_blocks_end)->get_sensor_id()) ++cur_blocks_end; - - if(try_divert && divert(*divert_track)) - reserve_more(); } void Train::check_turnout_paths(bool set) @@ -1204,18 +1089,13 @@ void Train::reverse_blocks(BlockList &blks) const *i = i->reverse(); } -bool Train::advance_route(list::iterator &iter, Track &track) +bool Train::advance_route(list::iterator &iter, Track &track) { - while(iter!=routes.end() && !iter->route->has_track(track)) + while(iter!=routes.end() && !(*iter)->has_track(track)) ++iter; if(iter==routes.end()) return false; - list::iterator next = iter; - ++next; - if(next!=routes.end() && next->diversion && next->route->has_track(track)) - iter = next; - return true; } @@ -1242,61 +1122,6 @@ Route *Train::create_lead_route(Route *lead, const Route *target) return lead; } -bool Train::is_valid_diversion(const Route &diversion, const TrackIter &from) -{ - float diversion_len = 0; - TrackLoopIter track1 = from; - while(diversion.has_track(*track1)) - { - unsigned path = diversion.get_path(*track1); - diversion_len += track1->get_type().get_path_length(path); - - track1 = track1.next(path); - - if(!track1 || track1.looped()) - return false; - } - - list::iterator route = routes.begin(); - if(!advance_route(route, *from)) - return false; - - float route_len = 0; - TrackLoopIter track2 = from; - while(1) - { - unsigned path = route->route->get_path(*track2); - route_len += track2->get_type().get_path_length(path); - - bool ok = (track2!=from && diversion.has_track(*track2)); - - track2 = track2.next(path); - if(!track2) - return false; - - if(ok) - break; - - if(track2.looped()) - return false; - - if(!advance_route(route, *track2)) - return false; - } - - // Must end up at the same place through both routes - if(track2!=track1) - return false; - - return diversion_len(t), diff --git a/source/libr2c2/train.h b/source/libr2c2/train.h index e16f726..709140c 100644 --- a/source/libr2c2/train.h +++ b/source/libr2c2/train.h @@ -51,14 +51,6 @@ public: sigc::signal signal_status_changed; private: - struct RouteRef - { - const Route *route; - unsigned diversion; - - RouteRef(const Route *, unsigned = 0); - }; - typedef std::list BlockList; Layout &layout; @@ -84,7 +76,7 @@ private: bool reverse; Msp::Time::TimeStamp stop_timeout; unsigned functions; - std::list routes; + std::list routes; bool end_of_route; Msp::Time::TimeStamp last_entry_time; @@ -135,7 +127,6 @@ public: bool set_route(const Route *); bool go_to(Track &); bool go_to(const Zone &); - bool divert(Track &); const Route *get_route() const; void place(Block &, unsigned); void unplace(); @@ -162,9 +153,8 @@ private: void release_blocks(); void release_blocks(BlockList::iterator, BlockList::iterator); void reverse_blocks(BlockList &) const; - bool advance_route(std::list::iterator &, Track &); + bool advance_route(std::list::iterator &, Track &); Route *create_lead_route(Route *, const Route *); - bool is_valid_diversion(const Route &, const TrackIter &); }; } // namespace R2C2 -- 2.43.0