]> git.tdb.fi Git - r2c2.git/blob - source/libr2c2/centralstation.h
Add basic support for signals
[r2c2.git] / source / libr2c2 / centralstation.h
1 #ifndef LIBR2C2_CENTRALSTATION_H_
2 #define LIBR2C2_CENTRALSTATION_H_
3
4 #include <msp/net/streamsocket.h>
5 #include <msp/time/timestamp.h>
6 #include "driver.h"
7
8 namespace R2C2 {
9
10 class CentralStation: public Driver
11 {
12 private:
13         struct Tag
14         {
15                 std::string type;
16                 unsigned code;
17                 std::string value;
18
19                 Tag();
20
21                 operator bool() const;
22         };
23
24         struct Message
25         {
26                 typedef std::multimap<std::string, std::string> AttribMap;
27                 typedef std::map<unsigned, AttribMap> ObjectMap;
28         
29                 Tag header;
30                 ObjectMap content;
31                 Tag footer;
32
33                 operator bool() const;
34         };
35
36         enum Error
37         {
38                 OK,
39                 NERROR_UNKNOWNCOMMAND = 10,
40                 NERROR_UNKNOWNARG = 11,
41                 NERROR_UNKNOWNPARAM = 12,
42                 NERROR_UNKNOWNID = 15,
43                 NERROR_SIZE = 20,
44                 NERROR_NOTALLOWED = 22,
45                 NERROR_NOCONTROL = 25,
46                 NERROR_NOCREATE = 28,
47                 NERROR_NOARG = 29
48         };
49
50         enum Protocol
51         {
52                 MM,
53                 MM_27,
54                 MFX
55         };
56
57         struct Locomotive
58         {
59                 std::string name;
60                 Protocol protocol;
61                 unsigned address;
62                 unsigned speed;
63                 bool reverse;
64                 unsigned func_mask;
65                 unsigned funcs;
66                 bool control;
67
68                 Locomotive();
69         };
70
71         struct MagnetAccessory
72         {
73                 enum Type
74                 {
75                         TURNOUT,
76                         SIGNAL
77                 };
78
79                 enum Symbol
80                 {
81                         TURNOUT_LEFT = 0,
82                         TURNOUT_RIGHT = 1,
83                         TURNOUT_THREEWAY = 2,
84                         TURNOUT_DOUBLESLIP = 3,
85                         SEMAPHORE_HOME = 5,
86                         TURNOUT_CURVED_LEFT = 21,
87                         TURNOUT_CURVED_RIGHT = 22
88                 };
89
90                 unsigned address;
91                 Type type;
92                 Symbol symbol;
93                 unsigned state;
94                 unsigned bits;
95                 bool synced;
96
97                 MagnetAccessory();
98         };
99
100         struct Sensor
101         {
102                 bool state;
103
104                 Sensor();
105         };
106
107         typedef std::map<unsigned, unsigned> AddressMap;
108         typedef std::map<unsigned, Locomotive> LocoMap;
109         typedef std::map<unsigned, MagnetAccessory> AccessoryMap;
110         typedef std::map<unsigned, Sensor> SensorMap;
111
112         Msp::Net::StreamSocket socket;
113         std::list<std::string> cmd_queue;
114         unsigned pending_commands;
115         bool power;
116         bool halted;
117         std::string in_buffer;
118         LocoMap locos;
119         AddressMap loco_addr;
120         bool locos_synced;
121         AccessoryMap accessories;
122         AddressMap accessory_addr;
123         bool accessories_synced;
124         SensorMap sensors;
125         std::vector<unsigned> s88;
126         bool sensors_synced;
127
128 public:
129         CentralStation(const std::string &);
130         ~CentralStation();
131
132         virtual void set_power(bool);
133         virtual bool get_power() const { return power; }
134         virtual void halt(bool);
135         virtual bool is_halted() const { return halted; }
136
137         virtual const char *enumerate_protocols(unsigned) const;
138         virtual unsigned get_protocol_speed_steps(const std::string &) const;
139
140         virtual void add_loco(unsigned, const std::string &, const VehicleType &);
141         virtual void set_loco_speed(unsigned, unsigned);
142         virtual void set_loco_reverse(unsigned, bool);
143         virtual void set_loco_function(unsigned, unsigned, bool);
144
145         virtual void add_turnout(unsigned, const TrackType &);
146         virtual void set_turnout(unsigned, unsigned);
147         virtual unsigned get_turnout(unsigned) const;
148
149         virtual void add_signal(unsigned, const SignalType &);
150         virtual void set_signal(unsigned, unsigned);
151         virtual unsigned get_signal(unsigned) const;
152
153 private:
154         MagnetAccessory &add_accessory(unsigned, MagnetAccessory::Type, MagnetAccessory::Symbol);
155         void set_accessory_state(unsigned, MagnetAccessory::Type, unsigned);
156         unsigned get_accessory_state(unsigned, MagnetAccessory::Type) const;
157         void accessory_state_changed(const MagnetAccessory &) const;
158
159 public:
160         virtual void add_sensor(unsigned);
161         virtual void set_sensor(unsigned, bool) { }
162         virtual bool get_sensor(unsigned) const;
163
164         virtual void tick();
165         virtual void flush();
166
167 private:
168         void command(const std::string &, bool = false);
169         Message receive();
170         void process_reply(const Message &);
171         void process_event(const Message &);
172         void process_object(unsigned, const Message::AttribMap &);
173         Protocol map_protocol(const std::string &) const;
174         template<typename T>
175         unsigned map_address(const std::map<unsigned, T> &, const AddressMap &, unsigned) const;
176         void skip(std::string::iterator &, const std::string::iterator &, const std::string &) const;
177         std::string parse_token(std::string::iterator &, const std::string::iterator &, const std::string &) const;
178         Tag parse_tag(std::string::iterator &, const std::string::iterator &) const;
179         Message parse_message(std::string::iterator &, const std::string::iterator &) const;
180 };
181
182 } // namespace R2C2
183
184 #endif