From e39a3bb041867d6b469bb26278ea0b05ebea0277 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Fri, 23 Apr 2010 17:05:18 +0000 Subject: [PATCH] Mark generated routes as temporary and don't show or save them Fix a segfault with unplaced trains Handle end-of-line gracefully in various places --- source/engineer/routeselect.cpp | 26 +++++++++++++++++++------- source/libmarklin/layout.cpp | 8 ++++++++ source/libmarklin/route.cpp | 10 +++++++++- source/libmarklin/route.h | 3 +++ source/libmarklin/train.cpp | 19 ++++++++++++++++++- 5 files changed, 57 insertions(+), 9 deletions(-) diff --git a/source/engineer/routeselect.cpp b/source/engineer/routeselect.cpp index 3413220..c285f35 100644 --- a/source/engineer/routeselect.cpp +++ b/source/engineer/routeselect.cpp @@ -32,12 +32,14 @@ RouteSelect::RouteSelect(Engineer &e, const GLtk::Resources &r, Train &t): drp_route->set_selected_index(0); const map &routes = engineer.get_layout().get_routes(); unsigned n = 1; - for(map::const_iterator i=routes.begin(); i!=routes.end(); ++i, ++n) - { - drp_route->append(i->second->get_name()); - if(i->second==train.get_route()) - drp_route->set_selected_index(n); - } + for(map::const_iterator i=routes.begin(); i!=routes.end(); ++i) + if(!i->second->is_temporary()) + { + drp_route->append(i->second->get_name()); + if(i->second==train.get_route()) + drp_route->set_selected_index(n); + ++n; + } } void RouteSelect::on_ok_clicked() @@ -46,7 +48,17 @@ void RouteSelect::on_ok_clicked() { const map &routes = engineer.get_layout().get_routes(); map::const_iterator i = routes.begin(); - advance(i, drp_route->get_selected_index()-1); + unsigned n = drp_route->get_selected_index()-1; + while(i!=routes.end()) + { + if(!i->second->is_temporary()) + { + if(!n) + break; + --n; + } + ++i; + } train.set_route(i->second); } diff --git a/source/libmarklin/layout.cpp b/source/libmarklin/layout.cpp index af88d7d..e67fbc2 100644 --- a/source/libmarklin/layout.cpp +++ b/source/libmarklin/layout.cpp @@ -237,6 +237,9 @@ void Layout::save(const string &fn) for(map::iterator i=routes.begin(); i!=routes.end(); ++i) { + if(i->second->is_temporary()) + continue; + DataFile::Statement st("route"); st.append(i->first); i->second->save(st.sub); @@ -287,6 +290,9 @@ void Layout::check_routes() { for(map::iterator i=routes.begin(); i!=routes.end(); ++i) { + if(i->second->is_temporary()) + continue; + /* We must copy the turnout map, since adding tracks to the route will (temporarily) mess it up */ const map turnouts = i->second->get_turnouts(); @@ -322,6 +328,8 @@ void Layout::check_routes() while(1) { // Traverse the track and get the next one + if(track->get_type().get_endpoints().size()<2) + break; unsigned out_ep = track->traverse(ep, trk_path); Track *next = track->get_links()[out_ep]; if(!next || next == start) diff --git a/source/libmarklin/route.cpp b/source/libmarklin/route.cpp index ace8d0b..7ecd473 100644 --- a/source/libmarklin/route.cpp +++ b/source/libmarklin/route.cpp @@ -130,6 +130,8 @@ Route *create_route(const Track &from, unsigned ep, const Pred &goal) for(list::iterator i=tracks.begin(); i!=tracks.end(); ++i) route->add_track(**i); + route->set_temporary(true); + return route; } @@ -140,7 +142,8 @@ namespace Marklin { Route::Route(Layout &l, const string &n): layout(l), - name(n) + name(n), + temporary(false) { layout.add_route(*this); layout.signal_track_removed.connect(sigc::mem_fun(this, &Route::track_removed)); @@ -151,6 +154,11 @@ Route::~Route() layout.remove_route(*this); } +void Route::set_temporary(bool t) +{ + temporary = t; +} + int Route::get_turnout(unsigned id) const { map::const_iterator i = turnouts.find(id); diff --git a/source/libmarklin/route.h b/source/libmarklin/route.h index 89788e3..010bb87 100644 --- a/source/libmarklin/route.h +++ b/source/libmarklin/route.h @@ -33,6 +33,7 @@ public: private: Layout &layout; std::string name; + bool temporary; std::set tracks; std::map turnouts; @@ -41,6 +42,8 @@ public: ~Route(); const std::string &get_name() const { return name; } + void set_temporary(bool); + bool is_temporary() const { return temporary; } int get_turnout(unsigned) const; const std::map &get_turnouts() const { return turnouts; } void add_track(const Track &); diff --git a/source/libmarklin/train.cpp b/source/libmarklin/train.cpp index 0c74172..ed57dd7 100644 --- a/source/libmarklin/train.cpp +++ b/source/libmarklin/train.cpp @@ -262,6 +262,8 @@ float Train::get_reserved_distance() const const VehicleType &vtype = veh.get_type(); Track *track = veh.get_track(); + if(!track) + return 0; unsigned entry = veh.get_entry(); float result = -vtype.get_length()/2; @@ -281,6 +283,9 @@ float Train::get_reserved_distance() const result += track->get_type().get_path_length(track->get_active_path()); first = false; + if(track->get_type().get_endpoints().size()<2) + return result; + unsigned exit = track->traverse(entry); Track *next = track->get_link(exit); @@ -390,7 +395,12 @@ void Train::save(list &st) const } if(route) - st.push_back((DataFile::Statement("route"), route->get_name())); + { + if(!route->is_temporary()) + st.push_back((DataFile::Statement("route"), route->get_name())); + else if(next_route && !next_route->is_temporary()) + st.push_back((DataFile::Statement("route"), next_route->get_name())); + } if(timetable) { @@ -592,6 +602,13 @@ unsigned Train::reserve_more() unsigned good_sens = nsens; while(good_sens<3) { + if(last->block->get_endpoints().size()<2) + { + good = last; + good_sens = nsens; + break; + } + // Traverse to the next block unsigned exit = last->block->traverse(last->entry); Block *link = last->block->get_link(exit); -- 2.45.2