]> git.tdb.fi Git - r2c2.git/commitdiff
Remove diversion logic
authorMikko Rasa <tdb@tdb.fi>
Fri, 15 Feb 2013 10:18:49 +0000 (12:18 +0200)
committerMikko Rasa <tdb@tdb.fi>
Fri, 15 Feb 2013 10:22:56 +0000 (12:22 +0200)
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
source/libr2c2/train.h

index 599f2dcdf28b27d92a1401b9fe025d701c4949d1..eb5724b762a9777494ec71ec23acccf8bf81a787 100644 (file)
@@ -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<RouteRef>::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<<i)) && i!=route_path)
-                               {
-                                       path = i;
-                                       break;
-                               }
-
-                       entry = track.entry();
-                       break;
-               }
-
-               track = track.next(route->route->get_path(*track));
-
-               if(!track || track.looped())
-                       return false;
-       }
-
-       TrackIter track = TrackIter(&from, entry).next(path);
-       if(!track)
-               return false;
-
-       set<Track *> tracks;
-       for(list<RouteRef>::iterator i=routes.begin(); i!=routes.end(); ++i)
-               tracks.insert(i->route->get_tracks().begin(), i->route->get_tracks().end());
-       RefPtr<Route> 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<RouteRef>::iterator end = routes.end();
-       while(1)
-       {
-               for(list<RouteRef>::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<DataFile::Statement> &st) const
 
        if(!routes.empty())
        {
-               list<RouteRef>::const_iterator i = routes.begin();
-               for(; (i!=routes.end() && i->route->is_temporary()); ++i) ;
+               list<const Route *>::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<RouteRef>::iterator cur_route = routes.begin();
+       list<const Route *>::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<BlockIter>::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<RouteRef>::iterator &iter, Track &track)
+bool Train::advance_route(list<const Route *>::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<RouteRef>::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<RouteRef>::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<route_len*1.2;
-}
-
-
-Train::RouteRef::RouteRef(const Route *r, unsigned d):
-       route(r),
-       diversion(d)
-{ }
-
 
 Train::Loader::Loader(Train &t):
        DataFile::ObjectLoader<Train>(t),
index e16f726c5bebf78bbb56b091c82f11739cca1108..709140c9a6102e3dcb61a94ffc130894dfb10baf 100644 (file)
@@ -51,14 +51,6 @@ public:
        sigc::signal<void, const std::string &> signal_status_changed;
 
 private:
-       struct RouteRef
-       {
-               const Route *route;
-               unsigned diversion;
-
-               RouteRef(const Route *, unsigned = 0);
-       };
-
        typedef std::list<BlockIter> BlockList;
 
        Layout &layout;
@@ -84,7 +76,7 @@ private:
        bool reverse;
        Msp::Time::TimeStamp stop_timeout;
        unsigned functions;
-       std::list<RouteRef> routes;
+       std::list<const Route *> 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<RouteRef>::iterator &, Track &);
+       bool advance_route(std::list<const Route *>::iterator &, Track &);
        Route *create_lead_route(Route *, const Route *);
-       bool is_valid_diversion(const Route &, const TrackIter &);
 };
 
 } // namespace R2C2