Zone::Zone(Layout &l):
TrackChain(l),
number(0),
- up_end(-1)
+ up_end(-1),
+ preferred_dir(UNSPECIFIED)
{
layout.add(*this);
}
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)
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
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;
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));
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;
}
add("direction_hint", &Loader::direction_hint);
add("group", &Zone::group);
add("number", &Zone::number);
+ add("preferred_direction", &Loader::preferred_direction);
add("qualifier", &Zone::qualifier);
}
throw invalid_argument("Zone::Loader::direction_hint");
}
+void Zone::Loader::preferred_direction(Direction d)
+{
+ obj.set_preferred_direction(d);
+}
+
} // namespace R2C2