]> git.llucax.com Git - z.facultad/75.42/plaqui.git/blob - Model/src/simulator.cpp
Se ponen flags del compilador para libxml2 con pkg-config.
[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::pump_deactivate(const std::string &name)
162 {
163         // Busco el elemento, usando RTTI :-(
164         Pump *pump = dynamic_cast<Pump *>(find(name));
165
166         if (!pump) {
167                 // Ups!, "name" no era un Pump!!!
168                 return false;
169         }
170         pump->deactivate();
171         return true;
172 }
173
174 void Simulator::loadBomba(xmlNodePtr nodo)
175 {
176         std::string name = (char *)xmlGetProp(nodo, BAD_CAST"nombre");
177         int orientacion=0, x, y;
178         RGB color;
179         float flujo;
180
181         nodo = nodo->children;
182         while (nodo != NULL) {
183                 if (nodo->type == XML_ELEMENT_NODE) {
184                         if (xmlStrcmp(nodo->name, BAD_CAST"orientacion") == 0) {
185                                 orientacion = atoi( (char *)XML_GET_CONTENT(nodo->children) );
186                         } else if (xmlStrcmp(nodo->name, BAD_CAST"x") == 0) {
187                                 x = atoi( (char *)XML_GET_CONTENT(nodo->children) );
188                         } else if (xmlStrcmp(nodo->name, BAD_CAST"y") == 0) {
189                                 y = atoi( (char *)XML_GET_CONTENT(nodo->children) );
190                         } else if (xmlStrcmp(nodo->name, BAD_CAST"entrega") == 0) {
191                                 flujo = atof( (char *)XML_GET_CONTENT(nodo->children) );
192                         } else if (xmlStrcmp(nodo->name, BAD_CAST"color") == 0) {
193                                 // FIXME !
194                                 color = RGB();
195                         }
196                 }
197                 nodo = nodo->next;
198         }
199
200         add_pump(name, flujo, color);
201 }
202
203 void Simulator::loadConduct(xmlNodePtr nodo)
204 {
205         std::string name = (char *)xmlGetProp(nodo, BAD_CAST"nombre");
206         int orientacion=0, x, y;
207         float flujo;
208
209         nodo = nodo->children;
210         while (nodo != NULL) {
211                 if (nodo->type == XML_ELEMENT_NODE) {
212                         if (xmlStrcmp(nodo->name, BAD_CAST"orientacion") == 0) {
213                                 orientacion = atoi( (char *)XML_GET_CONTENT(nodo->children) );
214                         } else if (xmlStrcmp(nodo->name, BAD_CAST"x") == 0) {
215                                 x = atoi( (char *)XML_GET_CONTENT(nodo->children) );
216                         } else if (xmlStrcmp(nodo->name, BAD_CAST"y") == 0) {
217                                 y = atoi( (char *)XML_GET_CONTENT(nodo->children) );
218                         } else if (xmlStrcmp(nodo->name, BAD_CAST"caudal") == 0) {
219                                 flujo = atof( (char *)XML_GET_CONTENT(nodo->children) );
220                         }
221                         
222
223                 }
224                 nodo = nodo->next;
225         }
226
227         // listo, ya recolecte todos los datos, ahora creo el objeto!
228         add_conduct(name, flujo);
229 }
230
231 void Simulator::loadExclusa(xmlNodePtr nodo)
232 {
233         std::string name = (char *)xmlGetProp(nodo, BAD_CAST"nombre");
234         int orientacion=0, x, y;
235         std::string open;
236
237         nodo = nodo->children;
238         while (nodo != NULL) {
239                 if (nodo->type == XML_ELEMENT_NODE) {
240                         if (xmlStrcmp(nodo->name, BAD_CAST"orientacion") == 0) {
241                                 orientacion = atoi( (char *)XML_GET_CONTENT(nodo->children) );
242                         } else if (xmlStrcmp(nodo->name, BAD_CAST"x") == 0) {
243                                 x = atoi( (char *)XML_GET_CONTENT(nodo->children) );
244                         } else if (xmlStrcmp(nodo->name, BAD_CAST"y") == 0) {
245                                 y = atoi( (char *)XML_GET_CONTENT(nodo->children) );
246                         } else if (xmlStrcmp(nodo->name, BAD_CAST"estado") == 0) {
247                                 open = (char *)XML_GET_CONTENT(nodo->children);
248                         }
249                 }
250                 nodo = nodo->next;
251         }
252
253         // listo, ya recolecte todos los datos, ahora creo el objeto!
254         add_exclusa(name, open == "1");
255 }
256
257 void Simulator::loadTank(xmlNodePtr nodo)
258 {
259         std::string name = (char *)xmlGetProp(nodo, BAD_CAST"nombre");
260         int orientacion=0, x, y;
261         float capacidad, inicial;
262         RGB color; // TODO
263
264         nodo = nodo->children;
265         while (nodo != NULL) {
266                 if (nodo->type == XML_ELEMENT_NODE) {
267                         if (xmlStrcmp(nodo->name, BAD_CAST"orientacion") == 0) {
268                                 orientacion = atoi( (char *)XML_GET_CONTENT(nodo->children) );
269                         } else if (xmlStrcmp(nodo->name, BAD_CAST"x") == 0) {
270                                 x = atoi( (char *)XML_GET_CONTENT(nodo->children) );
271                         } else if (xmlStrcmp(nodo->name, BAD_CAST"y") == 0) {
272                                 y = atoi( (char *)XML_GET_CONTENT(nodo->children) );
273                         } else if (xmlStrcmp(nodo->name, BAD_CAST"capacidad") == 0) {
274                                 capacidad = atoi( (char *)XML_GET_CONTENT(nodo->children) );
275                         } else if (xmlStrcmp(nodo->name, BAD_CAST"inicial") == 0) {
276                                 inicial = atof( (char *)XML_GET_CONTENT(nodo->children) );
277                         }
278                 }
279                 nodo = nodo->next;
280         }
281
282         // listo, ya recolecte todos los datos, ahora creo el objeto!
283         add_tank(name, capacidad, inicial, color);
284 }
285
286 void Simulator::loadUnion(xmlNodePtr nodo)
287 {
288         std::string name = (char *)xmlGetProp(nodo, BAD_CAST"nombre");
289         int orientacion=0, x, y;
290         float flow;
291         std::string type;
292
293         nodo = nodo->children;
294         while (nodo != NULL) {
295                 if (nodo->type == XML_ELEMENT_NODE) {
296                         if (xmlStrcmp(nodo->name, BAD_CAST"orientacion") == 0) {
297                                 orientacion = atoi( (char *)XML_GET_CONTENT(nodo->children) );
298                         } else if (xmlStrcmp(nodo->name, BAD_CAST"x") == 0) {
299                                 x = atoi( (char *)XML_GET_CONTENT(nodo->children) );
300                         } else if (xmlStrcmp(nodo->name, BAD_CAST"y") == 0) {
301                                 y = atoi( (char *)XML_GET_CONTENT(nodo->children) );
302                         } else if (xmlStrcmp(nodo->name, BAD_CAST"caudal") == 0) {
303                                 flow = atof( (char *)XML_GET_CONTENT(nodo->children) );
304                         } else if (xmlStrcmp(nodo->name, BAD_CAST"tipo") == 0) {
305                                 type = (char *)XML_GET_CONTENT(nodo->children);
306                         }
307                 }
308                 nodo = nodo->next;
309         }
310
311         // listo, ya recolecte todos los datos, ahora creo el objeto!
312         if (type == "union")
313                 add_union(name, flow);
314         else
315                 add_splitter(name, flow);
316 }
317
318 void Simulator::loadDrain(xmlNodePtr nodo)
319 {
320         std::string name = (char *)xmlGetProp(nodo, BAD_CAST"nombre");
321
322         add_drainage(name);
323 }
324
325 void Simulator::do_connections(xmlNodePtr nodo)
326 {
327         // Intengo conectar los elementos :)
328         IConector *current_item, *to_connect;
329         xmlNodePtr props; // propiedades del item actual
330         xmlNodePtr conector1, conector2;
331
332         while (nodo != NULL) {
333                 if (nodo->type != XML_ELEMENT_NODE) {
334                         nodo = nodo->next;
335                         continue;
336                 }
337                 // obtengo el items actual por su nombre
338                 current_item = find((char *)xmlGetProp(nodo, BAD_CAST"nombre"));
339                 props = nodo->children;
340                 conector2 = conector1 = NULL;
341                 while (props != NULL) {
342                         if (nodo->type == XML_ELEMENT_NODE) {
343                                 if (xmlStrcmp(props->name, BAD_CAST"conector") == 0) {
344                                         xmlNodePtr temp = props->children;
345                                         while ((temp != NULL) && (conector1 == NULL))
346                                                 if (temp->type == XML_ELEMENT_NODE) {
347                                                         conector1 = temp;
348                                                         temp = temp->next;
349                                                         break;
350                                                 } else {
351                                                         temp = temp->next;
352                                                 }
353                                         while ((temp != NULL) && (conector2 == NULL))
354                                                 if (temp->type == XML_ELEMENT_NODE) {
355                                                         conector2 = temp;
356                                                         temp = temp->next;
357                                                         break;
358                                                 } else {
359                                                         temp = temp->next;
360                                                 }
361                                 }
362                         }
363                         props = props->next;
364                 }
365                 // Bien, conector1 y 2 deberian estar apuntando a <entrada> y/o <salida>
366                 if (conector1 != NULL) {
367                         // si, aca hay un conector!, veamos cual es
368                         if (xmlStrcmp(conector1->name, BAD_CAST"entrada") == 0) {
369                                 // bien, es a la entrada!, obtengo el item al cual lo tengo que conectar
370                                 to_connect = find((char *)XML_GET_CONTENT(conector1->children));
371                                 // y lo conecto
372                                 current_item->connect(to_connect, IConector::IN);
373                         } else if (xmlStrcmp(conector1->name, BAD_CAST"salida") == 0) {
374                                 // Era a salida, es casi lo mismo que arriba 
375                                 to_connect = find((char *)XML_GET_CONTENT(conector1->children));
376                                 current_item->connect(to_connect, IConector::OUT);
377                         }
378                 }
379                 if (conector2 != NULL) {
380                         // si, aca hay un conector!, veamos cual es
381                         if (xmlStrcmp(conector2->name, BAD_CAST"entrada") == 0) {
382                                 // bien, es a la entrada!, obtengo el item al cual lo tengo que conectar
383                                 to_connect = find((char *)XML_GET_CONTENT(conector2->children));
384                                 // y lo conecto
385                                 current_item->connect(to_connect, IConector::IN);
386                         } else if (xmlStrcmp(conector2->name, BAD_CAST"salida") == 0) {
387                                 // Era a salida, es casi lo mismo que arriba 
388                                 to_connect = find((char *)XML_GET_CONTENT(conector2->children));
389                                 current_item->connect(to_connect, IConector::OUT);
390                         }
391                 }
392                 nodo = nodo->next;
393         }
394         // Fin de las conexiones
395 }
396
397 std::string Simulator::get_state_as_xml()
398 {
399         std::stringstream out;
400
401         // XML Header
402         out << "<?xml version=\"1.0\" ?>" << std::endl;
403
404         out << "<plantstatus frame=\"" << frame << "\">" << std::endl;
405         
406         std::list<PlantItem *>::iterator i2;
407         for(i2=items.begin(); i2!=items.end(); i2++)
408                 (*i2)->get_state_as_xml(out);
409
410         out << "</plantstatus>";
411         return out.str();;
412 }
413