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