From 9a2fd67cec715e371e293be638b126e0d1b2148d Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sun, 22 Mar 2015 17:58:41 +0200 Subject: [PATCH] Give zones a preferred running direction It's also reflected in tracks as a preferred exit endpoint to avoid having to look up zones while routing. Weird things may happen if a track belongs to multiple zones. --- source/designer/zoneproperties.cpp | 22 +++++++++++++++ source/designer/zoneproperties.h | 1 + source/libr2c2/track.cpp | 8 +++++- source/libr2c2/track.h | 3 ++ source/libr2c2/zone.cpp | 45 +++++++++++++++++++++++++++++- source/libr2c2/zone.h | 9 ++++++ 6 files changed, 86 insertions(+), 2 deletions(-) diff --git a/source/designer/zoneproperties.cpp b/source/designer/zoneproperties.cpp index 38d9cc7..b1380c5 100644 --- a/source/designer/zoneproperties.cpp +++ b/source/designer/zoneproperties.cpp @@ -82,6 +82,22 @@ ZoneProperties::ZoneProperties(Zone &z): } } + { + GLtk::Row row(*layout); + add(*(lbl1 = new GLtk::Label("Direction"))); + layout->add_constraint(*lbl1, GLtk::Layout::COPY_WIDTH, *lbl2); + + add(*(drp_preferred_dir = new GLtk::Dropdown)); + GLtk::ListDataStore &data = dynamic_cast &>(drp_preferred_dir->get_data()); + const char *directions[] = { "either", "up", "down", 0 }; + for(unsigned i=0; directions[i]; ++i) + { + data.append(directions[i]); + if(zone.get_preferred_direction()==i) + drp_preferred_dir->set_selected_index(i); + } + } + GLtk::Button *btn; { @@ -111,5 +127,11 @@ void ZoneProperties::on_response(int code) zone.clear_direction(); else zone.set_direction_towards(*up_directions.get(sel), TrackChain::UP); + + if(zone.has_direction()) + { + sel = drp_preferred_dir->get_selected_index(); + zone.set_preferred_direction(static_cast(sel)); + } } } diff --git a/source/designer/zoneproperties.h b/source/designer/zoneproperties.h index c27cadb..8169f87 100644 --- a/source/designer/zoneproperties.h +++ b/source/designer/zoneproperties.h @@ -15,6 +15,7 @@ private: Msp::GLtk::Entry *ent_number; Msp::GLtk::FunctionListData up_directions; Msp::GLtk::Dropdown *drp_up_direction; + Msp::GLtk::Dropdown *drp_preferred_dir; public: ZoneProperties(R2C2::Zone &); diff --git a/source/libr2c2/track.cpp b/source/libr2c2/track.cpp index b53342c..aeccaa6 100644 --- a/source/libr2c2/track.cpp +++ b/source/libr2c2/track.cpp @@ -38,7 +38,8 @@ Track::Track(Layout &l, const TrackType &t): sensor_addr(0), links(type.get_endpoints().size()), active_path(0), - path_changing(false) + path_changing(false), + preferred_exit(-1) { if(type.is_turnout()) { @@ -187,6 +188,11 @@ void Track::set_sensor_address(unsigned a) layout.create_blocks(*this); } +void Track::set_preferred_exit(int e) +{ + preferred_exit = e; +} + void Track::set_active_path(unsigned p) { if(!type.is_turnout()) diff --git a/source/libr2c2/track.h b/source/libr2c2/track.h index ba59da0..a2f8eff 100644 --- a/source/libr2c2/track.h +++ b/source/libr2c2/track.h @@ -50,6 +50,7 @@ private: unsigned active_path; bool path_changing; AttachmentList attachments; + int preferred_exit; Track(const Track &); Track &operator=(const Track &); @@ -76,6 +77,8 @@ public: void set_sensor_address(unsigned); unsigned get_turnout_address() const { return turnout_addr; } unsigned get_sensor_address() const { return sensor_addr; } + void set_preferred_exit(int); + int get_preferred_exit() const { return preferred_exit; } void set_active_path(unsigned); unsigned get_active_path() const { return active_path; } bool is_path_changing() const { return path_changing; } diff --git a/source/libr2c2/zone.cpp b/source/libr2c2/zone.cpp index 52e3c28..de77443 100644 --- a/source/libr2c2/zone.cpp +++ b/source/libr2c2/zone.cpp @@ -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 @@ -173,6 +207,9 @@ void Zone::save(list &st) const break; } } + + if(preferred_dir) + st.push_back((DataFile::Statement("preferred_direction"), preferred_dir)); } } @@ -189,6 +226,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 +255,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 diff --git a/source/libr2c2/zone.h b/source/libr2c2/zone.h index 9542a05..647a619 100644 --- a/source/libr2c2/zone.h +++ b/source/libr2c2/zone.h @@ -22,6 +22,7 @@ public: virtual void finish(); void block(unsigned); void direction_hint(unsigned, Direction); + void preferred_direction(Direction); }; private: @@ -29,6 +30,7 @@ private: std::string qualifier; unsigned number; int up_end; + Direction preferred_dir; public: Zone(Layout &); @@ -43,7 +45,14 @@ public: const std::string &get_qualifier() const { return qualifier; } unsigned get_number() const { return number; } +private: + virtual void on_track_added(Track &); + +public: void set_direction_towards(Track &, Direction); + bool has_direction() const { return up_end>=0; } + void set_preferred_direction(Direction); + Direction get_preferred_direction() const { return preferred_dir; } void clear_direction(); virtual TrackIter iter_for(Track &, Direction) const; private: -- 2.43.0