From bc955b09faf8365a72d07bb5ee1253c9b958c897 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sun, 1 Jun 2008 18:22:32 +0000 Subject: [PATCH] Add train status display Button for re-placing trains Bugfixes for train tracking Better handling of block coloring --- source/engineer/engineer.cpp | 51 ++++++++++++++++------------- source/engineer/engineer.h | 2 ++ source/engineer/trainpanel.cpp | 27 +++++++++++++-- source/engineer/trainpanel.h | 3 ++ source/engineer/trainproperties.cpp | 6 ++-- source/libmarklin/block.cpp | 2 +- source/libmarklin/trafficmanager.h | 1 + source/libmarklin/train.cpp | 41 ++++++++++++++++------- source/libmarklin/train.h | 4 +++ 9 files changed, 96 insertions(+), 41 deletions(-) diff --git a/source/engineer/engineer.cpp b/source/engineer/engineer.cpp index 3ac7c76..ec56103 100644 --- a/source/engineer/engineer.cpp +++ b/source/engineer/engineer.cpp @@ -119,14 +119,19 @@ Train *Engineer::add_train(unsigned addr) train_panels.push_back(tpanel); tpanel->set_visible(true); - placing_train=train; - placing_block=0; - main_panel->set_status_text("Select location"); + place_train(*train); return train; } } +void Engineer::place_train(Train &train) +{ + placing_train=&train; + placing_block=0; + main_panel->set_status_text("Select location"); +} + int Engineer::main() { dpy=new Graphics::Display; @@ -284,7 +289,7 @@ void Engineer::button_press(int x, int y, unsigned btn, unsigned) { if(placing_train) { - if(btn==1 && placing_block) + if(btn==1 && placing_block && !placing_block->get_train()) { set_block_color(*placing_block, GL::Color(1, 1, 1)); @@ -335,7 +340,7 @@ void Engineer::pointer_motion(int x, int y) if(&block!=placing_block) { if(placing_block) - set_block_color(*placing_block, GL::Color(1, 1, 1)); + reset_block_color(*placing_block); placing_block=█ placing_entry=0; set_block_color(*placing_block, GL::Color(0.5, 1, 0.7)); @@ -399,37 +404,37 @@ void Engineer::set_block_color(const Block &block, const GL::Color &color) layout_3d.get_track(**i).set_color(color); } -void Engineer::sensor_event(bool state, Sensor *sensor) -{ - const list <racks=layout_3d.get_tracks(); - for(list::const_iterator i=ltracks.begin(); i!=ltracks.end(); ++i) - if((*i)->get_track().get_sensor_id()==sensor->get_address()) - { - Block &block=trfc_mgr->get_block_by_track((*i)->get_track()); - if(state) - (*i)->set_color(GL::Color(1, 0.5, 0.3)); - else if(block.get_train()) - set_block_color(block, GL::Color(1, 1, 0.3)); - else - (*i)->set_color(GL::Color(1, 1, 1)); - } -} - -void Engineer::block_reserved(const Block &block, const Train *train) +void Engineer::reset_block_color(const Block &block) { if(unsigned sid=block.get_sensor_id()) { Sensor &sensor=control.get_sensor(sid); if(sensor.get_state()) + { + set_block_color(block, GL::Color(1, 0.5, 0.3)); return; + } } - if(train) + if(block.get_train()) set_block_color(block, GL::Color(1, 1, 0.3)); else set_block_color(block, GL::Color(1, 1, 1)); } +void Engineer::sensor_event(bool, Sensor *sensor) +{ + const list &blocks=trfc_mgr->get_blocks(); + for(list::const_iterator i=blocks.begin(); i!=blocks.end(); ++i) + if((*i)->get_sensor_id()==sensor->get_address()) + reset_block_color(**i); +} + +void Engineer::block_reserved(const Block &block, const Train *) +{ + reset_block_color(block); +} + void Engineer::project_3d() { glMatrixMode(GL_PROJECTION); diff --git a/source/engineer/engineer.h b/source/engineer/engineer.h index 6131c6f..3552bad 100644 --- a/source/engineer/engineer.h +++ b/source/engineer/engineer.h @@ -50,6 +50,7 @@ public: Marklin::Control &get_control() { return control; } Marklin::Train *add_train(unsigned); + void place_train(Marklin::Train &); int main(); void quit() { exit(0); } private: @@ -60,6 +61,7 @@ private: void pointer_motion(int, int); void view_all(); void set_block_color(const Marklin::Block &, const Msp::GL::Color &); + void reset_block_color(const Marklin::Block &); void sensor_event(bool, Marklin::Sensor *); void block_reserved(const Marklin::Block &, const Marklin::Train *); void project_3d(); diff --git a/source/engineer/trainpanel.cpp b/source/engineer/trainpanel.cpp index 4dec1af..cd41c23 100644 --- a/source/engineer/trainpanel.cpp +++ b/source/engineer/trainpanel.cpp @@ -1,8 +1,10 @@ #include #include #include "libmarklin/locomotive.h" +#include "engineer.h" #include "trainpanel.h" +using namespace std; using namespace Msp; using namespace Marklin; @@ -11,9 +13,9 @@ TrainPanel::TrainPanel(Engineer &e, const GLtk::Resources &r, Train &t): engineer(e), train(t) { - set_size(200, 100); + set_size(200, 131); - add(*(lbl_addr=new GLtk::Label(res, lexical_cast(train.get_locomotive().get_address(), "%2d")))); + add(*(lbl_addr=new GLtk::Label(res, format("%2d", train.get_locomotive().get_address())))); lbl_addr->set_style("digital"); lbl_addr->set_geometry(GLtk::Geometry(10, geom.h-34, 35, 24)); @@ -28,15 +30,24 @@ TrainPanel::TrainPanel(Engineer &e, const GLtk::Resources &r, Train &t): sld_speed->set_step(1); sld_speed->signal_value_changed.connect(sigc::mem_fun(this, &TrainPanel::speed_slider_changed)); - add(*(lbl_speed=new GLtk::Label(res, " 0"))); + add(*(lbl_speed=new GLtk::Label(res, format("%2d", train.get_locomotive().get_speed())))); lbl_speed->set_style("digital"); lbl_speed->set_geometry(GLtk::Geometry(10, geom.h-63, 35, 24)); train.get_locomotive().signal_speed_changed.connect(sigc::mem_fun(this, &TrainPanel::loco_speed_changed)); + add(*(lbl_status=new GLtk::Label(res, train.get_status()))); + lbl_status->set_style("digital"); + lbl_status->set_geometry(GLtk::Geometry(10, geom.h-92, geom.w-20, 24)); + train.signal_status_changed.connect(sigc::mem_fun(this, &TrainPanel::train_status_changed)); + GLtk::Button *btn; add(*(btn=new GLtk::Button(res, "Edit"))); btn->set_geometry(GLtk::Geometry(geom.w-50, 10, 40, 24)); + + add(*(btn=new GLtk::Button(res, "Place"))); + btn->set_geometry(GLtk::Geometry(geom.w-90, 10, 40, 24)); + btn->signal_clicked.connect(sigc::mem_fun(this, &TrainPanel::place_clicked)); } void TrainPanel::speed_slider_changed(double v) @@ -48,3 +59,13 @@ void TrainPanel::loco_speed_changed(unsigned speed) { lbl_speed->set_text(format("%2d", speed)); } + +void TrainPanel::train_status_changed(const string &s) +{ + lbl_status->set_text(s); +} + +void TrainPanel::place_clicked() +{ + engineer.place_train(train); +} diff --git a/source/engineer/trainpanel.h b/source/engineer/trainpanel.h index 3e44241..87e17c9 100644 --- a/source/engineer/trainpanel.h +++ b/source/engineer/trainpanel.h @@ -18,12 +18,15 @@ private: Msp::GLtk::HSlider *sld_speed; Marklin::Locomotive *loco; Msp::GLtk::Label *lbl_speed; + Msp::GLtk::Label *lbl_status; public: TrainPanel(Engineer &, const Msp::GLtk::Resources &, Marklin::Train &); private: void speed_slider_changed(double); void loco_speed_changed(unsigned); + void train_status_changed(const std::string &); + void place_clicked(); }; #endif diff --git a/source/engineer/trainproperties.cpp b/source/engineer/trainproperties.cpp index 9b46ce4..1a918ad 100644 --- a/source/engineer/trainproperties.cpp +++ b/source/engineer/trainproperties.cpp @@ -11,13 +11,13 @@ TrainProperties::TrainProperties(Engineer &e, GLtk::Resources &r, Train *t): engineer(e), train(t) { - set_size(200, 75); + set_size(200, 95); add(*(ent_addr=new GLtk::Entry(res))); - ent_addr->set_geometry(GLtk::Geometry(10, geom.h-25, 40, 20)); + ent_addr->set_geometry(GLtk::Geometry(10, geom.h-30, 40, 20)); add(*(ent_name=new GLtk::Entry(res, "Train"))); - ent_name->set_geometry(GLtk::Geometry(10, geom.h-50, geom.w-20, 20)); + ent_name->set_geometry(GLtk::Geometry(10, geom.h-55, geom.w-20, 20)); GLtk::Button *btn; diff --git a/source/libmarklin/block.cpp b/source/libmarklin/block.cpp index 0106a50..87654e4 100644 --- a/source/libmarklin/block.cpp +++ b/source/libmarklin/block.cpp @@ -124,7 +124,7 @@ bool Block::reserve(const Train *t) { train=t; if(train) - cout<<"Block "<get_name()<<'\n'; else cout<<"Block "< &get_blocks() const { return blocks; } Block &get_block_by_track(const Track &) const; const std::list &get_trains() const { return trains; } void add_train(Train *); diff --git a/source/libmarklin/train.cpp b/source/libmarklin/train.cpp index 1644802..8b34e84 100644 --- a/source/libmarklin/train.cpp +++ b/source/libmarklin/train.cpp @@ -14,7 +14,8 @@ namespace Marklin { Train::Train(TrafficManager &tm, Locomotive &l): trfc_mgr(tm), loco(l), - target_speed(0) + target_speed(0), + status("Unplaced") { trfc_mgr.add_train(this); @@ -35,13 +36,17 @@ void Train::set_speed(unsigned speed) target_speed=speed; if(!target_speed) { + // XXX We might roll onto a new sensor and get confused - should delay freeing blocks a bit for(list::iterator i=rsv_blocks.begin(); i!=rsv_blocks.end(); ++i) i->block->reserve(0); rsv_blocks.clear(); + try_reserve=Time::TimeStamp(); } else if(rsv_blocks.empty() && !reserve_more()) return; + loco.set_speed(speed); + set_status(target_speed ? "Traveling" : "Stopped"); } void Train::place(Block *block, unsigned entry) @@ -59,9 +64,14 @@ void Train::place(Block *block, unsigned entry) } if(!block->reserve(this)) + { + set_status("Unplaced"); return; + } cur_blocks.push_back(BlockRef(block, entry)); + + set_status("Stopped"); } bool Train::free_block(Block *block) @@ -84,9 +94,10 @@ void Train::tick(const Time::TimeStamp &t) { if(try_reserve && t>try_reserve) { - if(reserve_more()) + if(reserve_more() || !rsv_blocks.empty()) { loco.set_speed(target_speed); + set_status("Traveling"); try_reserve=Time::TimeStamp(); } else @@ -96,9 +107,6 @@ void Train::tick(const Time::TimeStamp &t) void Train::sensor_event(bool state, Sensor *sensor) { - if(!loco.get_speed()) - return; - unsigned addr=sensor->get_address(); if(state) @@ -107,19 +115,23 @@ void Train::sensor_event(bool state, Sensor *sensor) for(i=rsv_blocks.begin(); i!=rsv_blocks.end(); ++i) if(i->block->get_sensor_id() && i->block->get_sensor_id()!=addr) break; - cur_blocks.splice(cur_blocks.end(), rsv_blocks, rsv_blocks.begin(), i); - cout<<"Train "<::iterator i; for(i=cur_blocks.begin(); i!=cur_blocks.end(); ++i) { @@ -134,7 +146,8 @@ void Train::sensor_event(bool state, Sensor *sensor) } } - reserve_more(); + if(target_speed) + reserve_more(); } } @@ -148,7 +161,7 @@ bool Train::reserve_more() if(!last) return false; - cout<<"Train "< rsv_blocks; unsigned target_speed; Msp::Time::TimeStamp try_reserve; + std::string status; public: sigc::signal signal_name_changed; + sigc::signal signal_status_changed; Train(TrafficManager &, Locomotive &); @@ -40,12 +42,14 @@ public: void set_speed(unsigned); const std::string &get_name() const { return name; } Locomotive &get_locomotive() const { return loco; } + const std::string &get_status() const { return status; } void place(Block *, unsigned); bool free_block(Block *); void tick(const Msp::Time::TimeStamp &); private: void sensor_event(bool, Sensor *); bool reserve_more(); + void set_status(const std::string &); }; } // namespace Marklin -- 2.45.2