]> git.tdb.fi Git - r2c2.git/blob - source/libr2c2/centralstation.h
Detect curved turnouts and assign appropriate symbols to them
[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 Turnout
72         {
73                 enum Symbol
74                 {
75                         LEFT = 0,
76                         RIGHT = 1,
77                         THREEWAY = 2,
78                         DOUBLESLIP = 3,
79                         CURVED_LEFT = 21,
80                         CURVED_RIGHT = 22
81                 };
82
83                 unsigned address;
84                 unsigned symbol;
85                 unsigned state;
86                 unsigned bits;
87                 bool synced;
88
89                 Turnout();
90         };
91
92         struct Sensor
93         {
94                 bool state;
95
96                 Sensor();
97         };
98
99         typedef std::map<unsigned, unsigned> AddressMap;
100         typedef std::map<unsigned, Locomotive> LocoMap;
101         typedef std::map<unsigned, Turnout> TurnoutMap;
102         typedef std::map<unsigned, Sensor> SensorMap;
103
104         Msp::Net::StreamSocket socket;
105         std::list<std::string> cmd_queue;
106         unsigned pending_commands;
107         bool power;
108         bool halted;
109         std::string in_buffer;
110         LocoMap locos;
111         AddressMap loco_addr;
112         bool locos_synced;
113         TurnoutMap turnouts;
114         AddressMap turnout_addr;
115         bool turnouts_synced;
116         SensorMap sensors;
117         std::vector<unsigned> s88;
118         bool sensors_synced;
119
120 public:
121         CentralStation(const std::string &);
122         ~CentralStation();
123
124         virtual void set_power(bool);
125         virtual bool get_power() const { return power; }
126         virtual void halt(bool);
127         virtual bool is_halted() const { return halted; }
128
129         virtual const char *enumerate_protocols(unsigned) const;
130         virtual unsigned get_protocol_speed_steps(const std::string &) const;
131
132         virtual void add_loco(unsigned, const std::string &, const VehicleType &);
133         virtual void set_loco_speed(unsigned, unsigned);
134         virtual void set_loco_reverse(unsigned, bool);
135         virtual void set_loco_function(unsigned, unsigned, bool);
136
137         virtual void add_turnout(unsigned, const TrackType &);
138         virtual void set_turnout(unsigned, unsigned);
139         virtual unsigned get_turnout(unsigned) const;
140
141         virtual void add_sensor(unsigned);
142         virtual void set_sensor(unsigned, bool) { }
143         virtual bool get_sensor(unsigned) const;
144
145         virtual void tick();
146         virtual void flush();
147
148 private:
149         void command(const std::string &, bool = false);
150         Message receive();
151         void process_reply(const Message &);
152         void process_event(const Message &);
153         void process_object(unsigned, const Message::AttribMap &);
154         Protocol map_protocol(const std::string &) const;
155         template<typename T>
156         unsigned map_address(const std::map<unsigned, T> &, const AddressMap &, unsigned) const;
157         void skip(std::string::iterator &, const std::string::iterator &, const std::string &) const;
158         std::string parse_token(std::string::iterator &, const std::string::iterator &, const std::string &) const;
159         Tag parse_tag(std::string::iterator &, const std::string::iterator &) const;
160         Message parse_message(std::string::iterator &, const std::string::iterator &) const;
161 };
162
163 } // namespace R2C2
164
165 #endif