]> git.tdb.fi Git - r2c2.git/commitdiff
Support setting routes for trains
authorMikko Rasa <tdb@tdb.fi>
Sun, 13 Dec 2009 16:27:21 +0000 (16:27 +0000)
committerMikko Rasa <tdb@tdb.fi>
Sun, 13 Dec 2009 16:27:21 +0000 (16:27 +0000)
Fix Train::find_speed

source/engineer/engineer.h
source/engineer/routeselect.cpp [new file with mode: 0644]
source/engineer/routeselect.h [new file with mode: 0644]
source/engineer/trainpanel.cpp
source/engineer/trainpanel.h
source/libmarklin/train.cpp
source/libmarklin/train.h

index df45678306418c38e0ab9ffe905c89d567875d18..8e8e0216b21ef3a866c0d25b73a42e97e20e228e 100644 (file)
@@ -64,6 +64,7 @@ public:
        const Msp::GLtk::Resources &get_ui_resources() const { return ui_res; }
        Msp::GLtk::Root &get_root() const { return *root; }
        const Marklin::Catalogue &get_catalogue() const { return catalogue; }
+       const Marklin::Layout &get_layout() const { return layout; }
        Marklin::Control &get_control() { return control; }
        Marklin::TrafficManager &get_traffic_manager() { return *trfc_mgr; }
        void place_train(Marklin::Train &);
diff --git a/source/engineer/routeselect.cpp b/source/engineer/routeselect.cpp
new file mode 100644 (file)
index 0000000..8b526ae
--- /dev/null
@@ -0,0 +1,55 @@
+/* $Id$
+
+This file is part of the MSP Märklin suite
+Copyright © 2009 Mikkosoft Productions, Mikko Rasa
+Distributed under the GPL
+*/
+
+#include <msp/gltk/label.h>
+#include "engineer.h"
+#include "libmarklin/route.h"
+#include "routeselect.h"
+
+using namespace std;
+using namespace Msp;
+using namespace Marklin;
+
+RouteSelect::RouteSelect(Engineer &e, const GLtk::Resources &r, Train &t):
+       GLtk::Widget(r),
+       Dialog(r),
+       engineer(e),
+       train(t)
+{
+       set_size(200, 95);
+
+       GLtk::Label *label;
+       add(*(label = new GLtk::Label(res, "Select route")));
+       label->set_geometry(GLtk::Geometry(10, geom.h-25, geom.w-20, 20));
+
+       add(*(drp_route = new GLtk::Dropdown(res)));
+       drp_route->set_geometry(GLtk::Geometry(10, geom.h-50, geom.w-20, 20));
+       drp_route->append("(none)");
+       drp_route->set_selected_index(0);
+       const set<Route *> &routes = engineer.get_layout().get_routes();
+       unsigned n = 1;
+       for(set<Route *>::const_iterator i=routes.begin(); i!=routes.end(); ++i, ++n)
+       {
+               drp_route->append((*i)->get_name());
+               if(*i==train.get_route())
+                       drp_route->set_selected_index(n);
+       }
+}
+
+void RouteSelect::on_ok_clicked()
+{
+       if(drp_route->get_selected_index()>0)
+       {
+               const set<Route *> &routes = engineer.get_layout().get_routes();
+               set<Route *>::const_iterator i = routes.begin();
+               advance(i, drp_route->get_selected_index()-1);
+               
+               train.set_route(*i);
+       }
+       else
+               train.set_route(0);
+}
diff --git a/source/engineer/routeselect.h b/source/engineer/routeselect.h
new file mode 100644 (file)
index 0000000..53bf2fb
--- /dev/null
@@ -0,0 +1,30 @@
+/* $Id$
+
+This file is part of the MSP Märklin suite
+Copyright © 2009 Mikkosoft Productions, Mikko Rasa
+Distributed under the GPL
+*/
+
+#ifndef ROUTESELECT_H_
+#define ROUTESELECT_H_
+
+#include <msp/gltk/dropdown.h>
+#include "libmarklin/train.h"
+#include "dialog.h"
+
+class Engineer;
+
+class RouteSelect: public Dialog
+{
+private:
+       Engineer &engineer;
+       Marklin::Train &train;
+       Msp::GLtk::Dropdown *drp_route;
+
+public:
+       RouteSelect(Engineer &, const Msp::GLtk::Resources &, Marklin::Train &);
+private:
+       virtual void on_ok_clicked();
+};
+
+#endif
index be675d6b8a2e4582c65390cc121d16acccf935f9..d462b5139c85f192d7bf747523c3b4e40fca1cdd 100644 (file)
@@ -9,6 +9,7 @@ Distributed under the GPL
 #include <msp/strings/formatter.h>
 #include "libmarklin/locomotive.h"
 #include "engineer.h"
