]> git.tdb.fi Git - r2c2.git/blobdiff - source/libmarklin/train.cpp
Return null from Route::find if a route can't be found
[r2c2.git] / source / libmarklin / train.cpp
index 11ec776497e436c64eea49d3a8bcaecdf1e27e11..38f1c765aead156f1e6b6a16f2df9d8c542c1079 100644 (file)
@@ -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<Track *> tracks;
        for(list<RouteRef>::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<Route> 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<RouteRef>::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;
 }