From 34f8bf04e4bdffefeceea59b186386b51c542b9d Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Wed, 6 Apr 2011 07:51:55 +0000 Subject: [PATCH] Remove status from Train and turn it into a TrainAI --- source/engineer/trainpanel.cpp | 7 ++-- source/engineer/trainpanel.h | 2 ++ source/libr2c2/train.cpp | 53 +++++++---------------------- source/libr2c2/train.h | 11 ++---- source/libr2c2/trainstatus.cpp | 62 ++++++++++++++++++++++++++++++++++ source/libr2c2/trainstatus.h | 42 +++++++++++++++++++++++ source/network/server.cpp | 7 +++- source/network/server.h | 3 +- 8 files changed, 133 insertions(+), 54 deletions(-) create mode 100644 source/libr2c2/trainstatus.cpp create mode 100644 source/libr2c2/trainstatus.h diff --git a/source/engineer/trainpanel.cpp b/source/engineer/trainpanel.cpp index 813a534..51e7a88 100644 --- a/source/engineer/trainpanel.cpp +++ b/source/engineer/trainpanel.cpp @@ -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 &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()); + tgl_forward->set_value(!msg.value.value()); } void TrainPanel::train_function_changed(unsigned func, bool value) diff --git a/source/engineer/trainpanel.h b/source/engineer/trainpanel.h index 87803ec..ba65fb8 100644 --- a/source/engineer/trainpanel.h +++ b/source/engineer/trainpanel.h @@ -16,6 +16,7 @@ Distributed under the GPL #include #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; diff --git a/source/libr2c2/train.cpp b/source/libr2c2/train.cpp index 38765ce..78c16c0 100644 --- a/source/libr2c2/train.cpp +++ b/source/libr2c2/train.cpp @@ -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::iterator i=ais.begin(); i!=ais.end(); ++i) + for(list::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::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(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"); } } diff --git a/source/libr2c2/train.h b/source/libr2c2/train.h index 59aa9dc..90b2a72 100644 --- a/source/libr2c2/train.h +++ b/source/libr2c2/train.h @@ -92,7 +92,6 @@ private: unsigned functions; std::list 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 &) 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 index 0000000..777bc76 --- /dev/null +++ b/source/libr2c2/trainstatus.cpp @@ -0,0 +1,62 @@ +/* $Id$ + +This file is part of R²C² +Copyright © 2011 Mikkosoft Productions, Mikko Rasa +Distributed under the GPL +*/ + +#include +#include "catalogue.h" +#include "layout.h" +#include "train.h" +#include "trainstatus.h" +#include "vehicle.h" + +using namespace Msp; + +#include + +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(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 index 0000000..8a10121 --- /dev/null +++ b/source/libr2c2/trainstatus.h @@ -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 +#include +#include "trainai.h" + +namespace R2C2 { + +class Train; + +/** +Provides textual description of the status of a train. +*/ +class TrainStatus: public TrainAI +{ +public: + sigc::signal 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 diff --git a/source/network/server.cpp b/source/network/server.cpp index b3f4662..df40b3f 100644 --- a/source/network/server.cpp +++ b/source/network/server.cpp @@ -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(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()) diff --git a/source/network/server.h b/source/network/server.h index dc7543f..badced0 100644 --- a/source/network/server.h +++ b/source/network/server.h @@ -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 #include #include "libr2c2/layout.h" +#include "libr2c2/trainstatus.h" #include "packets.h" #include "protocol.h" -- 2.45.2