]> git.tdb.fi Git - r2c2.git/commitdiff
Remove status from Train and turn it into a TrainAI
authorMikko Rasa <tdb@tdb.fi>
Wed, 6 Apr 2011 07:51:55 +0000 (07:51 +0000)
committerMikko Rasa <tdb@tdb.fi>
Wed, 6 Apr 2011 07:51:55 +0000 (07:51 +0000)
source/engineer/trainpanel.cpp
source/engineer/trainpanel.h
source/libr2c2/train.cpp
source/libr2c2/train.h
source/libr2c2/trainstatus.cpp [new file with mode: 0644]
source/libr2c2/trainstatus.h [new file with mode: 0644]
source/network/server.cpp
source/network/server.h

index 813a53417452b43807650df9035e1b2ad34227b3..51e7a88fe8e820f54b76e03a1a0f94749c170365 100644 (file)
@@ -25,6 +25,7 @@ using namespace R2C2;
 TrainPanel::TrainPanel(Engineer &e, Train &t):
        engineer(e),
        train(t),
+       status(train),
        expanded(false)
 {
        set_size(200, 65);
@@ -77,10 +78,10 @@ TrainPanel::TrainPanel(Engineer &e, Train &t):
        lbl_route->set_geometry(GLtk::Geometry(10, 85, geom.w-20, 20));
        train.signal_route_changed.connect(sigc::mem_fun(this, &TrainPanel::train_route_changed));
 
-       pnl_extra->add(*(lbl_status = new GLtk::Label(train.get_status())));
+       pnl_extra->add(*(lbl_status = new GLtk::Label(status.get_status())));
        lbl_status->set_style("digital");
        lbl_status->set_geometry(GLtk::Geometry(10, 60, geom.w-20, 20));
-       train.signal_status_changed.connect(sigc::mem_fun(this, &TrainPanel::train_status_changed));
+       status.signal_changed.connect(sigc::mem_fun(this, &TrainPanel::train_status_changed));
 
        const map<unsigned, string> &funcs = train.get_locomotive_type().get_functions();
        unsigned x = 10;
@@ -157,7 +158,7 @@ void TrainPanel::ai_event(const TrainAI::Message &msg)
                lbl_speed->set_text(format("%3.0f", speed));
        }
        else if(msg.type=="reverse-changed")
-               tgl_forward->set_value(msg.value.value<bool>());
+               tgl_forward->set_value(!msg.value.value<bool>());
 }
 
 void TrainPanel::train_function_changed(unsigned func, bool value)
index 87803ec348bf94cc4f3d7ea6a4c3615a5c1a67c5..ba65fb886f351afeed2b03790e4e8527318a224c 100644 (file)
@@ -16,6 +16,7 @@ Distributed under the GPL
 #include <msp/gltk/toggle.h>
 #include "libr2c2/route.h"
 #include "libr2c2/train.h"
+#include "libr2c2/trainstatus.h"
 
 class Engineer;
 
@@ -24,6 +25,7 @@ class TrainPanel: public Msp::GLtk::Panel, public sigc::trackable
 private:
        Engineer &engineer;
        R2C2::Train &train;
+       R2C2::TrainStatus status;
        Msp::GLtk::Panel *pnl_basic;
        Msp::GLtk::Panel *pnl_extra;
        Msp::GLtk::Button *btn_expand;
index 38765cee7fde73517df49f546c5205bdd95caefa..78c16c072809ce74f2df57edac7b313d22826342 100644 (file)
@@ -63,7 +63,6 @@ Train::Train(Layout &l, const VehicleType &t, unsigned a, const string &p):
        reverse(false),
        functions(0),
        end_of_route(false),
-       status("Unplaced"),
        travel_dist(0),
        pure_speed(false),
        speed_quantizer(0),
@@ -180,10 +179,7 @@ void Train::set_active(bool a)
                reserve_more();
        }
        else
-       {
                stop_timeout = Time::now()+2*Time::sec;
-               set_status("Stopped");
-       }
 }
 
 void Train::set_function(unsigned func, bool state)
@@ -203,6 +199,14 @@ float Train::get_speed() const
        return controller->get_speed();
 }
 
+float Train::get_quantized_speed() const
+{
+       if(speed_quantizer)
+               return speed_quantizer->quantize_speed(controller->get_speed());
+       else
+               return controller->get_speed();
+}
+
 bool Train::get_function(unsigned func) const
 {
        return (functions>>func)&1;
@@ -221,9 +225,9 @@ void Train::remove_ai(TrainAI &ai)
                ais.erase(i);
 }
 
