]> git.tdb.fi Git - r2c2.git/blob - libr2c2/dummy.cpp
Don't crash if a train has no router
[r2c2.git] / 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 unsigned Dummy::add_turnout(unsigned addr, const TrackType &)
46 {
47         turnouts[addr];
48         return addr;
49 }
50
51 void Dummy::set_turnout(unsigned addr, unsigned state)
52 {
53         TurnoutState &turnout = turnouts[addr];
54         if(turnout.state==state && turnout.pending==state)
55         {
56                 signal_turnout.emit(addr, state);
57                 return;
58         }
59
60         turnout.pending = state;
61         if(turnout_delay)
62                 turnout.timeout = Time::now()+turnout_delay;
63         else
64         {
65                 turnout.state = state;
66                 signal_turnout.emit(addr, state);
67         }
68 }
69
70 unsigned Dummy::get_turnout(unsigned addr) const
71 {
72         map<unsigned, TurnoutState>::const_iterator i = turnouts.find(addr);
73         if(i!=turnouts.end())
74                 return i->second.state;
75         return 0;
76 }
77
78 void Dummy::set_loco_speed(unsigned addr, unsigned speed)
79 {
80         LocoState &loco = locos[addr];
81         loco.speed = speed;
82         signal_loco_speed.emit(addr, speed, loco.reverse);
83 }
84
85 void Dummy::set_loco_reverse(unsigned addr, bool rev)
86 {
87         LocoState &loco = locos[addr];
88         loco.reverse = rev;
89         signal_loco_speed.emit(addr, loco.speed, rev);
90 }
91
92 void Dummy::set_loco_function(unsigned addr, unsigned func, bool state)
93 {
94         signal_loco_function.emit(addr, func, state);
95 }
96
97 void Dummy::set_sensor(unsigned addr, bool state)
98 {
99         if(sensors[addr]!=state)
100         {
101                 sensors[addr] = state;
102                 signal_sensor.emit(addr, state);
103         }
104 }
105
106 bool Dummy::get_sensor(unsigned addr) const
107 {
108         map<unsigned, bool>::const_iterator i = sensors.find(addr);
109         if(i!=sensors.end())
110                 return i->second;
111         return false;
112 }
113
114 void Dummy::tick()
115 {
116         Time::TimeStamp t = Time::now();
117         for(map<unsigned, TurnoutState>::iterator i=turnouts.begin(); i!=turnouts.end(); ++i)
118         {
119                 if(i->second.timeout && t>=i->second.timeout)
120                 {
121                         i->second.state = i->second.pending;
122                         i->second.timeout = Time::TimeStamp();
123                         signal_turnout.emit(i->first, i->second.state);
124                 }
125         }
126 }
127
128 } // namespace R2C2