]> git.llucax.com Git - z.facultad/75.42/plaqui.git/blob - Server/src/plant.cpp
Para los docs
[z.facultad/75.42/plaqui.git] / Server / src / plant.cpp
1 // vim: set noexpandtab tabstop=4 shiftwidth=4:
2 //----------------------------------------------------------------------------
3 //                                  PlaQui
4 //----------------------------------------------------------------------------
5 // This file is part of PlaQui.
6 //
7 // PlaQui is free software; you can redistribute it and/or modify it under the
8 // terms of the GNU General Public License as published by the Free Software
9 // Foundation; either version 2 of the License, or (at your option) any later
10 // version.
11 //
12 // PlaQui is distributed in the hope that it will be useful, but WITHOUT ANY
13 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 // FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
15 // details.
16 //
17 // You should have received a copy of the GNU General Public License along
18 // with PlaQui; if not, write to the Free Software Foundation, Inc., 59 Temple
19 // Place, Suite 330, Boston, MA  02111-1307  USA
20 //----------------------------------------------------------------------------
21 // Creado:  dom nov 16 13:03:33 ART 2003
22 // Autores: Leandro Lucarella <llucare@fi.uba.ar>
23 //----------------------------------------------------------------------------
24 //
25 // $Id$
26 //
27
28 #include "plaqui/server/plant.h"
29 #include <glibmm/timer.h>
30 #include <sigc++/class_slot.h>
31 #include <fstream>
32 #ifdef DEBUG
33 #       include <iostream>
34 #endif // DEBUG
35
36 using namespace std;
37
38 namespace PlaQui {
39
40 namespace Server {
41
42 Plant::~Plant(void) {
43 #ifdef DEBUG
44         cerr << __FILE__ << "(" << __LINE__ << ")"
45                 << ": destructor." << endl;
46 #endif // DEBUG
47         // Mando a terminar todas las transmisiones.
48         transmissions_mutex.lock();
49         for (TransmitterList::iterator trans = transmissions.begin();
50                         trans != transmissions.end(); trans++) {
51                 (*trans)->finish();
52         }
53         TransmitterList::size_type count = transmissions.size();
54         transmissions_mutex.unlock();
55         // Espero que terminen realmente.
56         while (count) {
57                 Glib::usleep(10000); // 10 milisegundos
58                 transmissions_mutex.lock();
59                 count = transmissions.size();
60                 transmissions_mutex.unlock();
61         }
62 }
63
64 Plant::Plant(const string& filename): simulator(filename), filename(filename),
65                 wait_time(DEFAULT_WAIT_TIME), paused(true) {
66 #ifdef DEBUG
67         cerr << __FILE__ << "(" << __LINE__ << ")"
68                 << ": constructor. filename = " << filename << endl;
69 #endif // DEBUG
70 }
71
72 void Plant::real_run(void) throw() {
73 #ifdef DEBUG
74         cerr << __FILE__ << "(" << __LINE__ << ")"
75                 << ": real_run." << endl;
76 #endif // DEBUG
77         unsigned wait;
78         while (!stop()) {
79                 if (paused) { // Si está pausada, espera un tiempo sin simular.
80                         Glib::usleep(DEFAULT_WAIT_TIME);
81                 } else { // Si está andando, simula y manda estado.
82                         simulator_mutex.lock();
83                         simulator.simulate();
84                         string plantstatus = simulator.get_state_as_xml();
85                         simulator_mutex.unlock();
86                         transmissions_mutex.lock();
87                         for (TransmitterList::iterator i = transmissions.begin();
88                                         i != transmissions.end(); i++) {
89                                 (*i)->send(plantstatus);
90                         }
91                         transmissions_mutex.unlock();
92                         wait_time_mutex.lock();
93                         wait = wait_time;
94                         wait_time_mutex.unlock();
95                         Glib::usleep(wait);
96                 }
97         }
98 }
99
100 bool Plant::transmission_start(string& host, Connection::Port& port) {
101 #ifdef DEBUG
102                 cerr << __FILE__ << "(" << __LINE__ << ")"
103                         << ": transmission_start(host = " << host <<
104                         ", port = " << port << ")." << endl;
105 #endif // DEBUG
106         Glib::Mutex::Lock lock(transmissions_mutex);
107         for (TransmitterList::iterator i = transmissions.begin();
108                         i != transmissions.end(); i++) {
109                 if (((*i)->get_host() == host) && ((*i)->get_port() == port)) {
110 #ifdef DEBUG
111                         cerr << __FILE__ << "(" << __LINE__ << ")"
112                                 << ": transmission_start ERROR: ya existe."
113                                 << endl;
114 #endif // DEBUG
115                         return false;
116                 }
117         }
118         Transmitter* trans;
119         try {
120                 trans = new Transmitter(host, port);
121         } catch (const sockerr& e) {
122 #ifdef DEBUG
123                 cerr << __FILE__ << "(" << __LINE__ << ")"
124                         << ": transmission_start ERROR (" << e.serrno()
125                         << "): " << e.errstr() << endl;
126 #endif // DEBUG
127                 return false;
128         }
129         transmissions.push_back(trans);
130         trans->signal_finished().connect(SigC::bind(
131                                 SigC::slot_class(*this, &Plant::on_transmission_finished),
132                                 trans));
133         trans->run();
134         host = trans->get_host();
135         port = trans->get_port();
136         return true;
137 }
138
139 bool Plant::transmission_stop(const string& host,
140                 const Connection::Port& port) {
141 #ifdef DEBUG
142         cerr << __FILE__ << "(" << __LINE__ << ")"
143                 << ": transmission_stop(host = " << host <<
144                 ", port = " << port << ")." << endl;
145 #endif // DEBUG
146         Glib::Mutex::Lock lock(transmissions_mutex);
147         for (TransmitterList::iterator i = transmissions.begin();
148                         i != transmissions.end(); i++) {
149                 if (((*i)->get_host() == host) && ((*i)->get_port() == port)) {
150                         (*i)->finish();
151                         return true;
152                 }
153         }
154         return false; // No la encontró.
155 }
156
157 void Plant::on_transmission_finished(Transmitter* transmission) {
158 #ifdef DEBUG
159         cerr << __FILE__ << "(" << __LINE__ << ")"
160                 <<  ": on_transmission_finished(transmission = "
161                 << transmission << ")" << endl;
162 #endif // DEBUG
163         Glib::Mutex::Lock lock(transmissions_mutex);
164         transmissions.remove(transmission);
165 #ifdef DEBUG
166         cerr << __FILE__ << "(" << __LINE__ << ")"
167                 <<  ": lista de conexiones" << endl;
168         for (TransmitterList::const_iterator i = transmissions.begin();
169                         i != transmissions.end(); i++) {
170                 cerr << "\t " << *i << endl;
171         }
172 #endif // DEBUG
173 }
174
175 bool Plant::set_open(const std::string& element, bool open) {
176 #ifdef DEBUG
177                 cerr << __FILE__ << "(" << __LINE__ << ")"
178                         << ": set_open(element = " << element <<
179                         ", open = " << open << ")." << endl;
180 #endif // DEBUG
181         Glib::Mutex::Lock lock(simulator_mutex);
182         return simulator.set_open(element, open);
183 }
184
185 const string Plant::get_xml(void) const {
186 #ifdef DEBUG
187                 cerr << __FILE__ << "(" << __LINE__ << ")"
188                         << ": get_xml()." << endl;
189 #endif // DEBUG
190         ostringstream oss;
191         ifstream ifs(filename.c_str());
192         // FIXME Saco la línea de definición de XML (<?xml ?>), ver si esta hecho muy
193         // feo.
194         ifs.ignore(50, '\n'); // Ignora 50 caracteres o hasta un enter.
195         ifs >> oss.rdbuf();
196         return oss.str();
197 }
198
199 void Plant::set_frequency(unsigned hz) {
200         Glib::Mutex::Lock lock(wait_time_mutex);
201         wait_time = hz ? (1000000u/hz) : DEFAULT_WAIT_TIME;
202 }
203
204 void Plant::set_paused(bool paused_) {
205         Glib::Mutex::Lock lock(paused_mutex);
206         paused = paused_;
207 }
208
209 } // namespace Server
210
211 } // namespace PlaQui
212