-TrainAI *Train::get_tagged_ai(const string &tag)
+TrainAI *Train::get_tagged_ai(const string &tag) const
 {
-       for(list<TrainAI *>::iterator i=ais.begin(); i!=ais.end(); ++i)
+       for(list<TrainAI *>::const_iterator i=ais.begin(); i!=ais.end(); ++i)
                if((*i)->get_tag()==tag)
                        return *i;
 
@@ -433,10 +437,7 @@ void Train::place(Block &block, unsigned entry)
        accurate_position = false;
 
        if(!block.reserve(this))
-       {
-               set_status("Unplaced");
                return;
-       }
 
        blocks.push_back(BlockIter(&block, entry));
        if(reverse)
@@ -463,8 +464,6 @@ void Train::unplace()
 
        for(vector<Vehicle *>::iterator i=vehicles.begin(); i!=vehicles.end(); ++i)
                (*i)->unplace();
-
-       set_status("Unplaced");
 }
 
 bool Train::free_block(Block &block)
@@ -605,11 +604,6 @@ void Train::tick(const Time::TimeStamp &t, const Time::TimeDelta &dt)
                        driver.set_loco_speed(address, speed_step);
 
                        pure_speed = false;
-
-                       if(speed_step)
-                               set_status(format("Traveling %d kmh", get_travel_speed()));
-                       else
-                               set_status("Waiting");
                }
 
                speed = speed_quantizer->get_speed(current_speed_step);
@@ -768,12 +762,8 @@ void Train::sensor_event(unsigned addr, bool state)
                        // Compute speed and update related state
                        float travel_time_secs = (Time::now()-last_entry_time)/Time::sec;
 
-                       if(pure_speed)
-                       {
-                               if(speed_quantizer && current_speed_step>0)
-                                       speed_quantizer->learn(current_speed_step, travel_dist/travel_time_secs, travel_time_secs);
-                               set_status(format("Traveling %d kmh", get_travel_speed()));
-                       }
+                       if(pure_speed && speed_quantizer && current_speed_step>0)
+                               speed_quantizer->learn(current_speed_step, travel_dist/travel_time_secs, travel_time_secs);
 
                        travel_dist = 0;
                        for(BlockList::iterator j=cur_blocks_end; j!=end; ++j)
@@ -1173,23 +1163,6 @@ float Train::get_reserved_distance_until(const Block *until_block, bool back) co
        return result;
 }
 
-float Train::get_travel_speed() const
-{
-       float speed = 0;
-       if(speed_quantizer)
-               speed = speed_quantizer->get_speed(current_speed_step);
-       else
-               speed = controller->get_speed();
-       float scale = layout.get_catalogue().get_scale();
-       return static_cast<int>(round(speed/scale*3.6/5))*5;
-}
-
-void Train::set_status(const string &s)
-{
-       status = s;
-       signal_status_changed.emit(s);
-}
-
 void Train::release_blocks()
 {
        release_blocks(blocks.begin(), blocks.end());
@@ -1336,8 +1309,6 @@ void Train::Loader::finish()
                TrackIter track = obj.blocks.front().track_iter();
                float offset = 2*obj.layout.get_catalogue().get_scale();
                obj.vehicles.back()->place(*track, track.entry(), offset, Vehicle::BACK_BUFFER);
-
-               obj.set_status("Stopped");
        }
 }
 
index 59aa9dc022365be78823885a210f0431872dc48b..90b2a72dc5ce94e3795d2a3d232d932fed22d484 100644 (file)
@@ -92,7 +92,6 @@ private:
        unsigned functions;
        std::list<RouteRef> routes;
        bool end_of_route;
-       std::string status;
 
        Msp::Time::TimeStamp last_entry_time;
        float travel_dist;
@@ -128,13 +127,15 @@ public:
        void set_function(unsigned, bool);
        float get_control(const std::string &) const;
        float get_speed() const;
+       float get_quantized_speed() const;
+       unsigned get_speed_step() const { return current_speed_step; }
        bool is_active() const { return active; }
        bool get_function(unsigned) const;
        unsigned get_functions() const { return functions; }
 
        void add_ai(TrainAI &);
        void remove_ai(TrainAI &);
-       TrainAI *get_tagged_ai(const std::string &);
+       TrainAI *get_tagged_ai(const std::string &) const;
        void ai_message(const TrainAI::Message &);
 
        bool set_route(const Route *);
@@ -150,8 +151,6 @@ public:
        int get_entry_to_block(Block &) const;
        float get_reserved_distance() const;
 
-       const std::string &get_status() const { return status; }
-
        void tick(const Msp::Time::TimeStamp &, const Msp::Time::TimeDelta &);
 
        void save(std::list<Msp::DataFile::Statement> &) const;
@@ -166,10 +165,6 @@ private:
        void reserve_more();
        void check_turnout_paths(bool);
        float get_reserved_distance_until(const Block *, bool) const;
-       float get_real_speed(unsigned) const;
-       unsigned find_speed_step(float) const;
-       float get_travel_speed() const;
-       void set_status(const std::string &);
        void release_blocks();
        void release_blocks(BlockList::iterator, BlockList::iterator);
        void reverse_blocks(BlockList &) const;
