]> git.llucax.com Git - z.facultad/75.42/plaqui.git/commitdiff
- Se cambia bomb por Pump, que es mas representativo en ingles a igual
authorRicardo Markiewicz <gazer.arg@gmail.com>
Tue, 28 Oct 2003 23:58:35 +0000 (23:58 +0000)
committerRicardo Markiewicz <gazer.arg@gmail.com>
Tue, 28 Oct 2003 23:58:35 +0000 (23:58 +0000)
 traduccion
 - Se agregan Sumideros (Drain) y Drenaje (Drainage)
 - Se agrega Splitter
 - La Union no funciona como debe. Cuestiones de diseño que tengo que resolver
 - Nuevo ejemplo con Splitter y Drenaje
 - Se actualiza diagrama de clases

 Salvando por la Union, el modelo esta casi listo. Las clases que faltan
 agregar son triviales. El problema de la Union lo estoy replanteando. La
 logica de control se agrega en breve.

18 files changed:
Model/include/conduct.h
Model/include/drain.h [new file with mode: 0644]
Model/include/drainage.h [new file with mode: 0644]
Model/include/iconector.h
Model/include/plantitem.h
Model/include/pump.h [moved from Model/include/bomb.h with 86% similarity]
Model/include/splitter.h [new file with mode: 0644]
Model/include/union.h
Model/src/conduct.cpp
Model/src/drain.cpp [new file with mode: 0644]
Model/src/drainage.cpp [new file with mode: 0644]
Model/src/iconector.cpp
Model/src/main.cpp
Model/src/plantitem.cpp
Model/src/pump.cpp [moved from Model/src/bomb.cpp with 59% similarity]
Model/src/splitter.cpp [new file with mode: 0644]
Model/src/union.cpp
docs/clases.dia

index 41921bac79f6461199bd3953a9be00f89b3e4560..7013622dc2830993e813bd811b66bc74b15e9b0a 100644 (file)
@@ -23,7 +23,7 @@ public:
        virtual ~Conduct();
 
        virtual void recieve_msg(int msg, IConector *who, void *data);
-       virtual void update();
+       virtual void update(int dir=OUT);
        virtual void simulate();
 
 protected:
diff --git a/Model/include/drain.h b/Model/include/drain.h
new file mode 100644 (file)
index 0000000..a24c9a3
--- /dev/null
@@ -0,0 +1,39 @@
+
+#ifndef _H_DRAIN_H
+#define _H_DRAIN_H
+
+#include "control.h"
+
+namespace PlaQui {
+
+namespace Model {
+
+/** Modela objetos que recibe liquido */
+class Drain:public Control {
+public:
+       /// Constructor
+       Drain(const std::string &_name);
+       /// Destructor
+       virtual ~Drain();
+
+       virtual bool get_output();
+
+       virtual void simulate();
+       /// Retorna el flujo que entrega actualmente
+       float get_actual_flow() { return actual_flow; }
+       /// Retorna el flujo máximo capaz de entregar
+       float get_capacity() { return capacity; }
+       /// Asigna el flojo máximo capaz de entregar
+       virtual void  set_capacity(float _f) { capacity = _f; }
+protected:
+       float capacity;
+       float actual_flow;
+private:
+       Drain(const Drain &):Control("null") {}
+       Drain &operator = (const Drain &) { return *this; }
+};
+
+}
+}
+#endif // _H_SOURCE_H_
+
diff --git a/Model/include/drainage.h b/Model/include/drainage.h
new file mode 100644 (file)
index 0000000..0491fff
--- /dev/null
@@ -0,0 +1,36 @@
+
+#ifndef _DRAINAGE_H_
+#define _DRAINAGE_H_
+
+#include "drain.h"
+
+namespace PlaQui {
+
+namespace Model {
+
+/** Dranaje 
+ *
+ */
+class Drainage:public Drain {
+public:
+       /// Constructor
+       Drainage(const std::string &_name);
+       /// Destructor
+       virtual ~Drainage();
+
+       virtual void update(int dir=OUT);
+       virtual void simulate();
+
+       virtual void recieve_msg(int msg, IConector *who, void *data);
+
+       virtual void set_capacity(float _f) { /* IGNORO EL CAMBIO DE CAPACIDAD! */ }
+protected:
+private:
+       Drainage(const Drainage &):Drain("null") {}
+       Drainage &operator = (const Drainage &) { return *this; }
+};
+
+}
+}
+
+#endif // _DRAINAGE_H_
index 889e0980fb8e3facc151d069b008b4bb3d74a9b0..916d34175a0549d2ea8cf281508502669e88045a 100644 (file)
@@ -28,7 +28,7 @@ public:
         *  \param where Donde enviar el mensage, IConector::IN o IConector::OUT
         *  \param msg Mensage a enviar
         */