+#include "routeselect.h"
 #include "trainpanel.h"
 #include "trainproperties.h"
 
@@ -22,7 +23,7 @@ TrainPanel::TrainPanel(Engineer &e, const GLtk::Resources &r, Train &t):
        engineer(e),
        train(t)
 {
-       set_size(200, 145);
+       set_size(200, 170);
 
        add(*(lbl_addr=new GLtk::Label(res, format("%2d", train.get_locomotive().get_address()))));
        lbl_addr->set_style("digital");
@@ -50,6 +51,11 @@ TrainPanel::TrainPanel(Engineer &e, const GLtk::Resources &r, Train &t):
        tgl_forward->set_value(!train.get_locomotive().get_reverse());
        tgl_forward->signal_toggled.connect(sigc::mem_fun(this, &TrainPanel::forward_toggled));
 
+       add(*(lbl_route=new GLtk::Label(res, "Free run")));
+       lbl_route->set_style("digital");
+       lbl_route->set_geometry(GLtk::Geometry(10, 58, geom.w-20, 24));
+       train.signal_route_changed.connect(sigc::mem_fun(this, &TrainPanel::train_route_changed));
+
        add(*(lbl_status=new GLtk::Label(res, train.get_status())));
        lbl_status->set_style("digital");
        lbl_status->set_geometry(GLtk::Geometry(10, 34, geom.w-20, 24));
@@ -84,6 +90,10 @@ TrainPanel::TrainPanel(Engineer &e, const GLtk::Resources &r, Train &t):
 
        add(*(btn=new GLtk::Button(res, "GoTo")));
        btn->set_geometry(GLtk::Geometry(geom.w-130, 10, 40, 24));
+
+       add(*(btn=new GLtk::Button(res, "Route")));
+       btn->set_geometry(GLtk::Geometry(geom.w-170, 10, 40, 24));
+       btn->signal_clicked.connect(sigc::mem_fun(this, &TrainPanel::route_clicked));
 }
 
 void TrainPanel::speed_slider_changed(double v)
@@ -104,6 +114,14 @@ void TrainPanel::loco_function_changed(unsigned func, bool value)
                i->second->set_value(value);
 }
 
+void TrainPanel::train_route_changed(const Route *r)
+{
+       if(r)
+               lbl_route->set_text(r->get_name());
+       else
+               lbl_route->set_text("Free run");
+}
+
 void TrainPanel::train_status_changed(const string &s)
 {
        lbl_status->set_text(s);
@@ -122,6 +140,14 @@ void TrainPanel::edit_clicked()
        dialog->set_visible(true);
 }
 
+void TrainPanel::route_clicked()
+{
+       RouteSelect *dialog = new RouteSelect(engineer, res, train);
+       engineer.get_root().add(*dialog);
+       dialog->set_position(geom.x+geom.w, geom.y+geom.h-dialog->get_geometry().h);
+       dialog->set_visible(true);
+}
+
 void TrainPanel::forward_toggled(bool value)
 {
        train.set_reverse(!value);
index 817ba18b238d84a998bd4a6ade21166e15a13e62..aae71f98431f0f49d50d06e6f6e64d158c3d4233 100644 (file)
@@ -12,6 +12,7 @@ Distributed under the GPL
 #include <msp/gltk/label.h>
 #include <msp/gltk/panel.h>
 #include <msp/gltk/toggle.h>
+#include "libmarklin/route.h"
 #include "libmarklin/train.h"
 
 class Engineer;
@@ -25,6 +26,7 @@ private:
        Msp::GLtk::Label *lbl_name;
        Msp::GLtk::HSlider *sld_speed;
        Msp::GLtk::Label *lbl_speed;
+       Msp::GLtk::Label *lbl_route;
        Msp::GLtk::Label *lbl_status;
        Msp::GLtk::Toggle *tgl_forward;
        std::map<unsigned, Msp::GLtk::Toggle *> tgl_funcs;
@@ -35,9 +37,11 @@ private:
        void speed_slider_changed(double);
        void train_speed_changed(unsigned);
        void loco_function_changed(unsigned, bool);
+       void train_route_changed(const Marklin::Route *);
        void train_status_changed(const std::string &);
        void place_clicked();
        void edit_clicked();
+       void route_clicked();
        void forward_toggled(bool);
        void func_toggled(bool, unsigned);
 };
