]> git.llucax.com Git - z.facultad/75.42/plaqui.git/blob - Model/src/simulator.cpp
2fe6f6ecb586672da5cb106ce0eecb7b7e634d6e
[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                                 color = loadRGB(nodo->children);
205                         }
206                 }
207                 nodo = nodo->next;
208         }
209
210         add_pump(name, flujo, color);
211 }
212
213 void Simulator::loadConduct(xmlNodePtr nodo)
214 {
215         std::string name = (char *)xmlGetProp(nodo, BAD_CAST"nombre");
216         int orientacion=0, x, y;
217         float flujo;
218
219         nodo = nodo->children;
220         while (nodo != NULL) {
221                 if (nodo->type == XML_ELEMENT_NODE) {
222                         if (xmlStrcmp(nodo->name, BAD_CAST"orientacion") == 0) {
223                                 orientacion = atoi( (char *)XML_GET_CONTENT(nodo->children) );
224                         } else if (xmlStrcmp(nodo->name, BAD_CAST"x") == 0) {
225                                 x = atoi( (char *)XML_GET_CONTENT(nodo->children) );
226                         } else if (xmlStrcmp(nodo->name, BAD_CAST"y") == 0) {
227                                 y = atoi( (char *)XML_GET_CONTENT(nodo->children) );
228                         } else if (xmlStrcmp(nodo->name, BAD_CAST"caudal") == 0) {
229                                 flujo = atof( (char *)XML_GET_CONTENT(nodo->children) );
230                         }
231                         
232
233                 }
234                 nodo = nodo->next;
235         }
236
237         // listo, ya recolecte todos los datos, ahora creo el objeto!
238         add_conduct(name, flujo);
239 }
240
241 void Simulator::loadExclusa(xmlNodePtr nodo)
242 {
243         std::string name = (char *)xmlGetProp(nodo, BAD_CAST"nombre");
244         int orientacion=0, x, y;
245         std::string open;
246
247         nodo = nodo->children;
248         while (nodo != NULL) {
249                 if (nodo->type == XML_ELEMENT_NODE) {
250                         if (xmlStrcmp(nodo->name, BAD_CAST"orientacion") == 0) {
251                                 orientacion = atoi( (char *)XML_GET_CONTENT(nodo->children) );
252                         } else if (xmlStrcmp(nodo->name, BAD_CAST"x") == 0) {
253                                 x = atoi( (char *)XML_GET_CONTENT(nodo->children) );
254                         } else if (xmlStrcmp(nodo->name, BAD_CAST"y") == 0) {
255                                 y = atoi( (char *)XML_GET_CONTENT(nodo->children) );
256                         } else if (xmlStrcmp(nodo->name, BAD_CAST"estado") == 0) {
257                                 open = (char *)XML_GET_CONTENT(nodo->children);
258                         }
259                 }
260                 nodo = nodo->next;
261         }
262
263         // listo, ya recolecte todos los datos, ahora creo el objeto!
264         add_exclusa(name, open == "1");
265 }
266
267 void Simulator::loadTank(xmlNodePtr nodo)
268 {
269         std::string name = (char *)xmlGetProp(nodo, BAD_CAST"nombre");
270         int orientacion=0, x, y;
271         float capacidad, inicial;
272         RGB color;
273
274         nodo = nodo->children;
275         while (nodo != NULL) {
276                 if (nodo->type == XML_ELEMENT_NODE) {
277                         if (xmlStrcmp(nodo->name, BAD_CAST"orientacion") == 0) {
278                                 orientacion = atoi( (char *)XML_GET_CONTENT(nodo->children) );
279                         } else if (xmlStrcmp(nodo->name, BAD_CAST"x") == 0) {
280                                 x = atoi( (char *)XML_GET_CONTENT(nodo->children) );
281                         } else if (xmlStrcmp(nodo->name, BAD_CAST"y") == 0) {
282                                 y = atoi( (char *)XML_GET_CONTENT(nodo->children) );
283                         } else if (xmlStrcmp(nodo->name, BAD_CAST"capacidad") == 0) {
284                                 capacidad = atoi( (char *)XML_GET_CONTENT(nodo->children) );
285                         } else if (xmlStrcmp(nodo->name, BAD_CAST"inicial") == 0) {
286                                 inicial = atof( (char *)XML_GET_CONTENT(nodo->children) );
287                         } else if (xmlStrcmp(nodo->name, BAD_CAST"") == 0) {
288                                 color = loadRGB(nodo->children);
289                         }
290                 }
291                 nodo = nodo->next;
292         }
293
294         // listo, ya recolecte todos los datos, ahora creo el objeto!
295         add_tank(name, capacidad, inicial, color);
296 }
297
298 void Simulator::loadUnion(xmlNodePtr nodo)
299 {
300         std::string name = (char *)xmlGetProp(nodo, BAD_CAST"nombre");
301         int orientacion=0, x, y;
302         float flow;
303         std::string type;
304
305         nodo = nodo->children;
306         while (nodo != NULL) {
307                 if (nodo->type == XML_ELEMENT_NODE) {
308                         if (xmlStrcmp(nodo->name, BAD_CAST"orientacion") == 0) {
309                                 orientacion = atoi( (char *)XML_GET_CONTENT(nodo->children) );
310                         } else if (xmlStrcmp(nodo->name, BAD_CAST"x") == 0) {
311                                 x = atoi( (char *)XML_GET_CONTENT(nodo->children) );
312                         } else if (xmlStrcmp(nodo->name, BAD_CAST"y") == 0) {
313                                 y = atoi( (char *)XML_GET_CONTENT(nodo->children) );
314                         } else if (xmlStrcmp(nodo->name, BAD_CAST"caudal") == 0) {
315                                 flow = atof( (char *)XML_GET_CONTENT(nodo->children) );
316                         } else if (xmlStrcmp(nodo->name, BAD_CAST"tipo") == 0) {
317                                 type = (char *)XML_GET_CONTENT(nodo->children);
318                         }
319                 }
320                 nodo = nodo->next;
321         }
322
323         // listo, ya recolecte todos los datos, ahora creo el objeto!
324         if (type == "union")
325                 add_union(name, flow);
326         else
327                 add_splitter(name, flow);
328 }
329
330 void Simulator::loadDrain(xmlNodePtr nodo)
331 {
332         std::string name = (char *)xmlGetProp(nodo, BAD_CAST"nombre");
333
334         add_drainage(name);
335 }
336
337 void Simulator::do_connections(xmlNodePtr nodo)
338 {
339         // Intengo conectar los elementos :)
340         IConector *current_item, *to_connect;
341         xmlNodePtr props; // propiedades del item actual
342         xmlNodePtr conector1, conector2, conector3;
343
344         while (nodo != NULL) {
345                 if (nodo->type != XML_ELEMENT_NODE) {
346                         nodo = nodo->next;
347                         continue;
348                 }
349                 // obtengo el items actual por su nombre
350                 current_item = find((char *)xmlGetProp(nodo, BAD_CAST"nombre"));
351                 props = nodo->children;
352                 conector3 = conector2 = conector1 = NULL;
353                 while (props != NULL) {
354                         if (nodo->type == XML_ELEMENT_NODE) {
355                                 if (xmlStrcmp(props->name, BAD_CAST"conector") == 0) {
356                                         xmlNodePtr temp = props->children;
357                                         while ((temp != NULL) && (conector1 == NULL))
358                                                 if (temp->type == XML_ELEMENT_NODE) {
359                                                         conector1 = temp;
360                                                         temp = temp->next;
361                                                         break;
362                                                 } else {
363                                                         temp = temp->next;
364                                                 }
365                                         while ((temp != NULL) && (conector2 == NULL))
366                                                 if (temp->type == XML_ELEMENT_NODE) {
367                                                         conector2 = temp;
368                                                         temp = temp->next;
369                                                         break;
370                                                 } else {
371                                                         temp = temp->next;
372                                                 }
373                                         while ((temp != NULL) && (conector3 == NULL))
374                                                 if (temp->type == XML_ELEMENT_NODE) {
375                                                         conector3 = temp;
376                                                         temp = temp->next;
377                                                         break;
378                                                 } else {
379                                                         temp = temp->next;
380                                                 }
381                                 }
382                         }
383                         props = props->next;
384                 }
385                 // Bien, conector1 y 2 deberian estar apuntando a <entrada> y/o <salida>
386                 if (conector1 != NULL) {
387                         // si, aca hay un conector!, veamos cual es
388                         if (xmlStrcmp(conector1->name, BAD_CAST"entrada") == 0) {
389                                 // bien, es a la entrada!, obtengo el item al cual lo tengo que conectar
390                                 to_connect = find((char *)XML_GET_CONTENT(conector1->children));
391                                 // y lo conecto
392                                 current_item->connect(to_connect, IConector::IN);
393                         } else if (xmlStrcmp(conector1->name, BAD_CAST"salida") == 0) {
394                                 // Era a salida, es casi lo mismo que arriba 
395                                 to_connect = find((char *)XML_GET_CONTENT(conector1->children));
396                                 current_item->connect(to_connect, IConector::OUT);
397                         }
398                 }
399                 if (conector2 != NULL) {
400                         // si, aca hay un conector!, veamos cual es
401                         if (xmlStrcmp(conector2->name, BAD_CAST"entrada") == 0) {
402                                 // bien, es a la entrada!, obtengo el item al cual lo tengo que conectar
403                                 to_connect = find((char *)XML_GET_CONTENT(conector2->children));
404                                 // y lo conecto
405                                 current_item->connect(to_connect, IConector::IN);
406                         } else if (xmlStrcmp(conector2->name, BAD_CAST"salida") == 0) {
407                                 // Era a salida, es casi lo mismo que arriba 
408                                 to_connect = find((char *)XML_GET_CONTENT(conector2->children));
409                                 current_item->connect(to_connect, IConector::OUT);
410                         }
411                 }
412                 if (conector3 != NULL) {
413                         // si, aca hay un conector!, veamos cual es
414                         if (xmlStrcmp(conector3->name, BAD_CAST"entrada") == 0) {
415                                 // bien, es a la entrada!, obtengo el item al cual lo tengo que conectar
416                                 to_connect = find((char *)XML_GET_CONTENT(conector3->children));
417                                 // y lo conecto
418                                 current_item->connect(to_connect, IConector::IN);
419                         } else if (xmlStrcmp(conector3->name, BAD_CAST"salida") == 0) {
420                                 // Era a salida, es casi lo mismo que arriba 
421                                 to_connect = find((char *)XML_GET_CONTENT(conector3->children));
422                                 current_item->connect(to_connect, IConector::OUT);
423                         }
424                 }
425                 nodo = nodo->next;
426         }
427         // Fin de las conexiones
428 }
429
430 std::string Simulator::get_state_as_xml()
431 {
432         std::stringstream out;
433
434         // XML Header
435         out << "<?xml version=\"1.0\" ?>" << std::endl;
436
437         out << "<plantstatus frame=\"" << frame << "\">" << std::endl;
438         
439         std::list<PlantItem *>::iterator i2;
440         for(i2=items.begin(); i2!=items.end(); i2++)
441                 (*i2)->get_state_as_xml(out);
442
443         out << "</plantstatus>";
444         return out.str();;
445 }
446
447 RGB Simulator::loadRGB(xmlNodePtr nodo)
448 {
449         unsigned r,g,b;
450         while (nodo != NULL) {
451                 if (nodo->type == XML_ELEMENT_NODE) {
452                         if (xmlStrcmp(nodo->name, BAD_CAST"rojo")==0)
453                                 r = atoi( (char *)XML_GET_CONTENT(nodo->children) );
454                         if (xmlStrcmp(nodo->name, BAD_CAST"verde")==0)
455                                 g = atoi( (char *)XML_GET_CONTENT(nodo->children) );
456                         if (xmlStrcmp(nodo->name, BAD_CAST"azul")==0)
457                                 b = atoi( (char *)XML_GET_CONTENT(nodo->children) );
458                 }
459                 nodo = nodo->next;
460         }
461         return RGB(r,g,b);
462 }
463