-       void send_msg(int where, int msg);
+       void send_msg(int where, int msg, void *data=NULL);
        
        /** Recibe un mensage
         *
index b07816f9f827a4cf40f1a56416e737270ee4fecb..70fd6ac819bc6b9f6819f7ddc41233ad4fcdfd14 100644 (file)
@@ -38,7 +38,7 @@ public:
         *  Durante la fase de actualización los objetos se comunican entre
         *  sí para determinar cual es el flujo que manejan en una iteración.
         */
-       virtual void update() = 0;
+       virtual void update(int dir=OUT) = 0;
        /** Hace la simulación de esta iteración
         *
         *  Por simulacion se entiende que el modelo debe avisar a las vistas
@@ -59,7 +59,8 @@ public:
 
        /// Mensages manejados por los elementos de la planta
        enum {
-               MSG_QUERY_MAX_FLOW = IConector::MSG_LAST, ///< preguntar por el máximo flujo
+               MSG_QUERY_MAX_FLOW_OUT = IConector::MSG_LAST, ///< flujo maximo a la salida
+               MSG_QUERY_MAX_FLOW_IN, ///< flujo maximo a la entrada
                MSG_RESPONSE_MAX_FLOW, ///< responde al mensage QUERY_MAX_FLOW. data == float
                MSG_LAST
        };
similarity index 86%
rename from Model/include/bomb.h
rename to Model/include/pump.h
index ebba1275bc72cb3fbf473114cd51db697edc8aa9..ab7966ffe2b33f8228d6b211e955b7a2eca70440 100644 (file)
@@ -23,14 +23,14 @@ namespace Model {
  *  0 cuando se le consulta por su flojo máximo.
  *
  */
-class Bomb:public Source {
+class Pump:public Source {
 public:
        /// Constructor
-       Bomb(const std::string &_name);
+       Pump(const std::string &_name);
        /// Destructor
-       virtual ~Bomb();
+       virtual ~Pump();
 
-       virtual void update();
+       virtual void update(int dir=OUT);
        virtual void simulate();
 
        virtual bool get_output();
@@ -51,8 +51,8 @@ protected:
         */
        bool active;
 private:
-       Bomb(const Bomb &):Source("null") {}
-       Bomb &operator = (const Bomb &) { return *this; }
+       Pump(const Pump &):Source("null") {}
+       Pump &operator = (const Pump &) { return *this; }
 };
 
 }
diff --git a/Model/include/splitter.h b/Model/include/splitter.h
new file mode 100644 (file)
index 0000000..7adbb49
--- /dev/null
@@ -0,0 +1,28 @@
+
+#ifndef _SPLITTER_H
+#define _SPLITTER_H
+
+#include "transport.h"
+
+namespace PlaQui {
+
+namespace Model {
+
+class Splitter:public Transport {
+public:
+       Splitter(const std::string &_name);
+       virtual ~Splitter();
+
+       virtual void recieve_msg(int msg, IConector *who, void *data);
+       virtual void update(int dir=OUT);
+       virtual void simulate();
+protected:
+private:
+       Splitter(const Splitter &):Transport("null") {}
+       Splitter &operator = (const Splitter &) { return *this; }
+};
+
+}
+}
+
+#endif //_SPLITTER_H
index 71a87910058eb899d4d73d79042d7cd68d1bb07b..b08bc2368e4d57255dca3776f2c7edc904ee5dd7 100644 (file)
@@ -14,9 +14,11 @@ public:
        virtual ~Union();
 
        virtual void recieve_msg(int msg, IConector *who, void *data);
