]> git.tdb.fi Git - r2c2.git/commitdiff
Return null from Route::find if a route can't be found
authorMikko Rasa <tdb@tdb.fi>
Wed, 27 Oct 2010 18:49:03 +0000 (18:49 +0000)
committerMikko Rasa <tdb@tdb.fi>
Wed, 27 Oct 2010 18:49:03 +0000 (18:49 +0000)
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

source/engineer/routeselect.cpp
source/engineer/trainpanel.cpp
source/libmarklin/route.cpp
source/libmarklin/timetable.cpp
source/libmarklin/train.cpp
source/libmarklin/train.h

index 6cda460c810652b42b5adb89641f6093ffe347fd..cd1e7042e846b730ca180b71a96efe4ff21e5f29 100644 (file)
@@ -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);
index 96aa00df6de1816a3cbea78cb50d22570e965d28..cc53499050a419b7c647b76f36d908516b11ba14 100644 (file)
@@ -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");
 }
index 970c2d79dec63574691656f177af205208a3f751..daa044f9b9b4054b774421df3e6ada5168f76c43 100644 (file)
@@ -110,9 +110,6 @@ list<Track *> dijkstra(Track &from, unsigned ep, const Pred &goal)
                }
        }
 
-       if(!final)
-               throw InvalidParameterValue("Could not find a route");
-
        list<Track *> 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<Track *> tracks = dijkstra(from, ep, goal);
 
+       if(tracks.empty())
+               return 0;
+
        Route *route = new Route(from.get_layout());
        for(list<Track *>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
                route->add_track(**i);
index afe83ff867376004753b75c60408b904f5f36c48..a699fc8c14b39cc51db86e64323a51e7a96fa654 100644 (file)
@@ -90,7 +90,8 @@ void Timetable::tick(const Time::TimeStamp &t)
                switch(row.type)
                {
                case GOTO:
-                       train.go_to(**parse_location(row.get_param<string>(0)).get_tracks().begin());
+                       if(!train.go_to(**parse_location(row.get_param<string>(0)).get_tracks().begin()))
+                               set_enabled(false);
                        break;
                case TRAVEL:
                        pending_block = &parse_location(row.get_param<string>(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<string>(0)));
+                       if(!train.set_route(&train.get_layout().get_route(row.get_param<string>(0))))
+                               set_enabled(false);
                        break;
                }
 
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;
 }
index f267263cb9efbfa22cc804c4eb47c50ea5c972d9..4c4d1c353cb3145d566d7a5917d605c73cc02b74 100644 (file)
@@ -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);