3 This file is part of R²C²
4 Copyright © 2009-2011 Mikkosoft Productions, Mikko Rasa
5 Distributed under the GPL
8 #include <msp/net/inet.h>
9 #include "libr2c2/driver.h"
10 #include "libr2c2/route.h"
11 #include "libr2c2/train.h"
12 #include "libr2c2/vehicletype.h"
20 Server::Server(Layout &l):
22 listen_sock(Net::INET),
25 layout.get_driver().signal_power.connect(sigc::hide(sigc::mem_fun(this, &Server::driver_state_changed)));
26 layout.get_driver().signal_halt.connect(sigc::hide(sigc::mem_fun(this, &Server::driver_state_changed)));
27 layout.signal_emergency.connect(sigc::mem_fun(this, &Server::emergency));
29 layout.signal_train_added.connect(sigc::mem_fun(this, &Server::train_added));
31 const map<unsigned, Train *> &trains = layout.get_trains();
32 for(map<unsigned, Train *>::const_iterator i=trains.begin(); i!=trains.end(); ++i)
33 train_added(*i->second);
35 listen_sock.listen(Net::InetAddr(0, 8315), 4);
36 listen_sock.signal_data_available.connect(sigc::mem_fun(this, &Server::incoming_connection));
39 void Server::use_event_dispatcher(IO::EventDispatcher &ed)
42 event_disp->add(listen_sock);
45 void Server::incoming_connection()
47 Net::StreamSocket *sock = listen_sock.accept();
49 event_disp->add(*sock);
50 connections.push_back(new Connection(*this, sock));
53 void Server::driver_state_changed()
55 DriverStatePacket pkt;
56 pkt.power = layout.get_driver().get_power();
57 pkt.halt = layout.get_driver().is_halted();
61 void Server::emergency(const string &msg)
68 void Server::train_added(Train &train)
70 train.signal_control_changed.connect(sigc::bind<0>(sigc::mem_fun(this, &Server::train_control_changed), sigc::ref(train)));
71 train.signal_function_changed.connect(sigc::bind<0>(sigc::mem_fun(this, &Server::train_function_changed), sigc::ref(train)));
72 train.signal_route_changed.connect(sigc::bind<0>(sigc::mem_fun(this, &Server::train_route_changed), sigc::ref(train)));
73 train.signal_status_changed.connect(sigc::bind<0>(sigc::mem_fun(this, &Server::train_status_changed), sigc::ref(train)));
76 pkt.address = train.get_address();
77 pkt.loco_type = train.get_locomotive_type().get_article_number().str();
78 pkt.name = train.get_name();
82 void Server::train_control_changed(const Train &train, const string &control, float value)
84 TrainControlPacket pkt;
85 pkt.address = train.get_address();
86 pkt.control = control;
91 void Server::train_function_changed(const Train &train, unsigned, bool)
93 TrainFunctionPacket pkt;
94 pkt.address = train.get_address();
95 pkt.functions = train.get_functions();
99 void Server::train_route_changed(const Train &train, const Route *route)
101 TrainRoutePacket pkt;
102 pkt.address = train.get_address();
104 pkt.route = route->get_name();
108 void Server::train_status_changed(const Train &train, const string &status)
110 TrainStatusPacket pkt;
111 pkt.address = train.get_address();
117 void Server::send(const P &pkt)
119 for(vector<Connection *>::const_iterator i=connections.begin(); i!=connections.end(); ++i)
120 if(!(*i)->stale && (*i)->comm.is_handshake_done())
124 (*i)->comm.send(pkt);
134 Server::Connection::Connection(Server &s, Net::StreamSocket *o):
137 comm(*socket, server.proto, *this)
139 socket->signal_end_of_file.connect(sigc::mem_fun(this, &Connection::end_of_file));
140 comm.signal_handshake_done.connect(sigc::mem_fun(this, &Connection::handshake_done));
141 comm.initiate_handshake();
144 Server::Connection::~Connection()
149 void Server::Connection::handshake_done()
152 DriverStatePacket pkt;
153 pkt.power = server.layout.get_driver().get_power();
154 pkt.halt = server.layout.get_driver().is_halted();
158 const set<Route *> &routes = server.layout.get_routes();
159 for(set<Route *>::const_iterator i=routes.begin(); i!=routes.end(); ++i)
160 if(!(*i)->is_temporary())
163 pkt.name = (*i)->get_name();
167 const map<unsigned, Train *> &trains = server.layout.get_trains();
168 for(map<unsigned, Train *>::const_iterator i=trains.begin(); i!=trains.end(); ++i)
170 const Train &train = *i->second;
174 pkt.address = train.get_address();
175 pkt.loco_type = train.get_locomotive_type().get_article_number().str();
176 pkt.name = train.get_name();
179 for(unsigned j=0;; ++j)
181 const char *name = train.get_controller().enumerate_controls(j);
185 TrainControlPacket pkt;
186 pkt.address = train.get_address();
188 pkt.value = train.get_control(name);
192 TrainFunctionPacket pkt;
193 pkt.address = train.get_address();
194 pkt.functions = train.get_functions();
198 TrainStatusPacket pkt;
199 pkt.address = train.get_address();
200 pkt.status = train.get_status();
203 if(train.get_route())
205 TrainRoutePacket pkt;
206 pkt.address = train.get_address();
207 pkt.route = train.get_route()->get_name();
213 void Server::Connection::end_of_file()
219 void Server::Connection::receive(const DriverStatePacket &pkt)
221 Driver &driver = server.layout.get_driver();
222 if(pkt.power!=driver.get_power())
223 driver.set_power(pkt.power);
224 if(pkt.halt!=driver.is_halted())
225 driver.halt(pkt.halt);
228 void Server::Connection::receive(const TrainControlPacket &pkt)
232 Train &train = server.layout.get_train(pkt.address);
233 train.set_control(pkt.control, pkt.value);
235 catch(const Exception &e)
241 void Server::Connection::receive(const TrainFunctionPacket &pkt)
245 Train &train = server.layout.get_train(pkt.address);
246 for(unsigned i=0; i<9; ++i)
247 if(((pkt.functions^train.get_functions())>>i)&1)
248 train.set_function(i, (pkt.functions>>i)&1);
250 catch(const Exception &e)
256 void Server::Connection::receive(const TrainRoutePacket &pkt)
260 Train &train = server.layout.get_train(pkt.address);
261 if(pkt.route.empty())
265 Route &route = server.layout.get_route(pkt.route);
266 train.set_route(&route);
269 catch(const Exception &e)
275 void Server::Connection::error(const string &msg)