-       virtual void update();
+       virtual void update(int dir=OUT);
        virtual void simulate();
 protected:
+       int in_on_zero;
+       int in_ready;
 private:
        Union(const Union &):Transport("null") {}
        Union &operator = (const Union &) { return *this; }
index 5eb885cc327f361d09c70a05f0036731d7cadaae..4a4e731665ddaf96f29e15b6efb8761d94ed1ca5 100644 (file)
@@ -11,6 +11,7 @@ Conduct::Conduct(const std::string &_name):Transport(_name)
        // Inicio los parametros de conectores
        in_slots = 1;
        out_slots = 1;
+       actual_flow = 9999;
 }
 
 Conduct::~Conduct()
@@ -20,14 +21,19 @@ Conduct::~Conduct()
 void Conduct::recieve_msg(int msg, IConector *who, void *data)
 {
        switch (msg) {
-               case MSG_QUERY_MAX_FLOW: {
+               case MSG_QUERY_MAX_FLOW_OUT: {
                        // Me preguntan por el flujo máximo.
                        // Primero me actualizo, y luego respondo
-                       update();
-                       float tmp = (actual_flow>max_flow)?max_flow:actual_flow;
+                       float tmp = *((float *)data);
+       //              update();
+                       actual_flow = (actual_flow>max_flow)?max_flow:actual_flow;
+                       actual_flow = (actual_flow<tmp)?actual_flow:tmp;
+
+                       send_msg(OUT, MSG_QUERY_MAX_FLOW_OUT, &actual_flow);
                        // FIXME : no tiene que ir
                        if (out_list.size() == 0) tmp = max_flow;
-                       who->recieve_msg(MSG_RESPONSE_MAX_FLOW, this, &tmp);
+                       who->recieve_msg(MSG_RESPONSE_MAX_FLOW, this, &actual_flow);
+                       updated = true;
                }
                break;
                case MSG_RESPONSE_MAX_FLOW: {
@@ -43,15 +49,20 @@ void Conduct::recieve_msg(int msg, IConector *who, void *data)
        }
 }
 
-void Conduct::update()
+void Conduct::update(int dir)
 {
        // Si ya me actualice, no lo tengo que hacer de nuevo
        if (updated) return;
        // Seteo mi actualizar en true para evitar entrar de nuevo
-       actual_flow = 99999;
+//     actual_flow = 99999;
        updated = true;
-       send_msg(OUT, MSG_QUERY_MAX_FLOW);
-       send_msg(IN, MSG_QUERY_MAX_FLOW);
+       switch (dir) {
+               case IN:
+                       send_msg(IN, MSG_QUERY_MAX_FLOW_IN, (void *)&max_flow);
+               break;
+               case OUT:
+                       send_msg(OUT, MSG_QUERY_MAX_FLOW_OUT, (void *)&max_flow);
+       }
 }
 
 void Conduct::simulate()
@@ -62,5 +73,6 @@ void Conduct::simulate()
 
        std::cout << name << "::Flujo actual = " << actual_flow << std::endl;
        updated = false;
+       actual_flow = 99999;
 }
 
diff --git a/Model/src/drain.cpp b/Model/src/drain.cpp
new file mode 100644 (file)
index 0000000..fa682cc
--- /dev/null
@@ -0,0 +1,26 @@
+
+#include "drain.h"
+#include <iostream>
+
+using namespace PlaQui::Model;
+
+Drain::Drain(const std::string &_name):Control(_name)
+{
+}
+
+Drain::~Drain()
+{
+}
+
+bool Drain::get_output()
+{
+       // Siempre esta abierta una Fuente, salvo que
+       // se indique lo contrario!
+       return true;
+}
+
+void Drain::simulate()
+{
+       std::cout << name << "::Flujo aceptado : " << actual_flow << std::endl;
+}
+
diff --git a/Model/src/drainage.cpp b/Model/src/drainage.cpp
new file mode 100644 (file)
index 0000000..95c55e8
--- /dev/null
@@ -0,0 +1,51 @@
+
+#include "drainage.h"
+#include <iostream>
+
+using namespace PlaQui::Model;
+
+Drainage::Drainage(const std::string &_name):Drain(_name)
+{
+       in_slots = 1;
+       out_slots = 0;
+       // FIXME hacer INFINITO!
+       capacity = 99999;
+       actual_flow = 0.0f;
+}
+
+Drainage::~Drainage()
+{
+}
+
+void Drainage::update(int dir)
+{
+       // El drenaje no tiene que actualizar
+       if (updated) return;
+       actual_flow = 0;
+       updated = true;
+}
+
+void Drainage::simulate()
+{
+       std::cout << name << "::Flujo recibido = " << actual_flow << std::endl;
+       updated = false;
+       actual_flow = 0;
+}
+
+void Drainage::recieve_msg(int msg, IConector *who, void *data)
+{
+       float tmp;
+       switch (msg) {
+               case MSG_QUERY_MAX_FLOW_OUT:
+                       // FIXME Hacer INFINITO !!!
+                       actual_flow = *((float *)data);
+                       std::cout << "DD" << std::endl;
+                       tmp = 999999;
+                       who->recieve_msg(MSG_RESPONSE_MAX_FLOW, this, &tmp);
+                       updated = true;
+               break;
+               default:
+                       Drain::recieve_msg(msg, who, data);
+       }
+}
+
index 3307305eefed82dd58437632228cc88d5be9e4e5..7cbdd5670720b38622cd605abf8ec9abf1e95543 100644 (file)
@@ -17,7 +17,7 @@ IConector::~IConector()
        out_list.clear();
 }
 
