]> git.llucax.com Git - z.facultad/75.42/plaqui.git/blob - Server/src/plant.cpp
970fbabbb2fd2be308659ff40e4bf177584c0882
[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 #ifdef DEBUG
66         cerr << __FILE__ << "(" << __LINE__ << ")"
67                 << ": constructor. filename = " << filename << endl;
68 #endif // DEBUG
69         // TODO plant
70 /*      simulator.add_pump("bomba1");
71         simulator.add_conduct("c");
72         simulator.add_conduct("c1");
73         simulator.add_drainage("d");
74         simulator.add_tank("tanque");
75         
76         simulator.connect("bomba1", "c", Model::IConector::OUT);
77         simulator.connect("c", "tanque", Model::IConector::OUT);
78         simulator.connect("tanque", "c1", Model::IConector::OUT);
79         simulator.connect("c1", "d", Model::IConector::OUT);
80 */      
81 }
82
83 void Plant::real_run(void) throw() {
84 #ifdef DEBUG
85         cerr << __FILE__ << "(" << __LINE__ << ")"
86                 << ": real_run." << endl;
87 #endif // DEBUG
88         while (!stop()) {
89                 simulator_mutex.lock();
90                 simulator.simulate();
91                 string plantstatus = simulator.get_state_as_xml();
92                 simulator_mutex.unlock();
93                 transmissions_mutex.lock();
94                 for (TransmitterList::iterator i = transmissions.begin();
95                                 i != transmissions.end(); i++) {
96                         (*i)->send(plantstatus);
97                 }
98                 transmissions_mutex.unlock();
99                 Glib::usleep(100000);
100         }
101 }
102
103 bool Plant::transmission_start(string& host, Connection::Port& port) {
104 #ifdef DEBUG
105                 cerr << __FILE__ << "(" << __LINE__ << ")"
106                         << ": transmission_start(host = " << host <<
107                         ", port = " << port << ")." << endl;
108 #endif // DEBUG
109         Glib::Mutex::Lock lock(transmissions_mutex);
110         for (TransmitterList::iterator i = transmissions.begin();
111                         i != transmissions.end(); i++) {
112                 if (((*i)->get_host() == host) && ((*i)->get_port() == port)) {
113 #ifdef DEBUG
114                         cerr << __FILE__ << "(" << __LINE__ << ")"
115                                 << ": transmission_start ERROR: ya existe."
116                                 << endl;
117 #endif // DEBUG
118                         return false;
119                 }
120         }
121         Transmitter* trans;
122         try {
123                 trans = new Transmitter(host, port);
124         } catch (const sockerr& e) { // TODO - Hace mas selectivo el catch?
125 #ifdef DEBUG
126                 cerr << __FILE__ << "(" << __LINE__ << ")"
127                         << ": transmission_start ERROR (" << e.serrno()
128                         << "): " << e.errstr() << endl;
129 #endif // DEBUG
130                 //delete trans;
131                 return false;
132 //      } catch (...) { // TODO - Hace mas selectivo el catch?
133 //#ifdef DEBUG
134 //              cerr << __FILE__ << "(" << __LINE__ << ")"
135 //                      << ": transmission_start ERROR: desconocido."
136 //                      << endl;
137 //#endif // DEBUG
138 //              //delete trans;
139 //              return false;
140         }
141         transmissions.push_back(trans);
142         trans->signal_finished().connect(SigC::bind<Transmitter*>(
143                                 SigC::slot_class(*this, &Plant::on_transmission_finished),
144                                 trans));
145         trans->run();
146         host = trans->get_host();
147         port = trans->get_port();
148         return true;
149 }
150
151 bool Plant::transmission_stop(const string& host,
152                 const Connection::Port& port) {
153 #ifdef DEBUG
154         cerr << __FILE__ << "(" << __LINE__ << ")"
155                 << ": transmission_stop(host = " << host <<
156                 ", port = " << port << ")." << endl;
157 #endif // DEBUG
158         Glib::Mutex::Lock lock(transmissions_mutex);
159         for (TransmitterList::iterator i = transmissions.begin();
160                         i != transmissions.end(); i++) {
161                 if (((*i)->get_host() == host) && ((*i)->get_port() == port)) {
162                         (*i)->finish();
163                         return true;
164                 }
165         }
166         return false; // No la encontró.
167 }
168
169 void Plant::on_transmission_finished(Transmitter* transmission) {
170 #ifdef DEBUG
171         cerr << __FILE__ << "(" << __LINE__ << ")"
172                 <<  ": on_transmission_finished(transmission = "
173                 << transmission << ")" << endl;
174 #endif // DEBUG
175         Glib::Mutex::Lock lock(transmissions_mutex);
176         transmissions.remove(transmission);
177 #ifdef DEBUG
178         cerr << __FILE__ << "(" << __LINE__ << ")"
179                 <<  ": lista de conexiones" << endl;
180         for (TransmitterList::const_iterator i = transmissions.begin();
181                         i != transmissions.end(); i++) {
182                 cerr << "\t " << *i << endl;
183         }
184 #endif // DEBUG
185 }
186
187 bool Plant::set_open(const std::string& element, bool open) {
188 #ifdef DEBUG
189                 cerr << __FILE__ << "(" << __LINE__ << ")"
190                         << ": set_open(element = " << element <<
191                         ", open = " << open << ")." << endl;
192 #endif // DEBUG
193         Glib::Mutex::Lock lock(simulator_mutex);
194         return simulator.set_open(element, open);
195 }
196
197 const string Plant::get_xml(void) const {
198 #ifdef DEBUG
199                 cerr << __FILE__ << "(" << __LINE__ << ")"
200                         << ": get_xml()." << endl;
201 #endif // DEBUG
202         ostringstream oss;
203         ifstream ifs(filename.c_str());
204         ifs >> oss.rdbuf();
205         return oss.str();
206 }
207
208 /*
209 bool Plant::transmission_exists(const string& host,
210                 const Connection::Port& port) {
211         Glib::Mutex::Lock lock(transmissions_mutex);
212         for (TransmitterList::const_iterator i = transmissions.begin();
213                         i != transmissions.end(); i++) {
214                 if (((*i)->get_host() == host) && ((*i)->get_oprt() == port)) {
215                         return true;
216                 }
217         }
218         return false; // No la encontró.
219 }
220 */
221
222 //const std::string& Plant::get_filename(void) const {
223 //      return filename;
224 //}
225
226 /// \todo FIXME esto deberia estar protegido por un mutex.
227 //Plant::SignalUpdated& Plant::signal_updated(void) {
228 //      return updated;
229 //}
230
231 } // namespace Server
232
233 } // namespace PlaQui
234