X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Flibr2c2%2Froute.cpp;h=ffb420adabfa9cbd7911dad2e525e7a0a0b22afb;hb=eb9c7f5200da4f3f31b41233be8cee397cb6abb9;hp=be2eefc258ea8cfc7e135932e9ab325c1611ee96;hpb=64340dad429ba4040538fc06b6882aabdb489925;p=r2c2.git diff --git a/source/libr2c2/route.cpp b/source/libr2c2/route.cpp index be2eefc..ffb420a 100644 --- a/source/libr2c2/route.cpp +++ b/source/libr2c2/route.cpp @@ -83,9 +83,9 @@ list dijkstra(const TrackIter &from, const Pred &goal) break; } - unsigned paths = lowest.track.endpoint().paths; - for(unsigned i=0; paths>>i; ++i) - if(paths&(1<>i; ++i) + if(ep.has_path(i)) { TrackIter next = lowest.track.next(i); if(!next) @@ -128,31 +128,16 @@ Route *create_route(const TrackIter &from, const Pred &goal) namespace R2C2 { -string bad_route::get_message(RouteValidityMask valid) -{ - const char *reasons[3]; - unsigned i = 0; - if(!(valid&1)) - reasons[i++] = "unlinked"; - else if(!(valid&2)) - reasons[i++] = "branching"; - else if(!(valid&4)) - reasons[i++] = "not smooth"; - return join(reasons, reasons+i, ", "); -} - - Route::Route(Layout &l): - layout(l), + TrackChain(l), temporary(false) { - layout.add_route(*this); - layout.signal_track_removed.connect(sigc::mem_fun(this, &Route::track_removed)); + layout.add(*this); } Route::~Route() { - layout.remove_route(*this); + layout.remove(*this); } void Route::set_name(const string &n) @@ -196,9 +181,9 @@ void Route::update_turnouts() if(unsigned tid2 = links[j]->get_turnout_id()) { - const TrackType::Endpoint &ep = links[j]->get_type().get_endpoint(links[j]->get_endpoint_by_link(**i)); + const TrackType::Endpoint &ep = links[j]->get_type().get_endpoint(links[j]->get_link_slot(**i)); int p = get_turnout(tid2); - if(p>=0 && !(ep.paths&(1<=0 && !ep.has_path(p)) { // The linked track is a turnout and has a path which is incompatible with this endpoint mask &= ~endpoints[j].paths; @@ -249,50 +234,12 @@ unsigned Route::get_path(Track &trk) const return trk.get_active_path(); } -void Route::add_track(Track &trk) -{ - if(tracks.count(&trk)) - return; - - if(!tracks.empty()) - { - RouteValidityMask valid = check_validity(trk); - if(valid!=ROUTE_VALID) - throw bad_route(valid); - } - - tracks.insert(&trk); - update_turnouts(); -} - -void Route::add_tracks(const set &trks) +void Route::add_track_chain(const TrackIter &start, const TurnoutMap &trnts) { - set pending; - for(set::const_iterator i=trks.begin(); i!=trks.end(); ++i) - if(!tracks.count(*i)) - pending.insert(*i); + if(!start) + throw invalid_argument("Route::add_track_chain"); - while(!pending.empty()) - { - RouteValidityMask valid = ROUTE_INVALID; - for(set::const_iterator i=pending.begin(); i!=pending.end(); ++i) - if(tracks.empty() || (valid=check_validity(**i))==ROUTE_VALID) - { - tracks.insert(*i); - pending.erase(*i); - break; - } - - if(valid!=ROUTE_VALID) - throw bad_route(valid); - } - - update_turnouts(); -} - -void Route::add_track_chain(Track &start, unsigned ep, const TurnoutMap &trnts) -{ - TrackIter iter(&start, ep); + TrackIter iter = start; while(iter) { if(iter->get_type().is_dead_end()) @@ -317,9 +264,9 @@ void Route::add_track_chain(Track &start, unsigned ep, const TurnoutMap &trnts) } } -bool Route::has_track(Track &t) const +void Route::on_track_added(Track &) { - return tracks.count(&t); + update_turnouts(); } void Route::save(list &st) const @@ -329,74 +276,6 @@ void Route::save(list &st) const st.push_back((DataFile::Statement("turnout"), i->first, i->second)); } -RouteValidityMask Route::check_validity(Track &trk) const -{ - unsigned result = ROUTE_SMOOTH; - const vector &links = trk.get_links(); - for(vector::const_iterator i=links.begin(); i!=links.end(); ++i) - { - if(!*i) - continue; - if(!tracks.count(*i)) - continue; - - // Linked to an existing track - good - result |= ROUTE_LINKED; - - if(unsigned tid = (*i)->get_turnout_id()) - { - const TrackType::Endpoint &ep = (*i)->get_type().get_endpoint((*i)->get_endpoint_by_link(trk)); - int path = get_turnout(tid); - if(path>=0) - { - // Linking to a turnout with path set is only good if we're continuing that path - if(ep.paths&(1< &tlinks = (*i)->get_links(); - unsigned count = 0; - for(unsigned j=0; jget_turnout_id(); - if(tid2) - { - const TrackType::Endpoint &ep2 = tlinks[j]->get_type().get_endpoint(tlinks[j]->get_endpoint_by_link(**i)); - path = get_turnout(tid2); - // Ignore a linked turnout with some other path set - if(path>=0 && !(ep2.paths&(1<get_type().get_endpoint(j); - if(!(ep.paths&ep2.paths)) - // Impossible path through the turnout - not good - result &= ~ROUTE_SMOOTH; - } - - // Only good if at most one other track is linked to the turnout - if(count<=1) - result |= ROUTE_LINEAR; - } - } - else - // Linked to something linear - good - result |= ROUTE_LINEAR; - } - - return static_cast(result); -} - -void Route::track_removed(Track &t) -{ - tracks.erase(&t); -} - Route *Route::find(const TrackIter &from, Track &to) { return create_route(from, TrackMatch(to)); @@ -427,7 +306,7 @@ Route::Loader::Loader(Route &r): void Route::Loader::finish() { - const set <racks = obj.layout.get_tracks(); + const set <racks = obj.layout.get_all(); for(set::const_iterator i=ltracks.begin(); i!=ltracks.end(); ++i) { unsigned tid = (*i)->get_turnout_id(); @@ -438,16 +317,15 @@ void Route::Loader::finish() if(j==turnouts.end()) continue; - unsigned path_mask = 1<second; const vector &eps = (*i)->get_type().get_endpoints(); for(unsigned k=0; ksecond)) { Track *link = (*i)->get_link(k); if(!obj.tracks.count(link)) - obj.add_track_chain(*link, link->get_endpoint_by_link(**i), turnouts); + obj.add_track_chain(TrackIter(link, link->get_link_slot(**i)), turnouts); if(!obj.tracks.count(*i)) - obj.add_track_chain(**i, k, turnouts); + obj.add_track_chain(TrackIter(*i, k), turnouts); break; }