]> git.tdb.fi Git - r2c2.git/blob - source/libr2c2/dummy.cpp
Simulate a delay for switching turnouts in the Dummy driver
[r2c2.git] / source / libr2c2 / dummy.cpp
1 #include <msp/strings/utils.h>
2 #include <msp/time/utils.h>
3 #include "dummy.h"
4
5 using namespace std;
6 using namespace Msp;
7
8 namespace R2C2 {
9
10 Dummy::Dummy(const string &params):
11         power(true)
12 {
13         vector<string> opts = split(params, ':');
14         for(vector<string>::const_iterator i=opts.begin(); i!=opts.end(); ++i)
15         {
16                 string::size_type equals = i->find('=');
17                 if(equals!=string::npos)
18                 {
19                         string name = i->substr(0, equals);
20                         string value = i->substr(equals+1);
21                         if(name=="turnout_delay")
22                                 turnout_delay = lexical_cast<unsigned>(value)*Time::msec;
23                 }
24         }
25 }
26
27 void Dummy::set_power(bool p)
28 {
29         power = p;
30         signal_power.emit(power);
31 }
32
33 const char *Dummy::enumerate_protocols(unsigned i) const
34 {
35         if(i==0)
36                 return "dummy";
37         return 0;
38 }
39
40 unsigned Dummy::get_protocol_speed_steps(const string &) const
41 {
42         return 0;
43 }
44
45 void Dummy::add_turnout(unsigned addr, const TrackType &)
46 {
47         turnouts[addr];
48 }
49
50 void Dummy::set_turnout(unsigned addr, unsigned state)
51 {
52         TurnoutState &turnout = turnouts[addr];
53         if(turnout.state==state && turnout.pending==state)
54         {
55                 signal_turnout.emit(addr, state);
56                 return;
57         }
58
59         turnout.pending = state;
60         if(turnout_delay)
61                 turnout.timeout = Time::now()+turnout_delay;
62         else
63         {
64                 turnout.state = state;
65                 signal_turnout.emit(addr, state);
66         }
67 }
68
69 unsigned Dummy::get_turnout(unsigned addr) const
70 {
71         map<unsigned, TurnoutState>::const_iterator i = turnouts.find(addr);
72         if(i!=turnouts.end())
73                 return i->second.state;
74         return 0;
75 }
76
77 void Dummy::set_loco_speed(unsigned addr, unsigned speed)
78 {
79         LocoState &loco = locos[addr];
80         loco.speed = speed;
81         signal_loco_speed.emit(addr, speed, loco.reverse);
82 }
83
84 void Dummy::set_loco_reverse(unsigned addr, bool rev)
85 {
86         LocoState &loco = locos[addr];
87         loco.reverse = rev;
88         signal_loco_speed.emit(addr, loco.speed, rev);
89 }
90
91 void Dummy::set_loco_function(unsigned addr, unsigned func, bool state)
92 {
93         signal_loco_function.emit(addr, func, state);
94 }
95
96 void Dummy::set_sensor(unsigned addr, bool state)
97 {
98         if(sensors[addr]!=state)
99         {
100                 sensors[addr] = state;
101                 signal_sensor.emit(addr, state);
102         }
103 }
104
105 bool Dummy::get_sensor(unsigned addr) const
106 {
107         map<unsigned, bool>::const_iterator i = sensors.find(addr);
108         if(i!=sensors.end())
109                 return i->second;
110         return false;
111 }
112
113 void Dummy::tick()
114 {
115         Time::TimeStamp t = Time::now();
116         for(map<unsigned, TurnoutState>::iterator i=turnouts.begin(); i!=turnouts.end(); ++i)
117         {
118                 if(i->second.timeout && t>=i->second.timeout)
119                 {
120                         i->second.state = i->second.pending;
121                         i->second.timeout = Time::TimeStamp();
122                         signal_turnout.emit(i->first, i->second.state);
123                 }
124         }
125 }
126
127 } // namespace R2C2