3 This file is part of the MSP Märklin suite
4 Copyright © 2009-2010 Mikkosoft Productions, Mikko Rasa
5 Distributed under the GPL
8 #include <msp/net/inet.h>
9 #include "libmarklin/locotype.h"
10 #include "libmarklin/route.h"
11 #include "libmarklin/train.h"
19 Server::Server(Layout &l):
21 listen_sock(Net::INET),
24 layout.signal_train_added.connect(sigc::mem_fun(this, &Server::train_added));
26 const map<unsigned, Train *> &trains = layout.get_trains();
27 for(map<unsigned, Train *>::const_iterator i=trains.begin(); i!=trains.end(); ++i)
28 train_added(*i->second);
30 listen_sock.listen(Net::InetAddr(0, 8315), 4);
31 listen_sock.signal_data_available.connect(sigc::mem_fun(this, &Server::incoming_connection));
34 void Server::use_event_dispatcher(IO::EventDispatcher &ed)
37 event_disp->add(listen_sock);
40 void Server::incoming_connection()
42 Net::StreamSocket *sock = listen_sock.accept();
44 event_disp->add(*sock);
45 connections.push_back(new Connection(*this, sock));
48 void Server::train_added(Train &train)
50 train.signal_target_speed_changed.connect(sigc::bind<0>(sigc::mem_fun(this, &Server::train_speed_changed), sigc::ref(train)));
51 train.signal_reverse_changed.connect(sigc::bind<0>(sigc::mem_fun(this, &Server::train_reverse_changed), sigc::ref(train)));
52 train.signal_function_changed.connect(sigc::bind<0>(sigc::mem_fun(this, &Server::train_function_changed), sigc::ref(train)));
53 train.signal_route_changed.connect(sigc::bind<0>(sigc::mem_fun(this, &Server::train_route_changed), sigc::ref(train)));
54 train.signal_status_changed.connect(sigc::bind<0>(sigc::mem_fun(this, &Server::train_status_changed), sigc::ref(train)));
57 pkt.address = train.get_address();
58 pkt.loco_type = train.get_locomotive_type().get_article_number();
59 pkt.name = train.get_name();
63 void Server::train_speed_changed(const Train &train, unsigned speed)
66 pkt.address = train.get_address();
68 pkt.reverse = train.get_reverse();
72 void Server::train_reverse_changed(const Train &train, bool reverse)
75 pkt.address = train.get_address();
76 pkt.speed = train.get_target_speed();
77 pkt.reverse = reverse;
81 void Server::train_function_changed(const Train &train, unsigned, bool)
83 TrainFunctionPacket pkt;
84 pkt.address = train.get_address();
85 pkt.functions = train.get_functions();
89 void Server::train_route_changed(const Train &train, const Route *route)
92 pkt.address = train.get_address();
94 pkt.route = route->get_name();
98 void Server::train_status_changed(const Train &train, const string &status)
100 TrainStatusPacket pkt;
101 pkt.address = train.get_address();
107 void Server::send(const P &pkt)
109 for(vector<Connection *>::const_iterator i=connections.begin(); i!=connections.end(); ++i)
111 (*i)->comm.send(pkt);
115 Server::Connection::Connection(Server &s, Net::StreamSocket *o):
118 comm(*socket, server.proto, *this)
120 socket->signal_end_of_file.connect(sigc::mem_fun(this, &Connection::end_of_file));
121 comm.signal_handshake_done.connect(sigc::mem_fun(this, &Connection::handshake_done));
122 comm.initiate_handshake();
125 Server::Connection::~Connection()
130 void Server::Connection::handshake_done()
132 const map<string, Route *> &routes = server.layout.get_routes();
133 for(map<string, Route *>::const_iterator i=routes.begin(); i!=routes.end(); ++i)
140 const map<unsigned, Train *> &trains = server.layout.get_trains();
141 for(map<unsigned, Train *>::const_iterator i=trains.begin(); i!=trains.end(); ++i)
143 const Train &train = *i->second;
147 pkt.address = train.get_address();
148 pkt.loco_type = train.get_locomotive_type().get_article_number();
149 pkt.name = train.get_name();
153 TrainSpeedPacket pkt;
154 pkt.address = train.get_address();
155 pkt.speed = train.get_target_speed();
156 pkt.reverse = train.get_reverse();
160 TrainFunctionPacket pkt;
161 pkt.address = train.get_address();
162 pkt.functions = train.get_functions();
166 TrainStatusPacket pkt;
167 pkt.address = train.get_address();
168 pkt.status = train.get_status();
171 if(train.get_route())
173 TrainRoutePacket pkt;
174 pkt.address = train.get_address();
175 pkt.route = train.get_route()->get_name();
181 void Server::Connection::end_of_file()
187 void Server::Connection::receive(const TrainSpeedPacket &pkt)
191 Train &train = server.layout.get_train(pkt.address);
192 if(pkt.reverse!=train.get_reverse())
193 train.set_reverse(pkt.reverse);
195 train.set_speed(pkt.speed);
197 catch(const Exception &e)
203 void Server::Connection::receive(const TrainFunctionPacket &pkt)
207 Train &train = server.layout.get_train(pkt.address);
208 for(unsigned i=0; i<9; ++i)
209 if(((pkt.functions^train.get_functions())>>i)&1)
210 train.set_function(i, (pkt.functions>>i)&1);
212 catch(const Exception &e)
218 void Server::Connection::receive(const TrainRoutePacket &pkt)
222 Train &train = server.layout.get_train(pkt.address);
223 if(pkt.route.empty())
227 Route &route = server.layout.get_route(pkt.route);
228 train.set_route(&route);
231 catch(const Exception &e)
237 void Server::Connection::error(const string &msg)
244 } // namespace Marklin