From: Mikko Rasa Date: Wed, 27 Oct 2010 18:49:03 +0000 (+0000) Subject: Return null from Route::find if a route can't be found X-Git-Url: http://git.tdb.fi/?a=commitdiff_plain;h=e13742268b7030f8d6152858d39f1c6b43f94c88;p=r2c2.git Return null from Route::find if a route can't be found Avoid setting a route that can't be reached Stop timetable if route can't be set Put diversion route in RefPtr so it gets cleaned if we bail out --- diff --git a/source/engineer/routeselect.cpp b/source/engineer/routeselect.cpp index 6cda460..cd1e704 100644 --- a/source/engineer/routeselect.cpp +++ b/source/engineer/routeselect.cpp @@ -60,7 +60,8 @@ void RouteSelect::on_ok_clicked() ++i; } - train.set_route(*i); + if(!train.set_route(*i)) + engineer.set_status("Could not set route"); } else train.set_route(0); diff --git a/source/engineer/trainpanel.cpp b/source/engineer/trainpanel.cpp index 96aa00d..cc53499 100644 --- a/source/engineer/trainpanel.cpp +++ b/source/engineer/trainpanel.cpp @@ -288,12 +288,6 @@ void TrainPanel::go_to(Track *track, unsigned) { pick_conn.disconnect(); - try - { - train.go_to(*track); - } - catch(const Exception &e) - { - engineer.set_status(e.what()); - } + if(!train.go_to(*track)) + engineer.set_status("Could not set route"); } diff --git a/source/libmarklin/route.cpp b/source/libmarklin/route.cpp index 970c2d7..daa044f 100644 --- a/source/libmarklin/route.cpp +++ b/source/libmarklin/route.cpp @@ -110,9 +110,6 @@ list dijkstra(Track &from, unsigned ep, const Pred &goal) } } - if(!final) - throw InvalidParameterValue("Could not find a route"); - list result; for(Node *node=final; node; node=node->prev) result.push_front(node->track); @@ -125,6 +122,9 @@ Route *create_route(Track &from, unsigned ep, const Pred &goal) { list tracks = dijkstra(from, ep, goal); + if(tracks.empty()) + return 0; + Route *route = new Route(from.get_layout()); for(list::iterator i=tracks.begin(); i!=tracks.end(); ++i) route->add_track(**i); diff --git a/source/libmarklin/timetable.cpp b/source/libmarklin/timetable.cpp index afe83ff..a699fc8 100644 --- a/source/libmarklin/timetable.cpp +++ b/source/libmarklin/timetable.cpp @@ -90,7 +90,8 @@ void Timetable::tick(const Time::TimeStamp &t) switch(row.type) { case GOTO: - train.go_to(**parse_location(row.get_param(0)).get_tracks().begin()); + if(!train.go_to(**parse_location(row.get_param(0)).get_tracks().begin())) + set_enabled(false); break; case TRAVEL: pending_block = &parse_location(row.get_param(0)); @@ -116,7 +117,8 @@ void Timetable::tick(const Time::TimeStamp &t) train.set_control("reverse", !train.get_control("reverse")); break; case ROUTE: - train.set_route(&train.get_layout().get_route(row.get_param(0))); + if(!train.set_route(&train.get_layout().get_route(row.get_param(0)))) + set_enabled(false); break; } diff --git a/source/libmarklin/train.cpp b/source/libmarklin/train.cpp index 11ec776..38f1c76 100644 --- a/source/libmarklin/train.cpp +++ b/source/libmarklin/train.cpp @@ -204,42 +204,48 @@ void Train::set_timetable(Timetable *tt) timetable = tt; } -void Train::set_route(const Route *r) +bool Train::set_route(const Route *r) { free_noncritical_blocks(); - routes.clear(); - if(r) - routes.push_back(r); - end_of_route = false; - + Route *lead = 0; if(r && !cur_blocks.empty()) { TrackIter first = cur_blocks.front().track_iter(); TrackIter next = (rsv_blocks.empty() ? cur_blocks : rsv_blocks).back().next().track_iter(); if(!r->has_track(*next)) { - Route *lead = Route::find(*next, next.entry(), *r); + lead = Route::find(*next, next.entry(), *r); + if(!lead) + return false; create_lead_route(lead, lead); routes.push_front(lead); } else if(!r->has_track(*first)) - routes.push_front(create_lead_route(0, r)); + lead = create_lead_route(0, r); } + routes.clear(); + if(lead) + routes.push_back(lead); + if(r) + routes.push_back(r); + end_of_route = false; + reserve_more(); signal_route_changed.emit(get_route()); + + return true; } -void Train::go_to(Track &to) +bool Train::go_to(Track &to) { for(BlockList::const_iterator i=cur_blocks.begin(); i!=cur_blocks.end(); ++i) if((*i)->has_track(to)) { signal_arrived.emit(); - set_route(0); - return; + return set_route(0); } free_noncritical_blocks(); @@ -247,8 +253,10 @@ void Train::go_to(Track &to) TrackIter next = (rsv_blocks.empty() ? cur_blocks : rsv_blocks).back().next().track_iter(); Route *route = Route::find(*next, next.entry(), to); + if(!route) + return false; create_lead_route(route, route); - set_route(route); + return set_route(route); } bool Train::divert(Track &from) @@ -311,25 +319,16 @@ bool Train::divert(Track &from) 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; - try - { - diversion = Route::find(*track, ep, tracks); - } - catch(const Msp::Exception &) - { + RefPtr diversion = Route::find(*track, ep, 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, from, from_ep)) - { - delete diversion; return false; - } // Follow the diversion route until we get back to the original route list::iterator end = routes.end(); @@ -342,7 +341,7 @@ bool Train::divert(Track &from) if(end!=routes.end()) break; else if(!diversion->has_track(*track)) - throw Exception("Pathfinder returned a bad route"); + throw LogicError("Pathfinder returned a bad route"); unsigned tid = track->get_turnout_id(); track = track.next(tid ? diversion->get_turnout(tid) : 0); @@ -356,7 +355,7 @@ bool Train::divert(Track &from) ++route; routes.erase(route, end); } - routes.insert(end, RouteRef(diversion, from.get_turnout_id())); + routes.insert(end, RouteRef(diversion.release(), from.get_turnout_id())); return true; } diff --git a/source/libmarklin/train.h b/source/libmarklin/train.h index f267263..4c4d1c3 100644 --- a/source/libmarklin/train.h +++ b/source/libmarklin/train.h @@ -134,8 +134,8 @@ public: void set_timetable(Timetable *); Timetable *get_timetable() { return timetable; } - void set_route(const Route *); - void go_to(Track &); + bool set_route(const Route *); + bool go_to(Track &); bool divert(Track &); const Route *get_route() const; void place(Block &, unsigned);