From 4c787ea0227ee891b3f7dac3d071e607fbf8d109 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Thu, 21 Oct 2010 10:55:35 +0000 Subject: [PATCH] Better lead route generation --- source/libmarklin/train.cpp | 42 ++++++++++++++++++++++++------------- source/libmarklin/train.h | 2 +- 2 files changed, 28 insertions(+), 16 deletions(-) diff --git a/source/libmarklin/train.cpp b/source/libmarklin/train.cpp index baa58db..ccb7cc2 100644 --- a/source/libmarklin/train.cpp +++ b/source/libmarklin/train.cpp @@ -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::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 tracks; for(list::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 &btracks = i->block->get_tracks(); - set tracks(btracks.begin(), btracks.end()); - lead->add_tracks(tracks); + for(set::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; } diff --git a/source/libmarklin/train.h b/source/libmarklin/train.h index e675c4b..d9026c7 100644 --- a/source/libmarklin/train.h +++ b/source/libmarklin/train.h @@ -175,7 +175,7 @@ private: void release_blocks(std::list &, std::list::iterator, std::list::iterator); void reverse_blocks(std::list &) const; bool advance_route(std::list::iterator &, const Track &); - Route *create_lead_route(); + Route *create_lead_route(Route *, const Route *); bool is_valid_diversion(const Route &, const Track &, unsigned); }; -- 2.43.0