]> git.tdb.fi Git - r2c2.git/blobdiff - source/libr2c2/tracktype.cpp
Rework article numbers
[r2c2.git] / source / libr2c2 / tracktype.cpp
index e9136ac741e704e574199f0d1630a499d6844306..51b685f5ceed7964e54bf6ef26b84b3a83f41a89 100644 (file)
@@ -1,5 +1,7 @@
 #include <cmath>
+#include <msp/datafile/collection.h>
 #include <msp/geometry/union.h>
+#include "trackappearance.h"
 #include "tracktype.h"
 
 using namespace std;
@@ -7,12 +9,24 @@ using namespace Msp;
 
 namespace R2C2 {
 
-TrackType::TrackType(const ArticleNumber &an):
-       ObjectType(an),
+TrackType::TrackType():
+       appearance(0),
        state_bits(0),
        autofit_preference(1)
 { }
 
+const TrackAppearance &TrackType::get_appearance() const
+{
+       if(!appearance)
+               throw logic_error("no appearance");
+       return *appearance;
+}
+
+float TrackType::get_gauge() const
+{
+       return get_appearance().get_gauge();
+}
+
 float TrackType::get_total_length() const
 {
        return get_path_length(-1);
@@ -43,6 +57,36 @@ unsigned TrackType::get_n_paths() const
        return n;
 }
 
+unsigned TrackType::coerce_path(unsigned entry, unsigned path) const
+{
+       const Endpoint &ep = get_endpoint(entry);
+       if(ep.has_path(path))
+               return path;
+
+       unsigned paths = get_paths();
+       if(paths>>(1<<state_bits))
+       {
+               /* There are more paths than can be expressed with state_bits, so
+               multiple paths are set at once.  See if one of the alternatives fits. */
+               unsigned step = 1<<state_bits;
+               for(unsigned p=path+step; paths>>p; p+=step)
+                       if(ep.has_path(p))
+                               return p;
+       }
+
+       // Find an endpoint that's connected to the entry and has the requested path
+       for(vector<Endpoint>::const_iterator i=endpoints.begin(); i!=endpoints.end(); ++i)
+               if(i->has_path(path) && i->has_common_paths(ep))
+               {
+                       unsigned p = 1;
+                       for(unsigned m=i->paths&ep.paths; m>>p; ++p) ;
+                       return p-1;
+               }
+
+       // TODO crossings fall here
+       throw logic_error("TrackType::coerce_path");
+}
+
 bool TrackType::is_turnout() const
 {
        return endpoints.size()>2;
@@ -177,10 +221,12 @@ TrackType::Endpoint::Endpoint(float x, float y, const Angle &d, unsigned p):
 { }
 
 
-TrackType::Loader::Loader(TrackType &t):
+TrackType::Loader::Loader(TrackType &t, Collection &c):
        DataFile::DerivedObjectLoader<TrackType, ObjectType::Loader>(t),
+       coll(c),
        state_bits_set(false)
 {
+       add("appearance",  &TrackType::appearance);
        add("autofit_preference", &TrackType::autofit_preference);
        add("object",      &TrackType::object);
        add("state_bits",  &Loader::state_bits);