]> git.llucax.com Git - z.facultad/75.42/plaqui.git/blob - Model/src/simulator.cpp
Se arregla bug en la union que hacia que el flujo inicial este en 0, y eso condicion...
[z.facultad/75.42/plaqui.git] / Model / src / simulator.cpp
1
2 #include "simulator.h"
3
4 using namespace PlaQui::Model;
5
6 Simulator::Simulator(const std::string &filename)
7 {
8         frame = 0;
9         /* Parseo de ejemplo de un XML desde archivo */
10         xmlDocPtr document;
11         document = xmlParseFile(filename.c_str());
12         if (document == NULL) {
13                 return;
14         }
15
16         /* bien, el archivo se parseo bien! */
17         xmlNodePtr nodo, items;
18         nodo = document->children;
19
20         if (strcmp((char *)nodo->name, "planta") == 0) {
21                 items = nodo->children;
22                 while (items != NULL) {
23                         if (items->type == XML_ELEMENT_NODE) {
24                                 if (xmlStrcmp(items->name, BAD_CAST"bomba")==0) {
25                                         loadBomba(items);
26                                 } else if ((xmlStrcmp(items->name, BAD_CAST"tubo")==0)||(xmlStrcmp(items->name, BAD_CAST"codo")==0)) {
27                                         loadConduct(items);
28                                 } else if (xmlStrcmp(items->name, BAD_CAST"exclusa")==0) {
29                                         loadExclusa(items);
30                                 } else if (xmlStrcmp(items->name, BAD_CAST"tanque")==0) {
31                                         loadTank(items);
32                                 } else if (xmlStrcmp(items->name, BAD_CAST"empalme")==0) {
33                                         loadUnion(items);
34                                 } else if (xmlStrcmp(items->name, BAD_CAST"drenaje")==0) {
35                                         loadDrain(items);
36                                 }
37                         }
38                         items = items->next;
39                 }
40                 // Bien, la planta esta cargada, conectemos todo!!
41                 do_connections(nodo->children);
42         }
43 }
44
45 Simulator::~Simulator()
46 {
47         // FIXME REMOVER TODOOOOOO
48 }
49
50 void Simulator::add_pump(const std::string &name, float max_flow, RGB color)
51 {
52         Pump *p = new Pump(name);
53         // FIXME no va!!
54         p->set_max_flow(max_flow);
55         p->set_color(color);
56         pump_lst.push_back(p);
57         items.push_back(p);
58 }
59
60 void Simulator::add_union(const std::string &name, float max_flow)
61 {
62         Union *u = new Union(name);
63         // FIXME no va!!
64         u->set_max_flow(max_flow);
65         union_lst.push_back(u);
66         items.push_back(u);
67 }
68
69 void Simulator::add_splitter(const std::string &name, float max_flow)
70 {
71         Splitter *p = new Splitter(name);
72         p->set_max_flow(max_flow);
73         split_lst.push_back(p);
74         items.push_back(p);
75 }
76
77 void Simulator::add_conduct(const std::string &name, float flujo)
78 {
79         Conduct *p = new Conduct(name);
80         // FIXME no va!!
81         std::cout << flujo << std::endl;
82         p->set_max_flow(flujo);
83         conduct_lst.push_back(p);
84         items.push_back(p);
85 }
86
87 void Simulator::add_exclusa(const std::string &name, bool open)
88 {
89         Exclusa *p = new Exclusa(name);
90         if (!open)
91                 p->close();
92         exclusa_lst.push_back(p);
93         items.push_back(p);
94 }
95
96 void Simulator::add_tank(const std::string &name, float capacity, float initial, RGB color)
97 {
98         Tank *p = new Tank(name);
99         p->set_capacity(capacity);
100         p->set_max_flow(initial);
101         p->set_litros(initial);
102         p->set_color(color);
103         tank_lst.push_back(p);
104         items.push_back(p);
105 }
106
107 void Simulator::add_drainage(const std::string &name)
108 {
109         Drainage *p = new Drainage(name);
110         drainage_lst.push_back(p);
111         items.push_back(p);
112 }
113
114 bool Simulator::connect(const std::string &name1, const std::string &name2, int flag)
115 {
116         IConector *o1, *o2;
117         o1 = find(name1);
118         o2 = find(name2);
119
120         if ((o1 == NULL) || (o2 == NULL)) {
121                 // NO SE PUDO CONECTAR!, FALTAN ITEMS!!
122                 return false;
123         }
124
125         bool b;
126         if (flag == IConector::OUT) {
127                 b = o1->connect(o2, IConector::OUT);
128                 b = b && o2->connect(o1, IConector::IN);
129         } else {
130                 b = o1->connect(o2, IConector::IN);
131                 b = b && o2->connect(o1, IConector::OUT);
132         }
133         
134         return b;
135 }
136
137 void Simulator::simulate()
138 {
139         // Actualizo
140         std::list<Pump *>::iterator i1;
141         for(i1=pump_lst.begin(); i1!=pump_lst.end(); i1++)
142                 (*i1)->update();
143
144         // Simulo!
145         std::list<PlantItem *>::iterator i2;
146         for(i2=items.begin(); i2!=items.end(); i2++)
147                 (*i2)->simulate();
148
149         frame++;
150 }
151
152 IConector *Simulator::find(const std::string &name)
153 {
154         // Busco el item, aca no me importa de que tipo es!
155         std::list<PlantItem *>::iterator i;
156         for(i=items.begin(); i!=items.end(); i++)
157                 if ((*i)->get_name() == name)
158                         return *i;
159         return NULL;
160 }
161
162 bool Simulator::set_open(const std::string &name, bool open)
163 {
164         // Busco el elemento, usando RTTI :-(
165         IConector *tmp = find(name);
166         Pump *p;
167         Exclusa *e;
168         if ((p = dynamic_cast<Pump*>(tmp))) {
169                 if (open) {
170                         p->activate();
171                 } else {
172                         p->deactivate();
173                 }
174         } else if ((e = dynamic_cast<Exclusa*>(tmp))) {
175                 if (open) {
176                         e->open();
177                 } else {
178                         e->close();
179                 }
180         } else {
181                 return false;
182         }
183 }
184
185 void Simulator::loadBomba(xmlNodePtr nodo)
186 {
187         std::string name = (char *)xmlGetProp(nodo, BAD_CAST"nombre");
188         int orientacion=0, x, y;
189         RGB color;
190         float flujo;
191
192         nodo = nodo->children;
193         while (nodo != NULL) {
194                 if (nodo->type == XML_ELEMENT_NODE) {
195                         if (xmlStrcmp(nodo->name, BAD_CAST"orientacion") == 0) {
196                                 orientacion = atoi( (char *)XML_GET_CONTENT(nodo->children) );
197                         } else if (xmlStrcmp(nodo->name, BAD_CAST"x") == 0) {
198                                 x = atoi( (char *)XML_GET_CONTENT(nodo->children) );
199                         } else if (xmlStrcmp(nodo->name, BAD_CAST"y") == 0) {
200                                 y = atoi( (char *)XML_GET_CONTENT(nodo->children) );
201                         } else if (xmlStrcmp(nodo->name, BAD_CAST"entrega") == 0) {
202                                 flujo = atof( (char *)XML_GET_CONTENT(nodo->children) );
203                         } else if (xmlStrcmp(nodo->name, BAD_CAST"color") == 0) {
204                                 // FIXME !
205                                 color = RGB();
206                         }
207                 }
208                 nodo = nodo->next;
209         }
210
211         add_pump(name, flujo, color);
212 }
213
214 void Simulator::loadConduct(xmlNodePtr nodo)
215 {
216         std::string name = (char *)xmlGetProp(nodo, BAD_CAST"nombre");
217         int orientacion=0, x, y;
218         float flujo;
219
220         nodo = nodo->children;
221         while (nodo != NULL) {
222                 if (nodo->type == XML_ELEMENT_NODE) {
223                         if (xmlStrcmp(nodo->name, BAD_CAST"orientacion") == 0) {
224                                 orientacion = atoi( (char *)XML_GET_CONTENT(nodo->children) );
225                         } else if (xmlStrcmp(nodo->name, BAD_CAST"x") == 0) {
226                                 x = atoi( (char *)XML_GET_CONTENT(nodo->children) );
227                         } else if (xmlStrcmp(nodo->name, BAD_CAST"y") == 0) {
228                                 y = atoi( (char *)XML_GET_CONTENT(nodo->children) );
229                         } else if (xmlStrcmp(nodo->name, BAD_CAST"caudal") == 0) {
230                                 flujo = atof( (char *)XML_GET_CONTENT(nodo->children) );
231                         }
232                         
233
234                 }
235                 nodo = nodo->next;
236         }
237
238         // listo, ya recolecte todos los datos, ahora creo el objeto!
239         add_conduct(name, flujo);
240 }
241
242 void Simulator::loadExclusa(xmlNodePtr nodo)
243 {
244         std::string name = (char *)xmlGetProp(nodo, BAD_CAST"nombre");
245         int orientacion=0, x, y;
246         std::string open;
247
248         nodo = nodo->children;
249         while (nodo != NULL) {
250                 if (nodo->type == XML_ELEMENT_NODE) {
251                         if (xmlStrcmp(nodo->name, BAD_CAST"orientacion") == 0) {
252                                 orientacion = atoi( (char *)XML_GET_CONTENT(nodo->children) );
253                         } else if (xmlStrcmp(nodo->name, BAD_CAST"x") == 0) {
254                                 x = atoi( (char *)XML_GET_CONTENT(nodo->children) );
255                         } else if (xmlStrcmp(nodo->name, BAD_CAST"y") == 0) {
256                                 y = atoi( (char *)XML_GET_CONTENT(nodo->children) );
257                         } else if (xmlStrcmp(nodo->name, BAD_CAST"estado") == 0) {
258                                 open = (char *)XML_GET_CONTENT(nodo->children);
259                         }
260                 }
261                 nodo = nodo->next;
262         }
263
264         // listo, ya recolecte todos los datos, ahora creo el objeto!
265         add_exclusa(name, open == "1");
266 }
267
268 void Simulator::loadTank(xmlNodePtr nodo)
269 {
270         std::string name = (char *)xmlGetProp(nodo, BAD_CAST"nombre");
271         int orientacion=0, x, y;
272         float capacidad, inicial;
273         RGB color; // TODO
274
275         nodo = nodo->children;
276         while (nodo != NULL) {
277                 if (nodo->type == XML_ELEMENT_NODE) {
278                         if (xmlStrcmp(nodo->name, BAD_CAST"orientacion") == 0) {
279                                 orientacion = atoi( (char *)XML_GET_CONTENT(nodo->children) );
280                         } else if (xmlStrcmp(nodo->name, BAD_CAST"x") == 0) {
281                                 x = atoi( (char *)XML_GET_CONTENT(nodo->children) );
282                         } else if (xmlStrcmp(nodo->name, BAD_CAST"y") == 0) {
283                                 y = atoi( (char *)XML_GET_CONTENT(nodo->children) );
284                         } else if (xmlStrcmp(nodo->name, BAD_CAST"capacidad") == 0) {
285                                 capacidad = atoi( (char *)XML_GET_CONTENT(nodo->children) );
286                         } else if (xmlStrcmp(nodo->name, BAD_CAST"inicial") == 0) {
287                                 inicial = atof( (char *)XML_GET_CONTENT(nodo->children) );
288                         }
289                 }
290                 nodo = nodo->next;
291         }
292
293         // listo, ya recolecte todos los datos, ahora creo el objeto!
294         add_tank(name, capacidad, inicial, color);
295 }
296
297 void Simulator::loadUnion(xmlNodePtr nodo)
298 {
299         std::string name = (char *)xmlGetProp(nodo, BAD_CAST"nombre");
300         int orientacion=0, x, y;
301         float flow;
302         std::string type;
303
304         nodo = nodo->children;
305         while (nodo != NULL) {
306                 if (nodo->type == XML_ELEMENT_NODE) {
307                         if (xmlStrcmp(nodo->name, BAD_CAST"orientacion") == 0) {
308                                 orientacion = atoi( (char *)XML_GET_CONTENT(nodo->children) );
309                         } else if (xmlStrcmp(nodo->name, BAD_CAST"x") == 0) {
310                                 x = atoi( (char *)XML_GET_CONTENT(nodo->children) );
311                         } else if (xmlStrcmp(nodo->name, BAD_CAST"y") == 0) {
312                                 y = atoi( (char *)XML_GET_CONTENT(nodo->children) );
313                         } else if (xmlStrcmp(nodo->name, BAD_CAST"caudal") == 0) {
314                                 flow = atof( (char *)XML_GET_CONTENT(nodo->children) );
315                         } else if (xmlStrcmp(nodo->name, BAD_CAST"tipo") == 0) {
316                                 type = (char *)XML_GET_CONTENT(nodo->children);
317                         }
318                 }
319                 nodo = nodo->next;
320         }
321
322         // listo, ya recolecte todos los datos, ahora creo el objeto!
323         if (type == "union")
324                 add_union(name, flow);
325         else
326                 add_splitter(name, flow);
327 }
328
329 void Simulator::loadDrain(xmlNodePtr nodo)
330 {
331         std::string name = (char *)xmlGetProp(nodo, BAD_CAST"nombre");
332
333         add_drainage(name);
334 }
335
336 void Simulator::do_connections(xmlNodePtr nodo)
337 {
338         // Intengo conectar los elementos :)
339         IConector *current_item, *to_connect;
340         xmlNodePtr props; // propiedades del item actual
341         xmlNodePtr conector1, conector2, conector3;
342
343         while (nodo != NULL) {
344                 if (nodo->type != XML_ELEMENT_NODE) {
345                         nodo = nodo->next;
346                         continue;
347                 }
348                 // obtengo el items actual por su nombre
349                 current_item = find((char *)xmlGetProp(nodo, BAD_CAST"nombre"));
350                 props = nodo->children;
351                 conector3 = conector2 = conector1 = NULL;
352                 while (props != NULL) {
353                         if (nodo->type == XML_ELEMENT_NODE) {
354                                 if (xmlStrcmp(props->name, BAD_CAST"conector") == 0) {
355                                         xmlNodePtr temp = props->children;
356                                         while ((temp != NULL) && (conector1 == NULL))
357                                                 if (temp->type == XML_ELEMENT_NODE) {
358                                                         conector1 = temp;
359                                                         temp = temp->next;
360                                                         break;
361                                                 } else {
362                                                         temp = temp->next;
363                                                 }
364                                         while ((temp != NULL) && (conector2 == NULL))
365                                                 if (temp->type == XML_ELEMENT_NODE) {
366                                                         conector2 = temp;
367                                                         temp = temp->next;
368                                                         break;
369                                                 } else {
370                                                         temp = temp->next;
371                                                 }
372                                         while ((temp != NULL) && (conector3 == NULL))
373                                                 if (temp->type == XML_ELEMENT_NODE) {
374                                                         conector3 = temp;
375                                                         temp = temp->next;
376                                                         break;
377                                                 } else {
378                                                         temp = temp->next;
379                                                 }
380                                 }
381                         }
382                         props = props->next;
383                 }
384                 // Bien, conector1 y 2 deberian estar apuntando a <entrada> y/o <salida>
385                 if (conector1 != NULL) {
386                         // si, aca hay un conector!, veamos cual es
387                         if (xmlStrcmp(conector1->name, BAD_CAST"entrada") == 0) {
388                                 // bien, es a la entrada!, obtengo el item al cual lo tengo que conectar
389                                 to_connect = find((char *)XML_GET_CONTENT(conector1->children));
390                                 // y lo conecto
391                                 current_item->connect(to_connect, IConector::IN);
392                         } else if (xmlStrcmp(conector1->name, BAD_CAST"salida") == 0) {
393                                 // Era a salida, es casi lo mismo que arriba 
394                                 to_connect = find((char *)XML_GET_CONTENT(conector1->children));
395                                 current_item->connect(to_connect, IConector::OUT);
396                         }
397                 }
398                 if (conector2 != NULL) {
399                         // si, aca hay un conector!, veamos cual es
400                         if (xmlStrcmp(conector2->name, BAD_CAST"entrada") == 0) {
401                                 // bien, es a la entrada!, obtengo el item al cual lo tengo que conectar
402                                 to_connect = find((char *)XML_GET_CONTENT(conector2->children));
403                                 // y lo conecto
404                                 current_item->connect(to_connect, IConector::IN);
405                         } else if (xmlStrcmp(conector2->name, BAD_CAST"salida") == 0) {
406                                 // Era a salida, es casi lo mismo que arriba 
407                                 to_connect = find((char *)XML_GET_CONTENT(conector2->children));
408                                 current_item->connect(to_connect, IConector::OUT);
409                         }
410                 }
411                 if (conector3 != NULL) {
412                         // si, aca hay un conector!, veamos cual es
413                         if (xmlStrcmp(conector3->name, BAD_CAST"entrada") == 0) {
414                                 // bien, es a la entrada!, obtengo el item al cual lo tengo que conectar
415                                 to_connect = find((char *)XML_GET_CONTENT(conector3->children));
416                                 // y lo conecto
417                                 current_item->connect(to_connect, IConector::IN);
418                         } else if (xmlStrcmp(conector3->name, BAD_CAST"salida") == 0) {
419                                 // Era a salida, es casi lo mismo que arriba 
420                                 to_connect = find((char *)XML_GET_CONTENT(conector3->children));
421                                 current_item->connect(to_connect, IConector::OUT);
422                         }
423                 }
424                 nodo = nodo->next;
425         }
426         // Fin de las conexiones
427 }
428
429 std::string Simulator::get_state_as_xml()
430 {
431         std::stringstream out;
432
433         // XML Header
434         out << "<?xml version=\"1.0\" ?>" << std::endl;
435
436         out << "<plantstatus frame=\"" << frame << "\">" << std::endl;
437         
438         std::list<PlantItem *>::iterator i2;
439         for(i2=items.begin(); i2!=items.end(); i2++)
440                 (*i2)->get_state_as_xml(out);
441
442         out << "</plantstatus>";
443         return out.str();;
444 }
445