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