]> git.tdb.fi Git - r2c2.git/blobdiff - source/libr2c2/dummy.cpp
Initialize the halted flag of dummy driver
[r2c2.git] / source / libr2c2 / dummy.cpp
index cb625dd6bf1f691650b72b8a820e394912f1bbea..90638f63bd8c438b2cfa845a7c0d20173992df41 100644 (file)
@@ -1,3 +1,5 @@
+#include <cstdlib>
+#include <msp/core/maputils.h>
 #include <msp/strings/utils.h>
 #include <msp/time/utils.h>
 #include "dummy.h"
@@ -7,22 +9,12 @@ using namespace Msp;
 
 namespace R2C2 {
 
-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;
-               }
-       }
-}
+Dummy::Dummy(const Options &opts):
+       power(true),
+       halted(false),
+       turnout_delay(opts.get("turnout_delay", 0.0f)*Time::sec),
+       turnout_fail_rate(opts.get("turnout_fail_rate", 0.0f)*RAND_MAX)
+{ }
 
 void Dummy::set_power(bool p)
 {
@@ -30,6 +22,18 @@ void Dummy::set_power(bool p)
        signal_power.emit(power);
 }
 
+void Dummy::halt(bool h)
+{
+       halted = h;
+       if(halted)
+       {
+               for(map<unsigned, LocoState>::iterator i=locos.begin(); i!=locos.end(); ++i)
+                       if(i->second.speed)
+                               set_loco_speed(i->first, 0);
+       }
+       signal_halt.emit(halted);
+}
+
 const char *Dummy::enumerate_protocols(unsigned i) const
 {
        if(i==0)
@@ -42,9 +46,10 @@ unsigned Dummy::get_protocol_speed_steps(const string &) const
        return 0;
 }
 
-void Dummy::add_turnout(unsigned addr, const TrackType &)
+unsigned Dummy::add_turnout(unsigned addr, const TrackType &)
 {
        turnouts[addr];
+       return addr;
 }
 
 void Dummy::set_turnout(unsigned addr, unsigned state)
@@ -61,7 +66,8 @@ void Dummy::set_turnout(unsigned addr, unsigned state)
                turnout.timeout = Time::now()+turnout_delay;
        else
        {
-               turnout.state = state;
+               if(!turnout_fail_rate || rand()>=turnout_fail_rate)
+                       turnout.state = state;
                signal_turnout.emit(addr, state);
        }
 }
@@ -76,6 +82,9 @@ unsigned Dummy::get_turnout(unsigned addr) const
 
 void Dummy::set_loco_speed(unsigned addr, unsigned speed)
 {
+       if(speed && halted)
+               return;
+
        LocoState &loco = locos[addr];
        loco.speed = speed;
        signal_loco_speed.emit(addr, speed, loco.reverse);
@@ -110,6 +119,11 @@ bool Dummy::get_sensor(unsigned addr) const
        return false;
 }
 
+float Dummy::get_telemetry_value(const string &name) const
+{
+       throw key_error(name);
+}
+
 void Dummy::tick()
 {
        Time::TimeStamp t = Time::now();
@@ -117,6 +131,11 @@ void Dummy::tick()
        {
                if(i->second.timeout && t>=i->second.timeout)
                {
+                       if(turnout_fail_rate && rand()<turnout_fail_rate)
+                       {
+                               signal_turnout_failed.emit(i->first);
+                               i->second.pending = i->second.state;
+                       }
                        i->second.state = i->second.pending;
                        i->second.timeout = Time::TimeStamp();
                        signal_turnout.emit(i->first, i->second.state);