3 This file is part of the MSP Märklin suite
4 Copyright © 2009 Mikkosoft Productions, Mikko Rasa
5 Distributed under the GPL
8 #include <msp/net/inet.h>
9 #include "libmarklin/control.h"
10 #include "libmarklin/locomotive.h"
11 #include "libmarklin/locotype.h"
19 Server::Server(TrafficManager &tm):
21 listen_sock(Net::INET),
24 const list<Train *> &trains = trfc_mgr.get_trains();
25 for(list<Train *>::const_iterator i=trains.begin(); i!=trains.end(); ++i)
27 Locomotive &loco = (*i)->get_locomotive();
28 (*i)->signal_target_speed_changed.connect(sigc::bind<0>(sigc::mem_fun(this, &Server::train_speed_changed), sigc::ref(**i)));
29 loco.signal_function_changed.connect(sigc::bind<0>(sigc::mem_fun(this, &Server::train_function_changed), sigc::ref(**i)));
30 (*i)->signal_status_changed.connect(sigc::bind<0>(sigc::mem_fun(this, &Server::train_status_changed), sigc::ref(**i)));
33 listen_sock.listen(Net::InetAddr(0, 8315), 4);
34 listen_sock.signal_data_available.connect(sigc::mem_fun(this, &Server::incoming_connection));
37 void Server::use_event_dispatcher(IO::EventDispatcher &ed)
40 event_disp->add(listen_sock);
43 void Server::incoming_connection()
45 Net::StreamSocket *sock = listen_sock.accept();
47 event_disp->add(*sock);
48 connections.push_back(new Connection(*this, sock));
51 void Server::train_added(Train &train)
53 Locomotive &loco = train.get_locomotive();
54 train.signal_target_speed_changed.connect(sigc::bind<0>(sigc::mem_fun(this, &Server::train_speed_changed), sigc::ref(train)));
55 loco.signal_function_changed.connect(sigc::bind<0>(sigc::mem_fun(this, &Server::train_function_changed), sigc::ref(train)));
56 train.signal_status_changed.connect(sigc::bind<0>(sigc::mem_fun(this, &Server::train_status_changed), sigc::ref(train)));
59 pkt.address = loco.get_address();
60 pkt.loco_type = loco.get_type().get_article_number();
61 pkt.name = train.get_name();
65 void Server::train_speed_changed(const Train &train, unsigned speed)
68 pkt.address = train.get_locomotive().get_address();
70 pkt.reverse = train.get_locomotive().get_reverse();
74 void Server::train_function_changed(const Train &train, unsigned, bool)
76 TrainFunctionPacket pkt;
77 pkt.address = train.get_locomotive().get_address();
78 pkt.functions = train.get_locomotive().get_functions();
82 void Server::train_status_changed(const Train &train, const string &status)
84 TrainStatusPacket pkt;
85 pkt.address = train.get_locomotive().get_address();
91 void Server::send(const P &pkt)
93 for(vector<Connection *>::const_iterator i=connections.begin(); i!=connections.end(); ++i)
99 Server::Connection::Connection(Server &s, Net::StreamSocket *o):
102 comm(*socket, server.proto, *this)
104 socket->signal_end_of_file.connect(sigc::mem_fun(this, &Connection::end_of_file));
105 comm.signal_handshake_done.connect(sigc::mem_fun(this, &Connection::handshake_done));
106 comm.initiate_handshake();
109 Server::Connection::~Connection()
114 void Server::Connection::handshake_done()
116 const list<Train *> &trains = server.trfc_mgr.get_trains();
117 for(list<Train *>::const_iterator i=trains.begin(); i!=trains.end(); ++i)
119 Locomotive &loco = (*i)->get_locomotive();
123 pkt.address = loco.get_address();
124 pkt.loco_type = loco.get_type().get_article_number();
125 pkt.name = (*i)->get_name();
129 TrainSpeedPacket pkt;
130 pkt.address = loco.get_address();
131 pkt.speed = (*i)->get_target_speed();
132 pkt.reverse = loco.get_reverse();
136 TrainFunctionPacket pkt;
137 pkt.address = loco.get_address();
138 pkt.functions = loco.get_functions();
142 TrainStatusPacket pkt;
143 pkt.address = loco.get_address();
144 pkt.status = (*i)->get_status();
150 void Server::Connection::end_of_file()
156 void Server::Connection::receive(const TrainSpeedPacket &pkt)
158 Locomotive &loco = server.trfc_mgr.get_control().get_locomotive(pkt.address);
159 Train &train = server.trfc_mgr.get_train_by_locomotive(loco);
160 if(pkt.reverse!=loco.get_reverse())
161 train.set_reverse(pkt.reverse);
163 train.set_speed(pkt.speed);
166 void Server::Connection::receive(const TrainFunctionPacket &pkt)
168 Locomotive &loco = server.trfc_mgr.get_control().get_locomotive(pkt.address);
169 for(unsigned i=0; i<9; ++i)
170 if(((pkt.functions^loco.get_functions())>>i)&1)
171 loco.set_function(i, (pkt.functions>>i)&1);
174 } // namespace Marklin