X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Flibmarklin%2Ftrain.cpp;h=5bc50d85ff23ee5011535e34e5e6142f6b08fccc;hb=e9653dffd0026fb3c02c91a4c0feca688a86c721;hp=baa58db0e813ee042141b589812f634f06163f2c;hpb=0e691a3893a07dc362c733869760e0d7d1109ea8;p=r2c2.git diff --git a/source/libmarklin/train.cpp b/source/libmarklin/train.cpp index baa58db..5bc50d8 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->has_track(*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->has_track(*first_ep.track)) + routes.push_front(create_lead_route(0, r)); } reserve_more(); @@ -230,10 +234,10 @@ void Train::set_route(const Route *r) signal_route_changed.emit(get_route()); } -void Train::go_to(const Track &to) +void Train::go_to(Track &to) { for(list::const_iterator i=cur_blocks.begin(); i!=cur_blocks.end(); ++i) - if(i->block->get_tracks().count(const_cast(&to))) + if(i->block->has_track(to)) { signal_arrived.emit(); set_route(0); @@ -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) @@ -309,7 +315,7 @@ bool Train::divert(Track &from) unsigned ep = track->get_endpoint_by_link(from); - set tracks; + set tracks; for(list::iterator i=routes.begin(); i!=routes.end(); ++i) tracks.insert(i->route->get_tracks().begin(), i->route->get_tracks().end()); Route *diversion = 0; @@ -342,12 +348,12 @@ bool Train::divert(Track &from) Track *next = track->get_link(track->traverse(ep, path)); for(list::iterator i=route; (end==routes.end() && i!=routes.end()); ++i) - if(i->route->get_tracks().count(next)) + if(i->route->has_track(*next)) end = i; if(end!=routes.end()) break; - else if(!diversion->get_tracks().count(next)) + else if(!diversion->has_track(*next)) throw Exception("Pathfinder returned a bad route"); ep = next->get_endpoint_by_link(*track); @@ -466,7 +472,7 @@ void Train::free_noncritical_blocks() Track *track = veh.get_track(); list::iterator block = cur_blocks.begin(); bool in_rsv = false; - while(block!=rsv_blocks.end() && !block->block->get_tracks().count(track)) + while(block!=rsv_blocks.end() && !block->block->has_track(*track)) { ++block; if(block==cur_blocks.end()) @@ -491,7 +497,7 @@ void Train::free_noncritical_blocks() entry = next->get_endpoint_by_link(*track); track = next; - if(!block->block->get_tracks().count(track)) + if(!block->block->has_track(*track)) { ++block; if(block==cur_blocks.end()) @@ -582,7 +588,7 @@ void Train::tick(const Time::TimeStamp &t, const Time::TimeDelta &dt) bool ok = false; for(list::const_iterator i=cur_blocks.begin(); (!ok && i!=cur_blocks.end()); ++i) - ok = i->block->get_tracks().count(track); + ok = i->block->has_track(*track); float d = get_real_speed(current_speed)*(dt/Time::sec); if(ok) @@ -758,7 +764,7 @@ void Train::sensor_event(unsigned addr, bool state) // Check if we've reached the next route if(routes.size()>1) { - const set &rtracks = (++routes.begin())->route->get_tracks(); + const set &rtracks = (++routes.begin())->route->get_tracks(); for(list::iterator j=rsv_blocks.begin(); j!=i; ++j) if(rtracks.count(j->block->get_endpoints()[j->entry].track)) { @@ -787,7 +793,7 @@ void Train::sensor_event(unsigned addr, bool state) list::iterator end = cur_blocks.begin(); for(list::iterator i=cur_blocks.begin(); i!=cur_blocks.end(); ++i) { - if(i->block->get_tracks().count(veh.get_track())) + if(i->block->has_track(*veh.get_track())) break; if(i->block->get_sensor_id()) { @@ -919,7 +925,7 @@ unsigned Train::reserve_more() break; } } - else if(!routes.empty() && routes.front().route->get_tracks().count(entry_ep.track)) + else if(!routes.empty() && routes.front().route->has_track(*entry_ep.track)) cur_route = routes.begin(); if(link->get_endpoints().size()<2) @@ -1111,7 +1117,7 @@ float Train::get_reserved_distance_until(const Block *until_block, bool back) co return 0; list::const_iterator block = cur_blocks.begin(); - while(block!=rsv_blocks.end() && !block->block->get_tracks().count(track)) + while(block!=rsv_blocks.end() && !block->block->has_track(*track)) { ++block; if(block==cur_blocks.end()) @@ -1140,7 +1146,7 @@ float Train::get_reserved_distance_until(const Block *until_block, bool back) co Track *next = track->get_link(track->traverse(entry)); - if(!block->block->get_tracks().count(next)) + if(!block->block->has_track(*next)) { if(back) { @@ -1268,54 +1274,60 @@ void Train::reverse_blocks(list &blocks) const i->entry = i->block->traverse(i->entry); } -bool Train::advance_route(list::iterator &iter, const Track &track) +bool Train::advance_route(list::iterator &iter, Track &track) { - while(iter!=routes.end() && !iter->route->get_tracks().count(&track)) + while(iter!=routes.end() && !iter->route->has_track(track)) ++iter; if(iter==routes.end()) return false; list::iterator next = iter; ++next; - if(next!=routes.end() && next->diversion && next->route->get_tracks().count(&track)) + if(next!=routes.end() && next->diversion && next->route->has_track(track)) iter = next; 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->has_track(**j)) + tracks.insert(*j); if(++i==cur_blocks.end()) i = rsv_blocks.begin(); } + lead->add_tracks(tracks); + return lead; } -bool Train::is_valid_diversion(const Route &diversion, const Track &from, unsigned from_ep) +bool Train::is_valid_diversion(const Route &diversion, Track &from, unsigned from_ep) { float diversion_len = 0; - const Track *track = &from; + Track *track = &from; unsigned ep = from_ep; - while(diversion.get_tracks().count(track)) + while(diversion.has_track(*track)) { unsigned path = 0; if(track->get_turnout_id()) path = diversion.get_turnout(track->get_turnout_id()); diversion_len += track->get_type().get_path_length(path); - const Track *next = track->get_link(track->traverse(ep, path)); + Track *next = track->get_link(track->traverse(ep, path)); ep = next->get_endpoint_by_link(*track); track = next; @@ -1327,7 +1339,7 @@ bool Train::is_valid_diversion(const Route &diversion, const Track &from, unsign if(!advance_route(route, from)) return false; - set visited; + set visited; float route_len = 0; track = &from; ep = from_ep; @@ -1338,14 +1350,14 @@ bool Train::is_valid_diversion(const Route &diversion, const Track &from, unsign path = route->route->get_turnout(track->get_turnout_id()); route_len += track->get_type().get_path_length(path); - if(track!=&from && diversion.get_tracks().count(track)) + if(track!=&from && diversion.has_track(*track)) break; if(visited.count(track)) return false; visited.insert(track); - const Track *next = track->get_link(track->traverse(ep, path)); + Track *next = track->get_link(track->traverse(ep, path)); ep = next->get_endpoint_by_link(*track); track = next;