]> git.tdb.fi Git - r2c2.git/commitdiff
Simulate a delay for switching turnouts in the Dummy driver
authorMikko Rasa <tdb@tdb.fi>
Sun, 10 Feb 2013 09:46:25 +0000 (11:46 +0200)
committerMikko Rasa <tdb@tdb.fi>
Tue, 12 Feb 2013 12:37:59 +0000 (14:37 +0200)
source/libr2c2/driver.cpp
source/libr2c2/dummy.cpp
source/libr2c2/dummy.h

index 46548e82590ed3e11962184ded5f14f8b86edf25..3b6d64995f56a04c24e52472800e9d6ec8fe24ba 100644 (file)
@@ -21,7 +21,7 @@ Driver *Driver::create(const string &str)
        else if(type=="cs" || type=="centralstation")
                return new CentralStation(params);
        else if(type=="dummy")
-               return new Dummy;
+               return new Dummy(params);
 
        throw invalid_argument("Driver::create");
 }
index 99e4a5e3d189d952a1ad7a5978494fb350e17330..cb625dd6bf1f691650b72b8a820e394912f1bbea 100644 (file)
@@ -1,12 +1,28 @@
+#include <msp/strings/utils.h>
+#include <msp/time/utils.h>
 #include "dummy.h"
 
 using namespace std;
+using namespace Msp;
 
 namespace R2C2 {
 
-Dummy::Dummy():
+Dummy::Dummy(const string &params):
        power(true)
-{ }
+{
+       vector<string> opts = split(params, ':');
+       for(vector<string>::const_iterator i=opts.begin(); i!=opts.end(); ++i)
+       {
+               string::size_type equals = i->find('=');
+               if(equals!=string::npos)
+               {
+                       string name = i->substr(0, equals);
+                       string value = i->substr(equals+1);
+                       if(name=="turnout_delay")
+                               turnout_delay = lexical_cast<unsigned>(value)*Time::msec;
+               }
+       }
+}
 
 void Dummy::set_power(bool p)
 {
@@ -33,19 +49,29 @@ void Dummy::add_turnout(unsigned addr, const TrackType &)
 
 void Dummy::set_turnout(unsigned addr, unsigned state)
 {
-       if(turnouts[addr]!=state)
+       TurnoutState &turnout = turnouts[addr];
+       if(turnout.state==state && turnout.pending==state)
+       {
+               signal_turnout.emit(addr, state);
+               return;
+       }
+
+       turnout.pending = state;
+       if(turnout_delay)
+               turnout.timeout = Time::now()+turnout_delay;
+       else
        {
-               turnouts[addr] = state;
+               turnout.state = state;
                signal_turnout.emit(addr, state);
        }
 }
 
 unsigned Dummy::get_turnout(unsigned addr) const
 {
-       map<unsigned, unsigned>::const_iterator i = turnouts.find(addr);
+       map<unsigned, TurnoutState>::const_iterator i = turnouts.find(addr);
        if(i!=turnouts.end())
-               return i->second;
-       return false;
+               return i->second.state;
+       return 0;
 }
 
 void Dummy::set_loco_speed(unsigned addr, unsigned speed)
@@ -84,4 +110,18 @@ bool Dummy::get_sensor(unsigned addr) const
        return false;
 }
 
+void Dummy::tick()
+{
+       Time::TimeStamp t = Time::now();
+       for(map<unsigned, TurnoutState>::iterator i=turnouts.begin(); i!=turnouts.end(); ++i)
+       {
+               if(i->second.timeout && t>=i->second.timeout)
+               {
+                       i->second.state = i->second.pending;
+                       i->second.timeout = Time::TimeStamp();
+                       signal_turnout.emit(i->first, i->second.state);
+               }
+       }
+}
+
 } // namespace R2C2
index 469b7f2f7b9ade735bfe951d1fba0740a527f608..2c6f992c64d05ee5ca7cba8456093abdebe6d0db 100644 (file)
@@ -2,6 +2,8 @@
 #define LIBR2C2_DUMMY_H_
 
 #include <map>
+#include <msp/time/timedelta.h>
+#include <msp/time/timestamp.h>
 #include "driver.h"
 
 namespace R2C2 {
@@ -9,6 +11,13 @@ namespace R2C2 {
 class Dummy: public Driver
 {
 private:
+       struct TurnoutState
+       {
+               unsigned state;
+               unsigned pending;
+               Msp::Time::TimeStamp timeout;
+       };
+
        struct LocoState
        {
                unsigned speed;
@@ -16,12 +25,13 @@ private:
        };
 
        bool power;
-       std::map<unsigned, unsigned> turnouts;
+       std::map<unsigned, TurnoutState> turnouts;
        std::map<unsigned, LocoState> locos;
        std::map<unsigned, bool> sensors;
+       Msp::Time::TimeDelta turnout_delay;
 
 public:
-       Dummy();
+       Dummy(const std::string &);
 
        virtual void set_power(bool);
        virtual bool get_power() const { return power; }
@@ -47,7 +57,7 @@ public:
        virtual void set_sensor(unsigned, bool);
        virtual bool get_sensor(unsigned) const;
 
-       virtual void tick() { }
+       virtual void tick();
        virtual void flush() { }
 };