From 9f4f169affcedcf249e935f93e0a15ed60232f6a Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sun, 9 Jun 2013 11:39:05 +0300 Subject: [PATCH] Make the simulation independent of wall clock time Layout now holds a Clock object, which keeps track of simulated absolute time and can advance faster (or slower) than the system clock. --- source/libr2c2/aicontrol.cpp | 2 +- source/libr2c2/aicontrol.h | 2 +- source/libr2c2/clock.cpp | 21 +++++++++++++++++++++ source/libr2c2/clock.h | 24 ++++++++++++++++++++++++ source/libr2c2/layout.cpp | 8 ++++++-- source/libr2c2/layout.h | 3 +++ source/libr2c2/train.cpp | 24 +++++++++++++++--------- source/libr2c2/train.h | 8 ++++---- source/libr2c2/trainai.h | 2 +- source/libr2c2/trainrouter.cpp | 2 +- source/libr2c2/trainrouter.h | 2 +- source/libr2c2/trainstatus.cpp | 2 +- source/libr2c2/trainstatus.h | 2 +- 13 files changed, 80 insertions(+), 22 deletions(-) create mode 100644 source/libr2c2/clock.cpp create mode 100644 source/libr2c2/clock.h diff --git a/source/libr2c2/aicontrol.cpp b/source/libr2c2/aicontrol.cpp index 6e1c4b1..97b7209 100644 --- a/source/libr2c2/aicontrol.cpp +++ b/source/libr2c2/aicontrol.cpp @@ -52,7 +52,7 @@ void AIControl::message(const Message &msg) set_reverse(!reverse); } -void AIControl::tick(const Time::TimeStamp &, const Time::TimeDelta &) +void AIControl::tick(const Time::TimeDelta &) { float scale = train.get_layout().get_catalogue().get_scale(); float rsv_dist = train.get_reserved_distance(); diff --git a/source/libr2c2/aicontrol.h b/source/libr2c2/aicontrol.h index 154a2ea..b0c53d5 100644 --- a/source/libr2c2/aicontrol.h +++ b/source/libr2c2/aicontrol.h @@ -34,7 +34,7 @@ public: bool get_reverse() const { return reverse; } virtual void message(const Message &); - virtual void tick(const Msp::Time::TimeStamp &, const Msp::Time::TimeDelta &); + virtual void tick(const Msp::Time::TimeDelta &); private: void event(TrainAI &, const Message &); diff --git a/source/libr2c2/clock.cpp b/source/libr2c2/clock.cpp new file mode 100644 index 0000000..5f87c44 --- /dev/null +++ b/source/libr2c2/clock.cpp @@ -0,0 +1,21 @@ +#include "clock.h" + +using namespace Msp; + +namespace R2C2 { + +Clock::Clock(): + rate(1) +{ } + +void Clock::set_rate(float s) +{ + rate = s; +} + +void Clock::tick(const Time::TimeDelta &dt) +{ + current_time += dt*rate; +} + +} // namespace R2C2 diff --git a/source/libr2c2/clock.h b/source/libr2c2/clock.h new file mode 100644 index 0000000..0fa5f59 --- /dev/null +++ b/source/libr2c2/clock.h @@ -0,0 +1,24 @@ +#ifndef LIBR2C2_CLOCK_H_ +#define LIBR2C2_CLOCK_H_ + +#include + +namespace R2C2 { + +class Clock +{ +private: + Msp::Time::TimeDelta current_time; + float rate; + +public: + Clock(); + + void set_rate(float); + const Msp::Time::TimeDelta &get_current_time() const { return current_time; } + void tick(const Msp::Time::TimeDelta &); +}; + +} // namespace R2C2 + +#endif diff --git a/source/libr2c2/layout.cpp b/source/libr2c2/layout.cpp index efc1e0f..46a43a8 100644 --- a/source/libr2c2/layout.cpp +++ b/source/libr2c2/layout.cpp @@ -39,7 +39,9 @@ Layout::Layout(Catalogue &c, Driver *d): catalogue(c), driver(d), next_turnout_id(0x800) -{ } +{ + clock.set_rate(60); +} Layout::~Layout() { @@ -343,13 +345,15 @@ void Layout::tick() dt = t-last_tick; last_tick = t; + clock.tick(dt); + for(set::iterator i=sensors.get().begin(); i!=sensors.get().end(); ++i) (*i)->tick(dt); const set &signals = objects.get(); for(set::iterator i=signals.begin(); i!=signals.end(); ++i) (*i)->tick(dt); for(map::iterator i=trains.begin(); i!=trains.end(); ++i) - i->second->tick(t, dt); + i->second->tick(dt); } void Layout::emergency(const string &msg) diff --git a/source/libr2c2/layout.h b/source/libr2c2/layout.h index 204a60f..7c61c4f 100644 --- a/source/libr2c2/layout.h +++ b/source/libr2c2/layout.h @@ -7,6 +7,7 @@ #include #include "geometry.h" #include "sensor.h" +#include "clock.h" namespace R2C2 { @@ -84,6 +85,7 @@ public: private: Catalogue &catalogue; Driver *driver; + Clock clock; std::string base; Storage objects; Storage track_chains; @@ -99,6 +101,7 @@ public: Catalogue &get_catalogue() const { return catalogue; } bool has_driver() const { return driver; } Driver &get_driver() const; + const Clock &get_clock() const { return clock; } const std::string &get_base() const { return base; } void add(Object &); diff --git a/source/libr2c2/train.cpp b/source/libr2c2/train.cpp index d1fb4ed..8cfa2d0 100644 --- a/source/libr2c2/train.cpp +++ b/source/libr2c2/train.cpp @@ -136,11 +136,11 @@ void Train::set_active(bool a) active = a; if(active) { - stop_timeout = Time::TimeStamp(); + stop_timeout = Time::zero; allocator.reserve_more(); } else - stop_timeout = Time::now()+2*Time::sec; + stop_timeout = 2*Time::sec; } void Train::set_function(unsigned func, bool state) @@ -289,18 +289,24 @@ void Train::reserve_more() allocator.reserve_more(); } -void Train::tick(const Time::TimeStamp &t, const Time::TimeDelta &dt) +void Train::tick(const Time::TimeDelta &dt) { - if(!active && stop_timeout && t>=stop_timeout) + if(!active && stop_timeout) { - allocator.release_noncurrent(); - stop_timeout = Time::TimeStamp(); + stop_timeout -= dt; + if(stop_timeout<=Time::zero) + { + allocator.release_noncurrent(); + stop_timeout = Time::TimeDelta(); + } } + travel_time += dt; + Driver &driver = layout.get_driver(); for(list::iterator i=ais.begin(); i!=ais.end(); ++i) - (*i)->tick(t, dt); + (*i)->tick(dt); controller->tick(dt); float speed = controller->get_speed(); bool moving = speed>0; @@ -449,7 +455,7 @@ void Train::sensor_state_changed(Sensor &sensor, Sensor::State state) if(travel_distance>0) { - float travel_time_secs = (Time::now()-last_entry_time)/Time::sec; + float travel_time_secs = travel_time/Time::sec; if(travel_time_secs>=2) speed_quantizer->learn(current_speed_step, travel_distance/travel_time_secs, travel_time_secs); @@ -457,7 +463,7 @@ void Train::sensor_state_changed(Sensor &sensor, Sensor::State state) } last_entry_block = allocator.iter_for(*block); - last_entry_time = Time::now(); + travel_time = Time::zero; pure_speed = true; accurate_position = true; overshoot_dist = 0; diff --git a/source/libr2c2/train.h b/source/libr2c2/train.h index e3eebe1..c0eb52e 100644 --- a/source/libr2c2/train.h +++ b/source/libr2c2/train.h @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include "blockallocator.h" #include "controller.h" #include "sensor.h" @@ -60,11 +60,11 @@ private: unsigned current_speed_step; bool speed_changing; bool reverse; - Msp::Time::TimeStamp stop_timeout; + Msp::Time::TimeDelta stop_timeout; unsigned functions; BlockIter last_entry_block; - Msp::Time::TimeStamp last_entry_time; + Msp::Time::TimeDelta travel_time; bool pure_speed; SpeedQuantizer *speed_quantizer; bool accurate_position; @@ -123,7 +123,7 @@ public: const BlockAllocator &get_block_allocator() const { return allocator; } float get_reserved_distance() const; - void tick(const Msp::Time::TimeStamp &, const Msp::Time::TimeDelta &); + void tick(const Msp::Time::TimeDelta &); void save(std::list &) const; private: diff --git a/source/libr2c2/trainai.h b/source/libr2c2/trainai.h index b040493..3f98613 100644 --- a/source/libr2c2/trainai.h +++ b/source/libr2c2/trainai.h @@ -43,7 +43,7 @@ public: virtual ~TrainAI(); virtual void message(const Message &) { } - virtual void tick(const Msp::Time::TimeStamp &, const Msp::Time::TimeDelta &) { } + virtual void tick(const Msp::Time::TimeDelta &) = 0; }; } // namespace R2C2 diff --git a/source/libr2c2/trainrouter.cpp b/source/libr2c2/trainrouter.cpp index d29438f..a5e0d56 100644 --- a/source/libr2c2/trainrouter.cpp +++ b/source/libr2c2/trainrouter.cpp @@ -137,7 +137,7 @@ void TrainRouter::message(const Message &msg) } } -void TrainRouter::tick(const Time::TimeStamp &, const Time::TimeDelta &) +void TrainRouter::tick(const Time::TimeDelta &) { if(update_pending) create_plans(train.get_layout()); diff --git a/source/libr2c2/trainrouter.h b/source/libr2c2/trainrouter.h index 07afe2b..9938533 100644 --- a/source/libr2c2/trainrouter.h +++ b/source/libr2c2/trainrouter.h @@ -63,7 +63,7 @@ public: bool is_destination(Track &) const; virtual void message(const Message &); - virtual void tick(const Msp::Time::TimeStamp &, const Msp::Time::TimeDelta &); + virtual void tick(const Msp::Time::TimeDelta &); void save(std::list &) const; diff --git a/source/libr2c2/trainstatus.cpp b/source/libr2c2/trainstatus.cpp index a5f187f..65c17f7 100644 --- a/source/libr2c2/trainstatus.cpp +++ b/source/libr2c2/trainstatus.cpp @@ -16,7 +16,7 @@ TrainStatus::TrainStatus(Train &t): check(); } -void TrainStatus::tick(const Time::TimeStamp &, const Time::TimeDelta &) +void TrainStatus::tick(const Time::TimeDelta &) { check(); } diff --git a/source/libr2c2/trainstatus.h b/source/libr2c2/trainstatus.h index 40ad5c7..cc095c2 100644 --- a/source/libr2c2/trainstatus.h +++ b/source/libr2c2/trainstatus.h @@ -25,7 +25,7 @@ public: TrainStatus(Train &); const std::string &get_status() const { return status; } - void tick(const Msp::Time::TimeStamp &, const Msp::Time::TimeDelta &); + void tick(const Msp::Time::TimeDelta &); private: void check(); }; -- 2.43.0