]> git.tdb.fi Git - r2c2.git/commitdiff
Better lead route generation
authorMikko Rasa <tdb@tdb.fi>
Thu, 21 Oct 2010 10:55:35 +0000 (10:55 +0000)
committerMikko Rasa <tdb@tdb.fi>
Thu, 21 Oct 2010 10:55:35 +0000 (10:55 +0000)
source/libmarklin/train.cpp
source/libmarklin/train.h

index baa58db0e813ee042141b589812f634f06163f2c..ccb7cc25bbf8714706e549c3bb4cee6ff07e2b32 100644 (file)
@@ -214,15 +214,19 @@ void Train::set_route(const Route *r)
 
        if(r && !cur_blocks.empty())
        {
+               BlockRef &first = cur_blocks.front();
                BlockRef &last = (rsv_blocks.empty() ? cur_blocks.back() : rsv_blocks.back());
                BlockRef next = last.next();
-               const Block::Endpoint &ep = next.block->get_endpoints()[next.entry];
-               if(!r->get_tracks().count(ep.track))
-                       routes.push_front(Route::find(*ep.track, ep.track_ep, *r));
-
-               /* XXX This is sort of a hack, but it keeps divert() happy.  Need to come
-               up with a better solution when there is time. */
-               routes.push_front(create_lead_route());
+               const Block::Endpoint &first_ep = first.block->get_endpoints()[first.entry];
+               const Block::Endpoint &next_ep = next.block->get_endpoints()[next.entry];
+               if(!r->get_tracks().count(next_ep.track))
+               {
+                       Route *lead = Route::find(*next_ep.track, next_ep.track_ep, *r);
+                       create_lead_route(lead, lead);
+                       routes.push_front(lead);
+               }
+               else if(!r->get_tracks().count(first_ep.track))
+                       routes.push_front(create_lead_route(0, r));
        }
 
        reserve_more();
@@ -246,7 +250,9 @@ void Train::go_to(const Track &to)
        BlockRef next = last.next();
        const Block::Endpoint &ep = next.block->get_endpoints()[next.entry];
 
-       set_route(Route::find(*ep.track, ep.track_ep, to));
+       Route *route = Route::find(*ep.track, ep.track_ep, to);
+       create_lead_route(route, route);
+       set_route(route);
 }
 
 bool Train::divert(Track &from)
@@ -1283,23 +1289,29 @@ bool Train::advance_route(list<RouteRef>::iterator &iter, const Track &track)
        return true;
 }
 
-Route *Train::create_lead_route()
+Route *Train::create_lead_route(Route *lead, const Route *target)
 {
-       Route *lead = new Route(layout);
-       lead->set_name("Lead");
-       lead->set_temporary(true);
+       if(!lead)
+       {
+               lead = new Route(layout);
+               lead->set_name("Lead");
+               lead->set_temporary(true);
+       }
 
+       set<const Track *> tracks;
        for(list<BlockRef>::iterator i=cur_blocks.begin(); i!=rsv_blocks.end(); )
        {
-               // XXX Make Route eat non-const tracks to get rid of this idiocy and various const_casts
                const set<Track *> &btracks = i->block->get_tracks();
-               set<const Track *> tracks(btracks.begin(), btracks.end());
-               lead->add_tracks(tracks);
+               for(set<Track *>::const_iterator j=btracks.begin(); j!=btracks.end(); ++j)
+                       if(!target || !target->get_tracks().count(*j))
+                               tracks.insert(*j);
 
                if(++i==cur_blocks.end())
                        i = rsv_blocks.begin();
        }
 
+       lead->add_tracks(tracks);
+
        return lead;
 }
 
index e675c4b8cadba41a749e38464b704a2ee957ad56..d9026c7be84ba78299874d63305b92c204176f82 100644 (file)
@@ -175,7 +175,7 @@ private:
        void release_blocks(std::list<BlockRef> &, std::list<BlockRef>::iterator, std::list<BlockRef>::iterator);
        void reverse_blocks(std::list<BlockRef> &) const;
        bool advance_route(std::list<RouteRef>::iterator &, const Track &);
-       Route *create_lead_route();
+       Route *create_lead_route(Route *, const Route *);
        bool is_valid_diversion(const Route &, const Track &, unsigned);
 };