-void IConector::send_msg(int where, int msg)
+void IConector::send_msg(int where, int msg, void *data)
 {
        // Recorro toda la lista y envío el mensage a cada
        // elemento conectado en "where"
@@ -25,11 +25,11 @@ void IConector::send_msg(int where, int msg)
        switch (where) {
                case IN:
                        for(it=in_list.begin(); it!=in_list.end(); it++)
-                               (*it)->recieve_msg(msg, this, NULL);
+                               (*it)->recieve_msg(msg, this, data);
                        break;
                case OUT:
                        for(it=out_list.begin(); it!=out_list.end(); it++)
-                               (*it)->recieve_msg(msg, this, NULL);
+                               (*it)->recieve_msg(msg, this, data);
        }
 }
 
index 01f9ecb402d17fb0a174cc94325d389568766ac0..3fa359ecf1004263eef690f8761fd7f7477e0adb 100644 (file)
@@ -1,9 +1,11 @@
 
 /* Test pedorro a ver que pasa con lo que esta programado!! */
 /* Compilar : g++ -Wall -o test -I../include *.cpp */
-#include "bomb.h"
+#include "pump.h"
 #include "conduct.h"
 #include "union.h"
+#include "splitter.h"
+#include "drainage.h"
 #include <unistd.h>
 
 using namespace std;
