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