index e904ebfc5f94b8152890c47c68a9b77cc4ebf189..12c4c26586a89df5ffa1422abf317b314b8e7ae2 100644 (file)
@@ -11,6 +11,7 @@ Distributed under the GPL
 #include <msp/time/utils.h>
 #include "control.h"
 #include "except.h"
+#include "route.h"
 #include "tracktype.h"
 #include "trafficmanager.h"
 #include "train.h"
@@ -80,6 +81,12 @@ void Train::set_reverse(bool rev)
        loco.set_reverse(rev);
 }
 
+void Train::set_route(const Route *r)
+{
+       route = r;
+       signal_route_changed.emit(route);
+}
+
 void Train::place(Block *block, unsigned entry)
 {
        for(list<BlockRef>::iterator i=rsv_blocks.begin(); i!=rsv_blocks.end();)
@@ -321,6 +328,12 @@ unsigned Train::reserve_more()
                        Block *link = last->block->get_link(exit);
                        if(link && link->reserve(this))
                        {
+                               if(route && link->get_turnout_id())
+                               {
+                                       int path = route->get_turnout(link->get_turnout_id());
+                                       if(path>=0)
+                                               trfc_mgr.get_control().get_turnout(link->get_turnout_id()).set_path(path);
+                               }
                                rsv_blocks.push_back(BlockRef(link, link->get_endpoint_by_link(*last->block)));
                                last = &rsv_blocks.back();
                                if(last->block->get_sensor_id())
@@ -422,14 +435,23 @@ unsigned Train::find_speed(float real) const
 {
        if(real<=real_speed[0].speed)
                return 0;
-       if(real>=real_speed[14].speed)
-               return 14;
 
        unsigned low = 0;
        unsigned high = 0;
-       for(high=0; real_speed[high].speed<real; ++high)
-               if(real_speed[high].weight)
-                       low = high;
+       for(unsigned i=0; (!high && i<=14); ++i)
+               if(real_speed[i].weight)
+               {
+                       if(real_speed[i].speed<real)
+                               low = i;
+                       else
+                               high = i;
+               }
+       if(!high)
+       {
+               if(!low)
+                       return 0;
+               return min(static_cast<unsigned>(low*real/real_speed[low].speed), 14U);
+       }
 
        float f = (real-real_speed[low].speed)/(real_speed[high].speed-real_speed[low].speed);
        return static_cast<unsigned>(low*(1-f)+high*f+0.5);
index b891a660ac4e8ca381947421a7bc73c3c6b4397d..90627ae4561d021dc372ac8fe3090a1a94794677 100644 (file)
@@ -16,6 +16,7 @@ Distributed under the GPL
 namespace Marklin {
 
 class Locomotive;
+class Route;
 class Sensor;
 class TrafficManager;
 class Turnout;
@@ -33,6 +34,7 @@ public:
 
        sigc::signal<void, const std::string &> signal_name_changed;
        sigc::signal<void, unsigned> signal_target_speed_changed;
+       sigc::signal<void, const Route *> signal_route_changed;
        sigc::signal<void, const std::string &> signal_status_changed;
 
 private:
@@ -59,6 +61,7 @@ private:
        std::list<BlockRef> cur_blocks;
        std::list<BlockRef> rsv_blocks;
        unsigned target_speed;
+       const Route *route;
        Msp::Time::TimeStamp try_reserve;
        std::string status;
 
@@ -79,9 +82,11 @@ public:
        void set_name(const std::string &);
        void set_speed(unsigned);
        void set_reverse(bool);
+       void set_route(const Route *);
        const std::string &get_name() const { return name; }
        Locomotive &get_locomotive() const { return loco; }
        unsigned get_target_speed() const { return target_speed; }
+       const Route *get_route() const { return route; }
        const std::string &get_status() const { return status; }
        const Point &get_position() const { return pos; }
        void place(Block *, unsigned);