1 #include <msp/net/inet.h>
2 #include "libr2c2/driver.h"
3 #include "libr2c2/route.h"
4 #include "libr2c2/train.h"
5 #include "libr2c2/vehicletype.h"
13 Server::Server(Layout &l):
15 listen_sock(Net::INET),
18 layout.get_driver().signal_power.connect(sigc::hide(sigc::mem_fun(this, &Server::driver_state_changed)));
19 layout.get_driver().signal_halt.connect(sigc::hide(sigc::mem_fun(this, &Server::driver_state_changed)));
20 layout.signal_emergency.connect(sigc::mem_fun(this, &Server::emergency));
22 layout.signal_train_added.connect(sigc::mem_fun(this, &Server::train_added));
24 const map<unsigned, Train *> &trains = layout.get_trains();
25 for(map<unsigned, Train *>::const_iterator i=trains.begin(); i!=trains.end(); ++i)
26 train_added(*i->second);
28 listen_sock.listen(Net::InetAddr(0, 8315), 4);
29 listen_sock.signal_data_available.connect(sigc::mem_fun(this, &Server::incoming_connection));
32 void Server::use_event_dispatcher(IO::EventDispatcher &ed)
35 event_disp->add(listen_sock);
38 void Server::incoming_connection()
40 Net::StreamSocket *sock = listen_sock.accept();
42 event_disp->add(*sock);
43 connections.push_back(new Connection(*this, sock));
46 void Server::driver_state_changed()
48 DriverStatePacket pkt;
49 pkt.power = layout.get_driver().get_power();
50 pkt.halt = layout.get_driver().is_halted();
54 void Server::emergency(const string &msg)
61 void Server::train_added(Train &train)
63 train.signal_control_changed.connect(sigc::bind<0>(sigc::mem_fun(this, &Server::train_control_changed), sigc::ref(train)));
64 train.signal_function_changed.connect(sigc::bind<0>(sigc::mem_fun(this, &Server::train_function_changed), sigc::ref(train)));
65 train.signal_route_changed.connect(sigc::bind<0>(sigc::mem_fun(this, &Server::train_route_changed), sigc::ref(train)));
66 train.signal_status_changed.connect(sigc::bind<0>(sigc::mem_fun(this, &Server::train_status_changed), sigc::ref(train)));
69 pkt.address = train.get_address();
70 pkt.loco_type = train.get_locomotive_type().get_article_number().str();
71 pkt.name = train.get_name();
74 TrainStatus *status = new TrainStatus(train);
75 status->set_tag("server:status");
76 status->signal_changed.connect(sigc::bind<0>(sigc::mem_fun(this, &Server::train_status_changed), sigc::ref(train)));
79 void Server::train_control_changed(const Train &train, const string &control, float value)
81 TrainControlPacket pkt;
82 pkt.address = train.get_address();
83 pkt.control = control;
88 void Server::train_function_changed(const Train &train, unsigned, bool)
90 TrainFunctionPacket pkt;
91 pkt.address = train.get_address();
92 pkt.functions = train.get_functions();
96 void Server::train_route_changed(const Train &train, const Route *route)
99 pkt.address = train.get_address();
101 pkt.route = route->get_name();
105 void Server::train_status_changed(const Train &train, const string &status)
107 TrainStatusPacket pkt;
108 pkt.address = train.get_address();
114 void Server::send(const P &pkt)
116 for(vector<Connection *>::const_iterator i=connections.begin(); i!=connections.end(); ++i)
117 if(!(*i)->stale && (*i)->comm.is_handshake_done())
121 (*i)->comm.send(pkt);
131 Server::Connection::Connection(Server &s, Net::StreamSocket *o):
134 comm(*socket, server.proto, *this)
136 socket->signal_end_of_file.connect(sigc::mem_fun(this, &Connection::end_of_file));
137 comm.signal_handshake_done.connect(sigc::mem_fun(this, &Connection::handshake_done));
138 comm.initiate_handshake();
141 Server::Connection::~Connection()
146 void Server::Connection::handshake_done()
149 DriverStatePacket pkt;
150 pkt.power = server.layout.get_driver().get_power();
151 pkt.halt = server.layout.get_driver().is_halted();
155 const set<Route *> &routes = server.layout.get_routes();
156 for(set<Route *>::const_iterator i=routes.begin(); i!=routes.end(); ++i)
157 if(!(*i)->is_temporary())
160 pkt.name = (*i)->get_name();
164 const map<unsigned, Train *> &trains = server.layout.get_trains();
165 for(map<unsigned, Train *>::const_iterator i=trains.begin(); i!=trains.end(); ++i)
167 const Train &train = *i->second;
171 pkt.address = train.get_address();
172 pkt.loco_type = train.get_locomotive_type().get_article_number().str();
173 pkt.name = train.get_name();
176 for(unsigned j=0;; ++j)
178 const char *name = train.get_controller().enumerate_controls(j);
182 TrainControlPacket pkt;
183 pkt.address = train.get_address();
185 pkt.value = train.get_control(name);
189 TrainFunctionPacket pkt;
190 pkt.address = train.get_address();
191 pkt.functions = train.get_functions();
194 if(TrainStatus *status = dynamic_cast<TrainStatus *>(train.get_tagged_ai("server:status")))
196 TrainStatusPacket pkt;
197 pkt.address = train.get_address();
198 pkt.status = status->get_status();
201 if(train.get_route())
203 TrainRoutePacket pkt;
204 pkt.address = train.get_address();
205 pkt.route = train.get_route()->get_name();
211 void Server::Connection::end_of_file()
217 void Server::Connection::receive(const DriverStatePacket &pkt)
219 Driver &driver = server.layout.get_driver();
220 if(pkt.power!=driver.get_power())
221 driver.set_power(pkt.power);
222 if(pkt.halt!=driver.is_halted())
223 driver.halt(pkt.halt);
226 void Server::Connection::receive(const TrainControlPacket &pkt)
230 Train &train = server.layout.get_train(pkt.address);
231 train.set_control(pkt.control, pkt.value);
233 catch(const Exception &e)
239 void Server::Connection::receive(const TrainFunctionPacket &pkt)
243 Train &train = server.layout.get_train(pkt.address);
244 for(unsigned i=0; i<9; ++i)
245 if(((pkt.functions^train.get_functions())>>i)&1)
246 train.set_function(i, (pkt.functions>>i)&1);
248 catch(const Exception &e)
254 void Server::Connection::receive(const TrainRoutePacket &pkt)
258 Train &train = server.layout.get_train(pkt.address);
259 if(pkt.route.empty())
263 Route &route = server.layout.get_route(pkt.route);
264 train.set_route(&route);
267 catch(const Exception &e)
273 void Server::Connection::error(const string &msg)