1 #include <msp/core/refptr.h>
2 #include <msp/net/inet.h>
3 #include <msp/net/resolve.h>
4 #include "libr2c2/aicontrol.h"
5 #include "libr2c2/catalogue.h"
6 #include "libr2c2/driver.h"
7 #include "libr2c2/route.h"
8 #include "libr2c2/train.h"
9 #include "libr2c2/trainrouter.h"
10 #include "libr2c2/trainstatus.h"
11 #include "libr2c2/vehicletype.h"
19 Server::Server(Layout &l):
21 listen_sock(Net::INET),
24 layout.get_driver().signal_power.connect(sigc::hide(sigc::mem_fun(this, &Server::driver_state_changed)));
25 layout.get_driver().signal_halt.connect(sigc::hide(sigc::mem_fun(this, &Server::driver_state_changed)));
26 layout.signal_emergency.connect(sigc::mem_fun(this, &Server::emergency));
28 layout.signal_train_added.connect(sigc::mem_fun(this, &Server::train_added));
30 const map<unsigned, Train *> &trains = layout.get_trains();
31 for(map<unsigned, Train *>::const_iterator i=trains.begin(); i!=trains.end(); ++i)
32 train_added(*i->second);
34 RefPtr<Net::SockAddr> addr = Net::resolve("*", "8315", Net::INET);
35 listen_sock.listen(*addr, 4);
36 listen_sock.signal_data_available.connect(sigc::mem_fun(this, &Server::incoming_connection));
42 void Server::use_event_dispatcher(IO::EventDispatcher &ed)
45 event_disp->add(listen_sock);
48 void Server::incoming_connection()
50 Net::StreamSocket *sock = listen_sock.accept();
52 event_disp->add(*sock);
53 connections.push_back(new Connection(*this, sock));
56 void Server::driver_state_changed()
58 DriverStatePacket pkt;
59 pkt.power = layout.get_driver().get_power();
60 pkt.halt = layout.get_driver().is_halted();
64 void Server::emergency(Block *, const string &msg)
71 void Server::train_added(Train &train)
73 train.signal_control_changed.connect(sigc::bind<0>(sigc::mem_fun(this, &Server::train_control_changed), sigc::ref(train)));
74 train.signal_function_changed.connect(sigc::bind<0>(sigc::mem_fun(this, &Server::train_function_changed), sigc::ref(train)));
75 train.signal_ai_event.connect(sigc::bind<0>(sigc::mem_fun(this, &Server::train_ai_event), sigc::ref(train)));
78 pkt.address = train.get_address();
79 pkt.loco_type = layout.get_catalogue().get_name(&train.get_locomotive_type());
80 pkt.name = train.get_name();
83 if(!train.get_ai_of_type<TrainStatus>())
84 new TrainStatus(train);
87 void Server::train_control_changed(const Train &train, const string &control, float value)
89 TrainControlPacket pkt;
90 pkt.address = train.get_address();
91 pkt.control = control;
96 void Server::train_function_changed(const Train &train, unsigned, bool)
98 TrainFunctionPacket pkt;
99 pkt.address = train.get_address();
100 pkt.functions = train.get_functions();
104 void Server::train_ai_event(const Train &train, TrainAI &ai, const TrainAI::Message &ev)
106 if(ev.type=="route-changed")
108 TrainRoutePacket pkt;
109 pkt.address = train.get_address();
110 if(const Route *route = ev.value.value<const Route *>())
111 pkt.route = route->get_name();
114 else if(ev.type=="status-changed")
116 TrainStatusPacket pkt;
117 pkt.address = train.get_address();
118 pkt.status = ev.value.value<std::string>();
121 else if(ev.type=="target-speed-changed" || ev.type=="reverse-changed")
123 AIControl *control = dynamic_cast<AIControl *>(&ai);
126 TrainAIControlPacket pkt;
127 pkt.address = train.get_address();
128 pkt.target_speed = control->get_target_speed();
129 pkt.reverse = control->get_reverse();
136 void Server::send(const P &pkt)
138 for(vector<Connection *>::const_iterator i=connections.begin(); i!=connections.end(); ++i)
139 if(!(*i)->stale && (*i)->comm.is_handshake_done())
140 (*i)->comm.send(pkt);
144 Server::Connection::Connection(Server &s, Net::StreamSocket *o):
147 comm(*socket, server.proto, *this),
150 socket->signal_end_of_file.connect(sigc::mem_fun(this, &Connection::end_of_file));
151 comm.signal_handshake_done.connect(sigc::mem_fun(this, &Connection::handshake_done));
152 comm.signal_error.connect(sigc::mem_fun(this, &Connection::comm_error));
153 comm.initiate_handshake();
156 Server::Connection::~Connection()
161 void Server::Connection::handshake_done()
164 DriverStatePacket pkt;
165 pkt.power = server.layout.get_driver().get_power();
166 pkt.halt = server.layout.get_driver().is_halted();
170 const set<Route *> &routes = server.layout.get_all<Route>();
171 for(set<Route *>::const_iterator i=routes.begin(); i!=routes.end(); ++i)
172 if(!(*i)->is_temporary())
175 pkt.name = (*i)->get_name();
179 const Catalogue &cat = server.layout.get_catalogue();
180 const map<unsigned, Train *> &trains = server.layout.get_trains();
181 for(map<unsigned, Train *>::const_iterator i=trains.begin(); i!=trains.end(); ++i)
183 const Train &train = *i->second;
187 pkt.address = train.get_address();
188 pkt.loco_type = cat.get_name(&train.get_locomotive_type());
189 pkt.name = train.get_name();
192 if(AIControl *control = train.get_ai_of_type<AIControl>())
194 TrainAIControlPacket pkt;
195 pkt.address = train.get_address();
196 pkt.target_speed = control->get_target_speed();
197 pkt.reverse = control->get_reverse();
200 for(unsigned j=0;; ++j)
202 const char *name = train.get_controller().enumerate_controls(j);
206 TrainControlPacket pkt;
207 pkt.address = train.get_address();
209 pkt.value = train.get_control(name);
213 TrainFunctionPacket pkt;
214 pkt.address = train.get_address();
215 pkt.functions = train.get_functions();
218 if(TrainStatus *status = train.get_ai_of_type<TrainStatus>())
220 TrainStatusPacket pkt;
221 pkt.address = train.get_address();
222 pkt.status = status->get_status();
225 if(TrainRouter *router = train.get_ai_of_type<TrainRouter>())
227 TrainRoutePacket pkt;
228 pkt.address = train.get_address();
229 pkt.route = router->get_route()->get_name();
235 void Server::Connection::end_of_file()
240 void Server::Connection::receive(const DriverStatePacket &pkt)
242 Driver &driver = server.layout.get_driver();
243 if(pkt.power!=driver.get_power())
244 driver.set_power(pkt.power);
245 if(pkt.halt!=driver.is_halted())
246 driver.halt(pkt.halt);
249 void Server::Connection::receive(const TrainControlPacket &pkt)
253 Train &train = server.layout.get_train(pkt.address);
254 train.set_control(pkt.control, pkt.value);
256 catch(const exception &e)
262 void Server::Connection::receive(const TrainFunctionPacket &pkt)
266 Train &train = server.layout.get_train(pkt.address);
267 for(unsigned i=0; i<9; ++i)
268 if(((pkt.functions^train.get_functions())>>i)&1)
269 train.set_function(i, (pkt.functions>>i)&1);
271 catch(const exception &e)
277 void Server::Connection::receive(const TrainAIControlPacket &pkt)
281 Train &train = server.layout.get_train(pkt.address);
282 train.ai_message(TrainAI::Message("set-target-speed", pkt.target_speed));
283 train.ai_message(TrainAI::Message("set-reverse", static_cast<bool>(pkt.reverse)));
285 catch(const exception &e)
291 void Server::Connection::receive(const TrainRoutePacket &pkt)
295 Train &train = server.layout.get_train(pkt.address);
296 if(pkt.route.empty())
297 train.ai_message(TrainAI::Message("clear-route"));
300 Route &route = server.layout.get_route(pkt.route);
301 train.ai_message(TrainAI::Message("set-route", &route));
304 catch(const exception &e)
310 void Server::Connection::comm_error(const exception &)
315 void Server::Connection::error(const string &msg)