diff --git a/source/libr2c2/trainstatus.cpp b/source/libr2c2/trainstatus.cpp
new file mode 100644 (file)
index 0000000..777bc76
--- /dev/null
@@ -0,0 +1,62 @@
+/* $Id$
+
+This file is part of R²C²
+Copyright © 2011  Mikkosoft Productions, Mikko Rasa
+Distributed under the GPL
+*/
+
+#include <msp/strings/formatter.h>
+#include "catalogue.h"
+#include "layout.h"
+#include "train.h"
+#include "trainstatus.h"
+#include "vehicle.h"
+
+using namespace Msp;
+
+#include <msp/io/print.h>
+
+namespace R2C2 {
+
+TrainStatus::TrainStatus(Train &t):
+       TrainAI(t),
+       speed(-2)
+{
+       check();
+}
+
+void TrainStatus::tick(const Time::TimeStamp &, const Time::TimeDelta &)
+{
+       check();
+}
+
+void TrainStatus::check()
+{
+       float scale = train.get_layout().get_catalogue().get_scale();
+       int s = static_cast<int>(train.get_quantized_speed()*3.6/scale+0.5);
+       if(s==0 && train.is_active())
+               s = -1;
+
+       if(s!=speed)
+       {
+               if(s>0)
+               {
+                       status = format("Traveling %d kmh", s);
+                       if(unsigned step = train.get_speed_step())
+                               status += format(" (%d)", step);
+               }
+               else if(s==-1)
+                       status = "Waiting";
+               else if(!train.get_vehicle(0).get_track())
+                       status = "Unplaced";
+               else
+                       status = "Stopped";
+
+               speed = s;
+
+               signal_changed.emit(status);
+               signal_event.emit(Message("status-changed", status));
+       }
+}
+
+} // namespace R2C2
diff --git a/source/libr2c2/trainstatus.h b/source/libr2c2/trainstatus.h
new file mode 100644 (file)
index 0000000..8a10121
--- /dev/null
@@ -0,0 +1,42 @@
+/* $Id$
+
+This file is part of R²C²
+Copyright © 2011  Mikkosoft Productions, Mikko Rasa
+Distributed under the GPL
+*/
+
+#ifndef LIBR2C2_TRAINSTATUS_H_
+#define LIBR2C2_TRAINSTATUS_H_
+
+#include <string>
+#include <sigc++/signal.h>
+#include "trainai.h"
+
+namespace R2C2 {
+
+class Train;
+
+/**
+Provides textual description of the status of a train.
+*/
+class TrainStatus: public TrainAI
+{
+public:
+       sigc::signal<void, const std::string &> signal_changed;
+
+private:
+       int speed;
+       std::string status;
+
+public:
+       TrainStatus(Train &);
+
+       const std::string &get_status() const { return status; }
+       void tick(const Msp::Time::TimeStamp &, const Msp::Time::TimeDelta &);
+private:
+       void check();
+};
+
+} // namespace R2C2
+
+#endif
index b3f4662a05079814bb618062245e0a6215ed8b70..df40b3f11ea23d03bf9ca1cb2bb3cdb36b36d6f5 100644 (file)
@@ -77,6 +77,10 @@ void Server::train_added(Train &train)
        pkt.loco_type = train.get_locomotive_type().get_article_number().str();
        pkt.name = train.get_name();
        send(pkt);
+
+       TrainStatus *status = new TrainStatus(train);
+       status->set_tag("server:status");
+       status->signal_changed.connect(sigc::bind<0>(sigc::mem_fun(this, &Server::train_status_changed), sigc::ref(train)));
 }
 
 void Server::train_control_changed(const Train &train, const string &control, float value)
@@ -194,10 +198,11 @@ void Server::Connection::handshake_done()
                        pkt.functions = train.get_functions();
                        comm.send(pkt);
                }
+               if(TrainStatus *status = dynamic_cast<TrainStatus *>(train.get_tagged_ai("server:status")))
                {
                        TrainStatusPacket pkt;
                        pkt.address = train.get_address();
-                       pkt.status = train.get_status();
+                       pkt.status = status->get_status();
                        comm.send(pkt);
                }
                if(train.get_route())
index dc7543fe293278f09be6fb673731108500bae8bf..badced0dbd7d8dd612cf690319e8515c9f5ed63a 100644 (file)
@@ -1,7 +1,7 @@
 /* $Id$
 
 This file is part of R²C²
-Copyright © 2009-2010  Mikkosoft Productions, Mikko Rasa
+Copyright © 2009-2011  Mikkosoft Productions, Mikko Rasa
 Distributed under the GPL
 */
 
@@ -13,6 +13,7 @@ Distributed under the GPL
 #include <msp/net/streamsocket.h>
 #include <msp/net/streamlistensocket.h>
 #include "libr2c2/layout.h"
+#include "libr2c2/trainstatus.h"
 #include "packets.h"
 #include "protocol.h"