X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Flibmarklin%2Flayout.cpp;h=4e6620b2e1bcbb6704446efef85aabf5015c3b90;hb=02c9a9779954d993cb73fe5f7a72b0847e87f633;hp=3a6b6302d56ebf806c442ce8f8c808fb903a5091;hpb=6dc18b0e518407bd2a86602bae1e9bbae05da7c8;p=r2c2.git diff --git a/source/libmarklin/layout.cpp b/source/libmarklin/layout.cpp index 3a6b630..4e6620b 100644 --- a/source/libmarklin/layout.cpp +++ b/source/libmarklin/layout.cpp @@ -25,6 +25,8 @@ Layout::~Layout() { for(set::iterator i=tracks.begin(); i!=tracks.end(); ++i) delete *i; + for(map::iterator i=routes.begin(); i!=routes.end(); ++i) + delete i->second; } void Layout::add_track(Track &t) @@ -41,13 +43,23 @@ void Layout::remove_track(Track &t) void Layout::add_route(Route &r) { - if(routes.insert(&r).second) - signal_route_added.emit(r); + if(routes.count(r.get_name())) + throw KeyError("Duplicate route name"); + routes[r.get_name()] = &r; + signal_route_added.emit(r); +} + +Route &Layout::get_route(const string &name) const +{ + map::const_iterator i = routes.find(name); + if(i==routes.end()) + throw KeyError("Unknown route", name); + return *i->second; } void Layout::remove_route(Route &r) { - if(routes.erase(&r)) + if(routes.erase(r.get_name())) signal_route_removed.emit(r); } @@ -67,11 +79,11 @@ void Layout::save(const string &fn) writer.write(st); } - for(set::iterator i=routes.begin(); i!=routes.end(); ++i) + for(map::iterator i=routes.begin(); i!=routes.end(); ++i) { DataFile::Statement st("route"); - st.append((*i)->get_name()); - (*i)->save(st.sub); + st.append(i->first); + i->second->save(st.sub); writer.write(st); } } @@ -102,11 +114,13 @@ void Layout::check_links() void Layout::check_routes() { - for(set::iterator i=routes.begin(); i!=routes.end(); ++i) + for(map::iterator i=routes.begin(); i!=routes.end(); ++i) { - // We must copy the turnout map, since adding tracks to the route will (temporarily) mess it up - const map turnouts = (*i)->get_turnouts(); + /* We must copy the turnout map, since adding tracks to the route will + (temporarily) mess it up */ + const map turnouts = i->second->get_turnouts(); + // Find any turnout in the route Track *track = 0; unsigned trk_path = 0; for(set::const_iterator j=tracks.begin(); j!=tracks.end(); ++j) @@ -120,37 +134,50 @@ void Layout::check_routes() } } - (*i)->add_track(*track); + if(!track) + continue; + // Find an applicable endpoint const vector &eps = track->get_type().get_endpoints(); unsigned ep = 0; - for(unsigned j=0; jtraverse(ep, trk_path); - if(out_ep<0) - break; + // Traverse the track and get the next one + unsigned out_ep = track->traverse(ep, trk_path); Track *next = track->get_links()[out_ep]; if(!next || next == start) break; + ep = next->get_endpoint_by_link(*track); if(next->get_type().get_n_paths()>1) { + // Select correct path across the turnout, or break if we hit an unknown turnout map::const_iterator j = turnouts.find(next->get_turnout_id()); if(j==turnouts.end()) break; trk_path = j->second; } else + { trk_path = 0; - (*i)->add_track(*next); + + /* Start adding tracks when we find the first non-turnout. This + prevents the occurrence of ambiguities while adding the tracks */ + if(!start) + start = next; + } + + if(start) + i->second->add_track(*next); + track = next; } }