@@ -11,56 +13,57 @@ using namespace PlaQui::Model;
 
 int main(int argc, char *argv[])
 {
-       Bomb *bomba1, *bomba2;
-       Conduct *canio1;
-       Conduct *canio2;
-       Conduct *salida;
-       Union *union1;
+       Pump *bomba1;
+       Conduct *salida1;
+       Conduct *salida2;
+       Conduct *entrada;
+       Splitter *split;
+       Drainage *dren1, *dren2;
        
 
-       bomba1 = new Bomb("bomba1");
-       bomba1->set_max_flow(3);
-       bomba2 = new Bomb("bomba2");
-       bomba2->set_max_flow(5);
-       canio1 = new Conduct("cond_1");
-       canio1->set_max_flow(5);
-       canio2 = new Conduct("cond_2");
-       canio2->set_max_flow(5);
+       bomba1 = new Pump("bomba");
+       bomba1->set_max_flow(30);
+       salida1 = new Conduct("salida_1");
+       salida1->set_max_flow(2);
+       salida2 = new Conduct("salida_2");
+       salida2->set_max_flow(5);
 
-       union1 = new Union("union");
-       union1->set_max_flow(5);
-       salida = new Conduct("salida");
-       salida->set_max_flow(10);
+       split = new Splitter("splitter");
+       split->set_max_flow(8);
+       entrada = new Conduct("entrada");
+       entrada->set_max_flow(10);
 
-       bomba1->connect(canio1, IConector::OUT);
-       canio1->connect(bomba1, IConector::IN);
-       canio1->connect(union1, IConector::OUT);
+       dren1 = new Drainage("drenaje1");
+       dren2 = new Drainage("drenaje2");
 
-       bomba2->connect(canio2, IConector::OUT);
-       canio2->connect(bomba2, IConector::IN);
-       canio2->connect(union1, IConector::OUT);
-
-       union1->connect(canio1, IConector::IN);
-       union1->connect(canio2, IConector::IN);
-       union1->connect(salida, IConector::OUT);
-
-       salida->connect(union1, IConector::IN);
+       bomba1->connect(entrada, IConector::OUT);
+       entrada->connect(bomba1, IConector::IN);
+       entrada->connect(split, IConector::OUT);
+       split->connect(entrada, IConector::IN);
+       split->connect(salida1, IConector::OUT);
+       split->connect(salida2, IConector::OUT);
+       salida1->connect(split, IConector::IN);
+       salida2->connect(split, IConector::IN);
+       salida1->connect(dren1, IConector::OUT);
+       salida2->connect(dren2, IConector::OUT);
 
        int i = 0;
        while (i<10) {
                bomba1->update();
-               bomba2->update();
-               canio1->update();
-               canio2->update();
-               salida->update();
-               union1->update();
+               salida1->update();
+               salida2->update();
+               entrada->update();
+               split->update();
+               dren1->update();
+               dren2->update();
 
                bomba1->simulate();
-               bomba2->simulate();
-               canio1->simulate();
-               canio2->simulate();
-               salida->simulate();
-               union1->simulate();
+               salida1->simulate();
+               salida2->simulate();
+               entrada->simulate();
+               split->simulate();
+               dren1->simulate();
+               dren2->simulate();
                                        
                sleep(1);
                if (i == 5) {
@@ -70,11 +73,10 @@ int main(int argc, char *argv[])
        }
 
        delete bomba1;
-       delete bomba2;
-       delete canio1;
-       delete canio2;
-       delete salida;
-       delete union1;
+       delete salida1;
+       delete salida2;
+       delete entrada;
+       delete split;
        return 1;
 }
 
index aa3aa230a36b705647f9fc3a4f1450027c1b7b60..1ce56f8734174220a302a07c29d439f4b43b5156 100644 (file)
@@ -22,7 +22,7 @@ PlantItem::~PlantItem()
 void PlantItem::recieve_msg(int msg, IConector *who, void *data)
 {
        switch (msg) {
-               case MSG_QUERY_MAX_FLOW:
+               case MSG_QUERY_MAX_FLOW_OUT:
                        // TODO
                        return;
                break;
similarity index 59%
rename from Model/src/bomb.cpp
rename to Model/src/pump.cpp
index 82302b0da43c1bd1607cafb74299d4d91d87de09..086138f4844358407790d7d32da462ba3b3fc108 100644 (file)
@@ -1,10 +1,10 @@
 
-#include "bomb.h"
+#include "pump.h"
 #include <iostream>
 
 using namespace PlaQui::Model;
 
-Bomb::Bomb(const std::string &_name):Source(_name)
+Pump::Pump(const std::string &_name):Source(_name)
 {
        in_slots = 0;
        out_slots = 1;
@@ -13,19 +13,22 @@ Bomb::Bomb(const std::string &_name):Source(_name)
        max_flow = actual_flow = 0.0f;
 }
 
-Bomb::~Bomb()
+Pump::~Pump()
 {
 }
 
-void Bomb::update()
+void Pump::update(int dir)
 {
        if (updated) return;
-       actual_flow = 99999;
+       if (active && open)
+               actual_flow = max_flow;
+       else
+               actual_flow = 0;
        updated = true;
-       send_msg(OUT, MSG_QUERY_MAX_FLOW);
+       send_msg(OUT, MSG_QUERY_MAX_FLOW_OUT, (void *)&actual_flow);
 }
 
-void Bomb::simulate()
+void Pump::simulate()
 {
        std::cout << name << "::Flujo actual = " << ((active && open)?actual_flow:0) \
        << " de " << max_flow;
@@ -33,7 +36,7 @@ void Bomb::simulate()
        updated = false;
 }
 
-bool Bomb::get_output()
+bool Pump::get_output()
 {
        /* Si el corte fue manual, no puedo hacer nada */
        if (active == false) return false;
@@ -42,20 +45,17 @@ bool Bomb::get_output()
        return open;
 }
 
-void Bomb::recieve_msg(int msg, IConector *who, void *data)
+void Pump::recieve_msg(int msg, IConector *who, void *data)
 {
        switch (msg) {
-               case MSG_QUERY_MAX_FLOW: {
+               case MSG_QUERY_MAX_FLOW_OUT: {
                        // Me preguntan por el flujo máximo.
                        // Primero me actualizo, y luego respondo
-                       update();
+                       // TODO la bomba nunca deberia ser consultada,pues el flujo sale ella
+               /*      update();
                        float tmp;
-                       if (active && open) {
-                               tmp = (actual_flow<max_flow)?actual_flow:max_flow;
-                       } else {
-                               tmp = 0.0f;
-                       }
-                       who->recieve_msg(MSG_RESPONSE_MAX_FLOW, this, &tmp);
+                       tmp = (actual_flow<max_flow)?actual_flow:max_flow;
+                       who->recieve_msg(MSG_RESPONSE_MAX_FLOW, this, &tmp);*/
                }
                break;
                case MSG_RESPONSE_MAX_FLOW: {
diff --git a/Model/src/splitter.cpp b/Model/src/splitter.cpp
new file mode 100644 (file)
index 0000000..bf59c0f
--- /dev/null
@@ -0,0 +1,89 @@
+
+#include "splitter.h"
+#include <iostream>
+
+using namespace PlaQui::Model;
+
+Splitter::Splitter(const std::string &_name):Transport(_name)
+{
+       in_slots = 1;
+       out_slots = 2;
+       max_flow = actual_flow = 0.0f;
+}
+
+Splitter::~Splitter()
+{
+}
+
+void Splitter::recieve_msg(int msg, IConector *who, void *data)
+{
+       int pos = OUT;
+
+       // Verifico si esta conectado a mi entrada
+       std::list<IConector *>::iterator i;
+       for(i=in_list.begin(); i!=in_list.end(); i++) {
+               if ((*i) == who) pos = IN;
+       }
+       
+       switch (msg) {
+               case MSG_QUERY_MAX_FLOW_OUT: {
+                       // Me preguntan por el flujo máximo.
+                       // Primero me actualizo, y luego respondo
+                       actual_flow =  *((float *)data);
+
+                       if (max_flow < actual_flow) actual_flow = max_flow;
+
+                       actual_flow /= 2.0f;
+
+                       send_msg(OUT, MSG_QUERY_MAX_FLOW_OUT, &actual_flow);
+
+                       // Listo, mi flujo ahora es el doble de lo que me pueden
+                       // dar las salidas
+                       actual_flow *= 2.0f;
+                       who->recieve_msg(MSG_RESPONSE_MAX_FLOW, this, &actual_flow);
+                       updated = true;
+               }
+               break;
+               case MSG_RESPONSE_MAX_FLOW: {
+                       float max = *((float *)data);
+                       if (pos == OUT) {
+                               if (max < actual_flow)  actual_flow = max;
+                               if (max_flow < actual_flow) actual_flow = max_flow;
+                       } else {
+                                       if (((2*max) < actual_flow) && (max != 0))
+                                               actual_flow = 2*max;
+                       }
+               }
+               break;
+               default:
+                       Transport::recieve_msg(msg, who, data);
+       }
+}
+
+void Splitter::update(int dir)
+{
+       // Si ya me actualice, no lo tengo que hacer de nuevo
+       if (updated) return;
+       // Seteo mi actualizar en true para evitar entrar de nuevo
+       //      actual_flow = 99999;
+       updated = true;
+       switch (dir) {
+               case IN:
+                       send_msg(IN, MSG_QUERY_MAX_FLOW_IN, (void *)&max_flow);
+               break;
+               case OUT:
+                       send_msg(OUT, MSG_QUERY_MAX_FLOW_OUT, (void *)&max_flow);
+       }
+}
+
+void Splitter::simulate()
+{
+       if (!updated) {
+               return;
+       }
+
+       std::cout << name << "::Flujo actual = " << actual_flow << std::endl;
+       updated = false;
+       actual_flow = 99999;
+}
+
index 331e9536245f099f0ce5f54dc2d9572783db5ead..3b6a266f28c9b2fdb4efd3cb42a24cd0ebf394f2 100644 (file)
@@ -9,6 +9,8 @@ Union::Union(const std::string &_name):Transport(_name)
        in_slots = 2;
        out_slots = 1;
        max_flow = actual_flow = 0.0f;
+       in_on_zero = 0;
+       in_ready = 0;
 }
 
 Union::~Union()
@@ -26,19 +28,33 @@ void Union::recieve_msg(int msg, IConector *who, void *data)
        }
        
        switch (msg) {
-               case MSG_QUERY_MAX_FLOW: {
+               case MSG_QUERY_MAX_FLOW_OUT: {
                        // Me preguntan por el flujo máximo.
                        // Primero me actualizo, y luego respondo
-                       update();
-                       float tmp;
+                       float m_data =  *((float *)data)*2;
 
-                       tmp = (actual_flow<max_flow)?actual_flow:max_flow;
-                       if (pos == IN) {
-                                       // Si esta conectado a mi entrada, le puedo aceptar
-                                       // solo la mitad del flujo maximo
-                                       tmp /= 2;
+                       if (m_data == 0) {
+                               in_on_zero++;
                        }
+
+                       float tmp;
+                       switch (in_on_zero) {
+                               case 0:
+                                       actual_flow = (m_data<max_flow)?m_data:max_flow;
+                               break;
+                               case 1:
+                                       actual_flow = max_flow/2.0f;
+                               break;
+                               case 2:
+                                       actual_flow = 0;
+                       }
+                       send_msg(OUT, MSG_QUERY_MAX_FLOW_OUT, &actual_flow);
+
+                       // FIXME hay que resolver el problema de avisar a las
+                       // entradas el flujo correcto que deben enviar
+                       tmp = (in_on_zero==0)?actual_flow/2.0f:actual_flow;
                        who->recieve_msg(MSG_RESPONSE_MAX_FLOW, this, &tmp);
+                       updated = true;
                }
                break;
                case MSG_RESPONSE_MAX_FLOW: {
@@ -46,7 +62,8 @@ void Union::recieve_msg(int msg, IConector *who, void *data)
                        if (pos == OUT) {
                                if (max < actual_flow)  actual_flow = max;
                        } else {
-                               if ((2*max) < actual_flow) actual_flow = 2*max;
+                                       if (((2*max) < actual_flow) && (max != 0))
+                                               actual_flow = 2*max;
                        }
                }
                break;
@@ -55,15 +72,20 @@ void Union::recieve_msg(int msg, IConector *who, void *data)
        }
 }
 
-void Union::update()
+void Union::update(int dir)
 {
        // Si ya me actualice, no lo tengo que hacer de nuevo
        if (updated) return;
        // Seteo mi actualizar en true para evitar entrar de nuevo
-       actual_flow = 99999;
+//     actual_flow = 99999;
        updated = true;
-       send_msg(OUT, MSG_QUERY_MAX_FLOW);
-       send_msg(IN, MSG_QUERY_MAX_FLOW);
+       switch (dir) {
+               case IN:
+                       send_msg(IN, MSG_QUERY_MAX_FLOW_IN, (void *)&max_flow);
+               break;
+               case OUT:
+                       send_msg(OUT, MSG_QUERY_MAX_FLOW_OUT, (void *)&max_flow);
+       }
 }
 
 void Union::simulate()
@@ -74,5 +96,8 @@ void Union::simulate()
 
        std::cout << name << "::Flujo actual = " << actual_flow << std::endl;
        updated = false;
+       actual_flow = 99999;
+       in_on_zero = 0;
+       in_ready = 0;
 }
 
index 8ac71763db207fed6ed11b5b777c56787d4f9715..3ec90939ba0defec5d2b1659ec2b985ab5772823 100644 (file)
Binary files a/docs/clases.dia and b/docs/clases.dia differ