]> git.tdb.fi Git - r2c2.git/commitdiff
Add train status display
authorMikko Rasa <tdb@tdb.fi>
Sun, 1 Jun 2008 18:22:32 +0000 (18:22 +0000)
committerMikko Rasa <tdb@tdb.fi>
Sun, 1 Jun 2008 18:22:32 +0000 (18:22 +0000)
Button for re-placing trains
Bugfixes for train tracking
Better handling of block coloring

source/engineer/engineer.cpp
source/engineer/engineer.h
source/engineer/trainpanel.cpp
source/engineer/trainpanel.h
source/engineer/trainproperties.cpp
source/libmarklin/block.cpp
source/libmarklin/trafficmanager.h
source/libmarklin/train.cpp
source/libmarklin/train.h

index 3ac7c7682a605cc06942c23cfee7607db157259c..ec5610396f45f3c7530be5bd5f143fbbfafdfc3c 100644 (file)
@@ -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=&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<Track3D *> &ltracks=layout_3d.get_tracks();
-       for(list<Track3D *>::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<Block *> &blocks=trfc_mgr->get_blocks();
+       for(list<Block *>::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);
index 6131c6f2f4fc3d4a10596355ef442a77f4e55379..3552badd5a49fc6f749820da51958360c32bd0fa 100644 (file)
@@ -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();
index 4dec1afecb9322b407ca10eaa35e1b714e286f31..cd41c2343d2adde8a354dbebaa2d307718608163 100644 (file)
@@ -1,8 +1,10 @@
 #include <msp/gltk/button.h>
 #include <msp/strings/formatter.h>
 #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);
+}
index 3e44241bf3e7700e041f28f0b97413c231ba5138..87e17c9a14570b193c293f6902103407cbe09d68 100644 (file)
@@ -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
index 9b46ce41af96c6551d0bf59f29aa69278adf08c7..1a918ad19f6c1bacda3fea692b8f4a4a5ad10804 100644 (file)
@@ -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;
 
index 0106a50731d6dc3fb98e2e5a8f68a4c359614a04..87654e4387df997ac5b125dac1643a4bdd1cf47c 100644 (file)
@@ -124,7 +124,7 @@ bool Block::reserve(const Train *t)
        {
                train=t;
                if(train)
-                       cout<<"Block "<<this<<" reserved for train "<<train<<'\n';
+                       cout<<"Block "<<this<<" reserved for train "<<train->get_name()<<'\n';
                else
                        cout<<"Block "<<this<<" freed\n";
                trfc_mgr.signal_block_reserved.emit(*this, train);
index 2ef4bc9e9346a2d17a729c4660c1c9f3c3f90888..a73e57c99950c44081637ed9513a18c0099309d0 100644 (file)
@@ -25,6 +25,7 @@ public:
        ~TrafficManager();
 
        Control &get_control() const { return control; }
+       const std::list<Block *> &get_blocks() const { return blocks; }
        Block &get_block_by_track(const Track &) const;
        const std::list<Train *> &get_trains() const { return trains; }
        void add_train(Train *);
index 1644802008ae4b575c62d052f6a6e41ba94d306e..8b34e849a2d96dd29504fe54a02d83f7ea6113c4 100644 (file)
@@ -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<BlockRef>::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 "<<this<<" advanced, "<<cur_blocks.size()<<" cur_blocks, "<<rsv_blocks.size()<<" rsv_blocks\n";
+               if(i!=rsv_blocks.begin())
+               {
+                       cur_blocks.splice(cur_blocks.end(), rsv_blocks, rsv_blocks.begin(), i);
+                       cout<<"Train "<<name<<" advanced, "<<cur_blocks.size()<<" cur_blocks, "<<rsv_blocks.size()<<" rsv_blocks\n";
+               }
 
-               if(rsv_blocks.empty() && !reserve_more())
+               if(target_speed && rsv_blocks.empty() && !reserve_more())
                {
                        loco.set_speed(0);
                        try_reserve=Time::now()+2*Time::sec;
+                       set_status("Blocked");
                }
        }
        else
        {
-               cout<<"Train "<<this<<" finding blocks to free\n";
+               cout<<"Train "<<name<<" finding blocks to free\n";
                list<BlockRef>::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 "<<this<<" reserving more blocks\n";
+       cout<<"Train "<<name<<" reserving more blocks\n";
 
        bool result=false;
        unsigned size=rsv_blocks.size();
@@ -177,4 +190,10 @@ bool Train::reserve_more()
        return result;
 }
 
+void Train::set_status(const string &s)
+{
+       status=s;
+       signal_status_changed.emit(s);
+}
+
 } // namespace Marklin
index 815a9e9305f2baab23a506f98a886ccb497c51d5..24c9db9fc04acb238cf5e265ccee9e02d5f6b2b2 100644 (file)
@@ -30,9 +30,11 @@ private:
        std::list<BlockRef> rsv_blocks;
        unsigned target_speed;
        Msp::Time::TimeStamp try_reserve;
+       std::string status;
 
 public:
        sigc::signal<void, const std::string &> signal_name_changed;
+       sigc::signal<void, const std::string &> 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