]> git.llucax.com Git - z.facultad/75.42/plaqui.git/blob - Model/src/simulator.cpp
Se agrega XML para otros items (no todos ya implementados en el cliente).
[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         p->set_max_flow(flujo);
82         conduct_lst.push_back(p);
83         items.push_back(p);
84 }
85
86 void Simulator::add_exclusa(const std::string &name, bool open)
87 {
88         Exclusa *p = new Exclusa(name);
89         if (!open)
90                 p->close();
91         exclusa_lst.push_back(p);
92         items.push_back(p);
93 }
94
95 void Simulator::add_tank(const std::string &name, float capacity, float initial, RGB color)
96 {
97         Tank *p = new Tank(name);
98         p->set_capacity(capacity);
99         p->set_max_flow(initial);
100         p->set_litros(initial);
101         p->set_color(color);
102         tank_lst.push_back(p);
103         items.push_back(p);
104 }
105
106 void Simulator::add_drainage(const std::string &name)
107 {
108         Drainage *p = new Drainage(name);
109         drainage_lst.push_back(p);
110         items.push_back(p);
111 }
112
113 bool Simulator::connect(const std::string &name1, const std::string &name2, int flag)
114 {
115         IConector *o1, *o2;
116         o1 = find(name1);
117         o2 = find(name2);
118
119         if ((o1 == NULL) || (o2 == NULL)) {
120                 // NO SE PUDO CONECTAR!, FALTAN ITEMS!!
121                 return false;
122         }
123
124         bool b;
125         if (flag == IConector::OUT) {
126                 b = o1->connect(o2, IConector::OUT);
127                 b = b && o2->connect(o1, IConector::IN);
128         } else {
129                 b = o1->connect(o2, IConector::IN);
130                 b = b && o2->connect(o1, IConector::OUT);
131         }
132         
133         return b;
134 }
135
136 void Simulator::simulate()
137 {
138         // Actualizo
139         std::list<Pump *>::iterator i1;
140         for(i1=pump_lst.begin(); i1!=pump_lst.end(); i1++)
141                 (*i1)->update();
142
143         // Simulo!
144         std::list<PlantItem *>::iterator i2;
145         for(i2=items.begin(); i2!=items.end(); i2++)
146                 (*i2)->simulate();
147
148         frame++;
149 }
150
151 IConector *Simulator::find(const std::string &name)
152 {
153         // Busco el item, aca no me importa de que tipo es!
154         std::list<PlantItem *>::iterator i;
155         for(i=items.begin(); i!=items.end(); i++)
156                 if ((*i)->get_name() == name)
157                         return *i;
158         return NULL;
159 }
160
161 bool Simulator::set_open(const std::string &name, bool open)
162 {
163         // Busco el elemento, usando RTTI :-(
164         IConector *tmp = find(name);
165         Pump *p;
166         Exclusa *e;
167         if ((p = dynamic_cast<Pump*>(tmp))) {
168                 if (open) {
169                         p->activate();
170                 } else {
171                         p->deactivate();
172                 }
173         } else if ((e = dynamic_cast<Exclusa*>(tmp))) {
174                 if (open) {
175                         e->open();
176                 } else {
177                         e->close();
178                 }
179         } else {
180                 return false;
181         }
182 }
183
184 void Simulator::loadBomba(xmlNodePtr nodo)
185 {
186         std::string name = (char *)xmlGetProp(nodo, BAD_CAST"nombre");
187         int orientacion=0, x, y;
188         RGB color;
189         float flujo;
190
191         nodo = nodo->children;
192         while (nodo != NULL) {
193                 if (nodo->type == XML_ELEMENT_NODE) {
194                         if (xmlStrcmp(nodo->name, BAD_CAST"orientacion") == 0) {
195                                 orientacion = atoi( (char *)XML_GET_CONTENT(nodo->children) );
196                         } else if (xmlStrcmp(nodo->name, BAD_CAST"x") == 0) {
197                                 x = atoi( (char *)XML_GET_CONTENT(nodo->children) );
198                         } else if (xmlStrcmp(nodo->name, BAD_CAST"y") == 0) {
199                                 y = atoi( (char *)XML_GET_CONTENT(nodo->children) );
200                         } else if (xmlStrcmp(nodo->name, BAD_CAST"entrega") == 0) {
201                                 flujo = atof( (char *)XML_GET_CONTENT(nodo->children) );
202                         } else if (xmlStrcmp(nodo->name, BAD_CAST"color") == 0) {
203                                 // FIXME !
204                                 color = RGB();
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; // TODO
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                         }
288                 }
289                 nodo = nodo->next;
290         }
291
292         // listo, ya recolecte todos los datos, ahora creo el objeto!
293         add_tank(name, capacidad, inicial, color);
294 }
295
296 void Simulator::loadUnion(xmlNodePtr nodo)
297 {
298         std::string name = (char *)xmlGetProp(nodo, BAD_CAST"nombre");
299         int orientacion=0, x, y;
300         float flow;
301         std::string type;
302
303         nodo = nodo->children;
304         while (nodo != NULL) {
305                 if (nodo->type == XML_ELEMENT_NODE) {
306                         if (xmlStrcmp(nodo->name, BAD_CAST"orientacion") == 0) {
307                                 orientacion = atoi( (char *)XML_GET_CONTENT(nodo->children) );
308                         } else if (xmlStrcmp(nodo->name, BAD_CAST"x") == 0) {
309                                 x = atoi( (char *)XML_GET_CONTENT(nodo->children) );
310                         } else if (xmlStrcmp(nodo->name, BAD_CAST"y") == 0) {
311                                 y = atoi( (char *)XML_GET_CONTENT(nodo->children) );
312                         } else if (xmlStrcmp(nodo->name, BAD_CAST"caudal") == 0) {
313                                 flow = atof( (char *)XML_GET_CONTENT(nodo->children) );
314                         } else if (xmlStrcmp(nodo->name, BAD_CAST"tipo") == 0) {
315                                 type = (char *)XML_GET_CONTENT(nodo->children);
316                         }
317                 }
318                 nodo = nodo->next;
319         }
320
321         // listo, ya recolecte todos los datos, ahora creo el objeto!
322         if (type == "union")
323                 add_union(name, flow);
324         else
325                 add_splitter(name, flow);
326 }
327
328 void Simulator::loadDrain(xmlNodePtr nodo)
329 {
330         std::string name = (char *)xmlGetProp(nodo, BAD_CAST"nombre");
331
332         add_drainage(name);
333 }
334
335 void Simulator::do_connections(xmlNodePtr nodo)
336 {
337         // Intengo conectar los elementos :)
338         IConector *current_item, *to_connect;
339         xmlNodePtr props; // propiedades del item actual
340         xmlNodePtr conector1, conector2, conector3;
341
342         while (nodo != NULL) {
343                 if (nodo->type != XML_ELEMENT_NODE) {
344                         nodo = nodo->next;
345                         continue;
346                 }
347                 // obtengo el items actual por su nombre
348                 current_item = find((char *)xmlGetProp(nodo, BAD_CAST"nombre"));
349                 props = nodo->children;
350                 conector3 = conector2 = conector1 = NULL;
351                 while (props != NULL) {
352                         if (nodo->type == XML_ELEMENT_NODE) {
353                                 if (xmlStrcmp(props->name, BAD_CAST"conector") == 0) {
354                                         xmlNodePtr temp = props->children;
355                                         while ((temp != NULL) && (conector1 == NULL))
356                                                 if (temp->type == XML_ELEMENT_NODE) {
357                                                         conector1 = temp;
358                                                         temp = temp->next;
359                                                         break;
360                                                 } else {
361                                                         temp = temp->next;
362                                                 }
363                                         while ((temp != NULL) && (conector2 == NULL))
364                                                 if (temp->type == XML_ELEMENT_NODE) {
365                                                         conector2 = temp;
366                                                         temp = temp->next;
367                                                         break;
368                                                 } else {
369                                                         temp = temp->next;
370                                                 }
371                                         while ((temp != NULL) && (conector3 == NULL))
372                                                 if (temp->type == XML_ELEMENT_NODE) {
373                                                         conector3 = temp;
374                                                         temp = temp->next;
375                                                         break;
376                                                 } else {
377                                                         temp = temp->next;
378                                                 }
379                                 }
380                         }
381                         props = props->next;
382                 }
383                 // Bien, conector1 y 2 deberian estar apuntando a <entrada> y/o <salida>
384                 if (conector1 != NULL) {
385                         // si, aca hay un conector!, veamos cual es
386                         if (xmlStrcmp(conector1->name, BAD_CAST"entrada") == 0) {
387                                 // bien, es a la entrada!, obtengo el item al cual lo tengo que conectar
388                                 to_connect = find((char *)XML_GET_CONTENT(conector1->children));
389                                 // y lo conecto
390                                 current_item->connect(to_connect, IConector::IN);
391                         } else if (xmlStrcmp(conector1->name, BAD_CAST"salida") == 0) {
392                                 // Era a salida, es casi lo mismo que arriba 
393                                 to_connect = find((char *)XML_GET_CONTENT(conector1->children));
394                                 current_item->connect(to_connect, IConector::OUT);
395                         }
396                 }
397                 if (conector2 != NULL) {
398                         // si, aca hay un conector!, veamos cual es
399                         if (xmlStrcmp(conector2->name, BAD_CAST"entrada") == 0) {
400                                 // bien, es a la entrada!, obtengo el item al cual lo tengo que conectar
401                                 to_connect = find((char *)XML_GET_CONTENT(conector2->children));
402                                 // y lo conecto
403                                 current_item->connect(to_connect, IConector::IN);
404                         } else if (xmlStrcmp(conector2->name, BAD_CAST"salida") == 0) {
405                                 // Era a salida, es casi lo mismo que arriba 
406                                 to_connect = find((char *)XML_GET_CONTENT(conector2->children));
407                                 current_item->connect(to_connect, IConector::OUT);
408                         }
409                 }
410                 if (conector3 != NULL) {
411                         // si, aca hay un conector!, veamos cual es
412                         if (xmlStrcmp(conector3->name, BAD_CAST"entrada") == 0) {
413                                 // bien, es a la entrada!, obtengo el item al cual lo tengo que conectar
414                                 to_connect = find((char *)XML_GET_CONTENT(conector3->children));
415                                 // y lo conecto
416                                 current_item->connect(to_connect, IConector::IN);
417                         } else if (xmlStrcmp(conector3->name, BAD_CAST"salida") == 0) {
418                                 // Era a salida, es casi lo mismo que arriba 
419                                 to_connect = find((char *)XML_GET_CONTENT(conector3->children));
420                                 current_item->connect(to_connect, IConector::OUT);
421                         }
422                 }
423                 nodo = nodo->next;
424         }
425         // Fin de las conexiones
426 }
427
428 std::string Simulator::get_state_as_xml()
429 {
430         std::stringstream out;
431
432         // XML Header
433         out << "<?xml version=\"1.0\" ?>" << std::endl;
434
435         out << "<plantstatus frame=\"" << frame << "\">" << std::endl;
436         
437         std::list<PlantItem *>::iterator i2;
438         for(i2=items.begin(); i2!=items.end(); i2++)
439                 (*i2)->get_state_as_xml(out);
440
441         out << "</plantstatus>";
442         return out.str();;
443 }
444