]> git.tdb.fi Git - r2c2.git/blobdiff - source/libr2c2/zone.cpp
Allow zones with no qualifier or no number
[r2c2.git] / source / libr2c2 / zone.cpp
index 52e3c281d8175254474cef140ea4217774c3c3e9..eb5d102b8414570ff6d01578b04994d675701205 100644 (file)
@@ -13,7 +13,8 @@ namespace R2C2 {
 Zone::Zone(Layout &l):
        TrackChain(l),
        number(0),
-       up_end(-1)
+       up_end(-1),
+       preferred_dir(UNSPECIFIED)
 {
        layout.add(*this);
 }
@@ -55,6 +56,15 @@ void Zone::update_name()
        TrackChain::set_name(full_name);
 }
 
+void Zone::on_track_added(Track &track)
+{
+       if(preferred_dir)
+       {
+               TrackIter iter = iter_for(track, preferred_dir==UP ? DOWN : UP);
+               track.set_preferred_exit(iter.entry());
+       }
+}
+
 void Zone::set_direction_towards(Track &track, Direction dir)
 {
        if(dir==UNSPECIFIED)
@@ -78,9 +88,33 @@ void Zone::set_direction_towards(Track &track, Direction dir)
        throw logic_error("internal error (valid track not linked to ends)");
 }
 
+void Zone::set_preferred_direction(Direction d)
+{
+       if(up_end<0)
+               throw logic_error("no direction");
+
+       preferred_dir = d;
+
+       if(preferred_dir)
+       {
+               TrackIter iter = get_end(preferred_dir).reverse();
+               while(iter && tracks.count(iter.track()))
+               {
+                       iter->set_preferred_exit(iter.entry());
+                       iter = next_iter(iter);
+               }
+       }
+       else
+       {
+               for(TrackSet::iterator i=tracks.begin(); i!=tracks.end(); ++i)
+                       (*i)->set_preferred_exit(-1);
+       }
+}
+
 void Zone::clear_direction()
 {
        up_end = -1;
+       preferred_dir = UNSPECIFIED;
 }
 
 TrackIter Zone::iter_for(Track &track, Direction dir) const
@@ -113,16 +147,6 @@ TrackIter Zone::iter_for(Track &track, Direction dir) const
        return TrackIter();
 }
 
-TrackIter Zone::get_end(Direction dir) const
-{
-       if(dir==UNSPECIFIED)
-               return ends[0];
-       if(up_end<0)
-               return TrackIter();
-
-       return ends[up_end^(dir==DOWN)];
-}
-
 TrackIter Zone::next_iter(const TrackIter &iter) const
 {
        TrackIter next_outside;
@@ -140,6 +164,16 @@ TrackIter Zone::next_iter(const TrackIter &iter) const
        return next_outside;
 }
 
+TrackIter Zone::get_end(Direction dir) const
+{
+       if(dir==UNSPECIFIED)
+               return ends[0];
+       if(up_end<0)
+               return TrackIter();
+
+       return ends[up_end^(dir==DOWN)];
+}
+
 void Zone::save(list<DataFile::Statement> &st) const
 {
        st.push_back((DataFile::Statement("group"), group));
@@ -173,12 +207,19 @@ void Zone::save(list<DataFile::Statement> &st) const
                                break;
                        }
                }
+
+               if(preferred_dir)
+                       st.push_back((DataFile::Statement("preferred_direction"), preferred_dir));
        }
 }
 
 DataFile::Statement Zone::save_reference() const
 {
-       return (DataFile::Statement("zone"), group, number);
+       DataFile::Statement st("zone");
+       st.append(group);
+       if(number)
+               st.append(number);
+       return st;
 }
 
 
@@ -189,6 +230,7 @@ Zone::Loader::Loader(Zone &z):
        add("direction_hint", &Loader::direction_hint);
        add("group",     &Zone::group);
        add("number",    &Zone::number);
+       add("preferred_direction", &Loader::preferred_direction);
        add("qualifier", &Zone::qualifier);
 }
 
@@ -217,4 +259,9 @@ void Zone::Loader::direction_hint(unsigned b, Direction d)
        throw invalid_argument("Zone::Loader::direction_hint");
 }
 
+void Zone::Loader::preferred_direction(Direction d)
+{
+       obj.set_preferred_direction(d);
+}
+
 } // namespace R2C2