From: Mikko Rasa Date: Thu, 17 Jan 2013 10:48:58 +0000 (+0200) Subject: Use a dedicated exception class for route errors X-Git-Url: http://git.tdb.fi/?a=commitdiff_plain;h=a20b8421d002629a9f4d97c0c378e9f9cb29e292;p=r2c2.git Use a dedicated exception class for route errors --- diff --git a/source/libr2c2/route.cpp b/source/libr2c2/route.cpp index 78f96a6..aabe880 100644 --- a/source/libr2c2/route.cpp +++ b/source/libr2c2/route.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include "layout.h" #include "route.h" #include "track.h" @@ -127,6 +128,20 @@ Route *create_route(const TrackIter &from, const Pred &goal) namespace R2C2 { +string bad_route::get_message(RouteValidityMask valid) +{ + const char *reasons[3]; + unsigned i = 0; + if(!(valid&1)) + reasons[i++] = "unlinked"; + else if(!(valid&2)) + reasons[i++] = "branching"; + else if(!(valid&4)) + reasons[i++] = "not smooth"; + return join(reasons, reasons+i, ", "); +} + + Route::Route(Layout &l): layout(l), temporary(false) @@ -241,13 +256,9 @@ void Route::add_track(Track &trk) if(!tracks.empty()) { - unsigned valid = check_validity(trk); - if(!(valid&1)) - throw Exception("Not linked to existing tracks"); - else if(!(valid&2)) - throw Exception("Branching routes not allowed"); - else if(!(valid&4)) - throw Exception("Route must be smooth"); + RouteValidityMask valid = check_validity(trk); + if(valid!=ROUTE_VALID) + throw bad_route(valid); } tracks.insert(&trk); @@ -263,18 +274,17 @@ void Route::add_tracks(const set &trks) while(!pending.empty()) { - bool found = false; + RouteValidityMask valid = ROUTE_INVALID; for(set::const_iterator i=pending.begin(); i!=pending.end(); ++i) - if(tracks.empty() || check_validity(**i)==7) + if(tracks.empty() || (valid=check_validity(**i))==ROUTE_VALID) { tracks.insert(*i); pending.erase(*i); - found = true; break; } - if(!found) - throw Exception("Could not add all tracks to route"); + if(valid!=ROUTE_VALID) + throw bad_route(valid); } update_turnouts(); @@ -319,9 +329,9 @@ void Route::save(list &st) const st.push_back((DataFile::Statement("turnout"), i->first, i->second)); } -unsigned Route::check_validity(Track &trk) const +RouteValidityMask Route::check_validity(Track &trk) const { - unsigned result = 4; + unsigned result = ROUTE_SMOOTH; const vector &links = trk.get_links(); for(vector::const_iterator i=links.begin(); i!=links.end(); ++i) { @@ -331,7 +341,7 @@ unsigned Route::check_validity(Track &trk) const continue; // Linked to an existing track - good - result |= 1; + result |= ROUTE_LINKED; if(unsigned tid = (*i)->get_turnout_id()) { @@ -341,7 +351,7 @@ unsigned Route::check_validity(Track &trk) const { // Linking to a turnout with path set is only good if we're continuing that path if(ep.paths&(1<get_type().get_endpoint(j); if(!(ep.paths&ep2.paths)) // Impossible path through the turnout - not good - result &= 3; + result &= ~ROUTE_SMOOTH; } // Only good if at most one other track is linked to the turnout if(count<=1) - result |= 2; + result |= ROUTE_LINEAR; } } else // Linked to something linear - good - result |= 2; + result |= ROUTE_LINEAR; } - return result; + return static_cast(result); } void Route::track_removed(Track &t) diff --git a/source/libr2c2/route.h b/source/libr2c2/route.h index 4f5d056..5ea86be 100644 --- a/source/libr2c2/route.h +++ b/source/libr2c2/route.h @@ -14,6 +14,26 @@ class Track; class TrackIter; class Zone; +enum RouteValidityMask +{ + ROUTE_INVALID = 0, + ROUTE_LINKED = 1, + ROUTE_LINEAR = 2, + ROUTE_SMOOTH = 4, + ROUTE_VALID = 7 +}; + +class bad_route: public std::logic_error +{ +public: + bad_route(RouteValidityMask m): std::logic_error(get_message(m)) { } + virtual ~bad_route() throw() { } + +private: + static std::string get_message(RouteValidityMask); +}; + + class Route: public sigc::trackable { public: @@ -60,7 +80,7 @@ public: bool has_track(Track &) const; void save(std::list &) const; private: - unsigned check_validity(Track &) const; + RouteValidityMask check_validity(Track &) const; void track_removed(Track &); public: