From b75b5632c75f245e59a00775ffbe0affdedf8b6c Mon Sep 17 00:00:00 2001 From: Ricardo Markiewicz Date: Fri, 24 Oct 2003 03:23:45 +0000 Subject: [PATCH] =?utf8?q?=20-=20Se=20agregan=20mas=20comentarios=20a=20la?= =?utf8?q?s=20clases=20=20-=20Se=20agrega=20Union.=20Aun=20tiene=20un=20pe?= =?utf8?q?que=C3=B1o=20bug=20donde=20no=20actualiza=20bien=20su=20propio?= =?utf8?q?=20=09=20flujo=20actual,=20pero=20si=20se=20actualiza=20bien=20e?= =?utf8?q?l=20flujo=20de=20sus=20entradas=20=20-=20Se=20agrega=20una=20uni?= =?utf8?q?on=20al=20ejemplo,=20ahora=20se=20modela=20algo=20como=20:=20=20?= =?utf8?q?=20=20+---+=20=20=20=20=20=20+---+=20=09=20|=20B=20|=20=20=20=20?= =?utf8?q?=20=20|=20B=20|=20=09=20+---+=20=20=20=20=20=20+---+=20=09=20=20?= =?utf8?q?=20\=20=20=20=20=20=20=20=20=20/=20=09cond\=20=20=20=20=20=20=20?= =?utf8?q?/cond=20=09=09=09=20\-----/=20=09=09=09=20=20|=20U=20=20|=20=09?= =?utf8?q?=09=09=09+---+=20=09=09=09=09=20=20|=20=09=09=09=09=09|cond=20?= =?utf8?q?=09=09=09=09=09|=20=09B=3Dbomba=20=09U=3Dunion=20=09cond=3Dcondu?= =?utf8?q?cto?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- Model/include/bomb.h | 21 ++++++++++- Model/include/conduct.h | 12 ++++-- Model/include/control.h | 4 ++ Model/include/iconector.h | 8 +++- Model/include/plantitem.h | 33 ++++++++++++++--- Model/include/source.h | 5 +++ Model/include/transport.h | 9 +++++ Model/include/union.h | 28 ++++++++++++++ Model/src/bomb.cpp | 1 + Model/src/conduct.cpp | 2 +- Model/src/iconector.cpp | 1 + Model/src/main.cpp | 53 ++++++++++++++++++++------ Model/src/union.cpp | 78 +++++++++++++++++++++++++++++++++++++++ 13 files changed, 231 insertions(+), 24 deletions(-) create mode 100644 Model/include/union.h create mode 100644 Model/src/union.cpp diff --git a/Model/include/bomb.h b/Model/include/bomb.h index 468bbb5..ebba127 100644 --- a/Model/include/bomb.h +++ b/Model/include/bomb.h @@ -8,10 +8,27 @@ namespace PlaQui { namespace Model { +/** Bomba hidráulica + * + * La bomba es un elemento que toma líquido de alguna fuente + * misteriosa y lo envía por su salida. La cantidad de fluido que + * envía va a depender exclusivamente del sistema al cual está conectado. + * La bomba es "inteligente", y es capaz de reducir el flujo que envía + * dependiendo de las condiciones que le ponga el sistema, reduciendo + * así el flujo de manera automática para evitar sobrecargas. + * + * La bomba tiene 2 interruptores, uno manual y otro automático. + * Si el manual está apagado, la bomba se considera apagada e ignora + * todo mensage del interruptor automático. En esta condición envía + * 0 cuando se le consulta por su flojo máximo. + * + */ class Bomb:public Source { public: + /// Constructor Bomb(const std::string &_name); - ~Bomb(); + /// Destructor + virtual ~Bomb(); virtual void update(); virtual void simulate(); @@ -20,7 +37,9 @@ public: virtual void recieve_msg(int msg, IConector *who, void *data); + /// Activa la bomba void activate() { active = true; } + /// Desactiva la bomba void deactivate() { active = false; } protected: /** Define si la bomba esta abierta o no. Esto lo maneja la logica de diff --git a/Model/include/conduct.h b/Model/include/conduct.h index 811ea26..41921ba 100644 --- a/Model/include/conduct.h +++ b/Model/include/conduct.h @@ -8,16 +8,22 @@ namespace PlaQui { namespace Model { - + +/** Conducto de transporte de fluido + * + * Un conducto puede modelar tanto a un caño recto como a un + * codo. Su principal objetivo es saber que flujo puede pasar por + * el y consultar que flujo pasará en cada iteración + */ class Conduct:public Transport { public: + /// Constructor Conduct(const std::string &_name); + /// Destructor virtual ~Conduct(); virtual void recieve_msg(int msg, IConector *who, void *data); - /// Hace que los elementos de la plata actualicen su flujo en esta etapa virtual void update(); - /// Hace la simulación de esta iteración virtual void simulate(); protected: diff --git a/Model/include/control.h b/Model/include/control.h index 00c56fa..4429627 100644 --- a/Model/include/control.h +++ b/Model/include/control.h @@ -11,9 +11,12 @@ namespace Model { /** Elementos que pueden ser automatizados */ class Control:public PlantItem { public: + /// Constructor Control(const std::string &_name); + /// Destructor virtual ~Control(); + /// Retorna un estado booleano dependiendo de su estado actual virtual bool get_output() = 0; protected: /* @@ -29,3 +32,4 @@ private: } #endif // _CONTROL_H_ + diff --git a/Model/include/iconector.h b/Model/include/iconector.h index eae2175..889e098 100644 --- a/Model/include/iconector.h +++ b/Model/include/iconector.h @@ -12,14 +12,18 @@ namespace Model { */ class IConector { public: - /// Constructor + /** Constructor + * + * \param in Cantidad de entradas + * \param out Cantidad de salidas + */ IConector(unsigned in, unsigned out); /// Destructor virtual ~IConector(); /** Envía un mensage a los elementos conectados * - * Esvía un mensage a los elementos conectados a la entrada o + * Envía un mensage a los elementos conectados a la entrada o * a la salida. * \param where Donde enviar el mensage, IConector::IN o IConector::OUT * \param msg Mensage a enviar diff --git a/Model/include/plantitem.h b/Model/include/plantitem.h index 1e28b0b..b07816f 100644 --- a/Model/include/plantitem.h +++ b/Model/include/plantitem.h @@ -10,21 +10,40 @@ namespace PlaQui { namespace Model { - + +/** Elementos simulables en una planta + * + * Todo elemento que pueda ser simulado en la planta debe + * descender de esta clase. + */ class PlantItem:public IConector { public: - /// Constructor + /** Constructor + * + * \param _name Nombre único que identifica el objeto + */ PlantItem(const std::string &_name); + /// FIXME : agregar el nombre! PlantItem(unsigned ins, unsigned outs); + /// Destructor virtual ~PlantItem(); // FIXME: ver que parametros seran necesarios + // TODO : ver si no son inutiles!!! virtual void send_fluid() {} virtual void receive_fluid() {} - /// Hace que los elementos de la plata actualicen su flujo en esta etapa + /** Ejecuta la fase de actualización. + * + * 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; - /// Hace la simulación de esta iteración + /** Hace la simulación de esta iteración + * + * Por simulacion se entiende que el modelo debe avisar a las vistas + * que ya está actualizado para que el usuario vea los resultados. + */ virtual void simulate() = 0; /// Setea el nuevo color del fluido @@ -32,11 +51,15 @@ public: /// Retorna el actual color del fluido const RGB &getColor() { return fluid_color; } + /** Recive un mensage y lo procesa + * + * \see IConector::recieve_msg + */ virtual void recieve_msg(int msg, IConector *who, void *data); /// Mensages manejados por los elementos de la planta enum { - MSG_QUERY_MAX_FLOW = IConector::MSG_LAST, ///< pregunta por el maximo flujo + MSG_QUERY_MAX_FLOW = IConector::MSG_LAST, ///< preguntar por el máximo flujo MSG_RESPONSE_MAX_FLOW, ///< responde al mensage QUERY_MAX_FLOW. data == float MSG_LAST }; diff --git a/Model/include/source.h b/Model/include/source.h index 41a7266..fde6511 100644 --- a/Model/include/source.h +++ b/Model/include/source.h @@ -11,14 +11,19 @@ namespace Model { /** Modela objetos desde donde fluye liquido */ class Source:public Control { public: + /// Constructor Source(const std::string &_name); + /// Destructor virtual ~Source(); 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_max_flow() { return max_flow; } + /// Asigna el flojo máximo capaz de entregar void set_max_flow(float _f) { max_flow = _f; } protected: float max_flow; diff --git a/Model/include/transport.h b/Model/include/transport.h index b6474b3..d27ca0d 100644 --- a/Model/include/transport.h +++ b/Model/include/transport.h @@ -9,13 +9,22 @@ namespace PlaQui { namespace Model { +/** Elementos que permiten transportar fluidos + * + * Estos objetos son capaces de transportar fluidos solamente. + */ class Transport:public PlantItem { public: + /// Constructor Transport(const std::string &_name); + /// Destructor virtual ~Transport(); + /// Retorna el flujo actual que maneja el objeto. float get_actual_flow() { return actual_flow; } + /// Retorna el flujo máximo soportado por el objeto float get_max_flow() { return max_flow; } + /// Asigna el flujo máximo a manejar void set_max_flow(float _f) { max_flow = _f; } protected: // Es de solo lectura, no hay set diff --git a/Model/include/union.h b/Model/include/union.h new file mode 100644 index 0000000..71a8791 --- /dev/null +++ b/Model/include/union.h @@ -0,0 +1,28 @@ + +#ifndef _UNION_H_ +#define _UNION_H_ + +#include "transport.h" + +namespace PlaQui { + +namespace Model { + +class Union:public Transport { +public: + Union(const std::string &_name); + virtual ~Union(); + + virtual void recieve_msg(int msg, IConector *who, void *data); + virtual void update(); + virtual void simulate(); +protected: +private: + Union(const Union &):Transport("null") {} + Union &operator = (const Union &) { return *this; } +}; + +} +} + +#endif //_UNION_H_ diff --git a/Model/src/bomb.cpp b/Model/src/bomb.cpp index b9159a6..82302b0 100644 --- a/Model/src/bomb.cpp +++ b/Model/src/bomb.cpp @@ -30,6 +30,7 @@ void Bomb::simulate() std::cout << name << "::Flujo actual = " << ((active && open)?actual_flow:0) \ << " de " << max_flow; std::cout << ((active && open)?" (funcionando)":" (apagada)") << std::endl; + updated = false; } bool Bomb::get_output() diff --git a/Model/src/conduct.cpp b/Model/src/conduct.cpp index 495e94a..5eb885c 100644 --- a/Model/src/conduct.cpp +++ b/Model/src/conduct.cpp @@ -50,8 +50,8 @@ void Conduct::update() // Seteo mi actualizar en true para evitar entrar de nuevo actual_flow = 99999; updated = true; - send_msg(IN, MSG_QUERY_MAX_FLOW); send_msg(OUT, MSG_QUERY_MAX_FLOW); + send_msg(IN, MSG_QUERY_MAX_FLOW); } void Conduct::simulate() diff --git a/Model/src/iconector.cpp b/Model/src/iconector.cpp index eb9a647..3307305 100644 --- a/Model/src/iconector.cpp +++ b/Model/src/iconector.cpp @@ -54,6 +54,7 @@ bool IConector::connect(IConector *obj, int place) } else { return false; // no se pudo conectar! } + break; case OUT: if (out_list.size() <= out_slots) { out_list.push_back(obj); diff --git a/Model/src/main.cpp b/Model/src/main.cpp index 237e158..01f9ecb 100644 --- a/Model/src/main.cpp +++ b/Model/src/main.cpp @@ -3,6 +3,7 @@ /* Compilar : g++ -Wall -o test -I../include *.cpp */ #include "bomb.h" #include "conduct.h" +#include "union.h" #include using namespace std; @@ -10,42 +11,70 @@ using namespace PlaQui::Model; int main(int argc, char *argv[]) { - Bomb *bomba; + Bomb *bomba1, *bomba2; Conduct *canio1; Conduct *canio2; + Conduct *salida; + Union *union1; + - bomba = new Bomb("bomba"); - bomba->set_max_flow(3); + 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(10); + canio1->set_max_flow(5); canio2 = new Conduct("cond_2"); canio2->set_max_flow(5); - bomba->connect(canio1, IConector::OUT); - canio1->connect(bomba, IConector::IN); - canio1->connect(canio2, IConector::OUT); - canio2->connect(canio1, IConector::IN); + union1 = new Union("union"); + union1->set_max_flow(5); + salida = new Conduct("salida"); + salida->set_max_flow(10); + + bomba1->connect(canio1, IConector::OUT); + canio1->connect(bomba1, IConector::IN); + canio1->connect(union1, IConector::OUT); + + 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); int i = 0; while (i<10) { - bomba->update(); + bomba1->update(); + bomba2->update(); canio1->update(); canio2->update(); + salida->update(); + union1->update(); - bomba->simulate(); + bomba1->simulate(); + bomba2->simulate(); canio1->simulate(); canio2->simulate(); + salida->simulate(); + union1->simulate(); sleep(1); if (i == 5) { - bomba->deactivate(); + bomba1->deactivate(); } i++; } - delete bomba; + delete bomba1; + delete bomba2; delete canio1; delete canio2; + delete salida; + delete union1; return 1; } diff --git a/Model/src/union.cpp b/Model/src/union.cpp new file mode 100644 index 0000000..331e953 --- /dev/null +++ b/Model/src/union.cpp @@ -0,0 +1,78 @@ + +#include "union.h" +#include + +using namespace PlaQui::Model; + +Union::Union(const std::string &_name):Transport(_name) +{ + in_slots = 2; + out_slots = 1; + max_flow = actual_flow = 0.0f; +} + +Union::~Union() +{ +} + +void Union::recieve_msg(int msg, IConector *who, void *data) +{ + int pos = OUT; + + // Verifico si esta conectado a mi entrada + std::list::iterator i; + for(i=in_list.begin(); i!=in_list.end(); i++) { + if ((*i) == who) pos = IN; + } + + switch (msg) { + case MSG_QUERY_MAX_FLOW: { + // Me preguntan por el flujo máximo. + // Primero me actualizo, y luego respondo + update(); + float tmp; + + tmp = (actual_flowrecieve_msg(MSG_RESPONSE_MAX_FLOW, this, &tmp); + } + break; + case MSG_RESPONSE_MAX_FLOW: { + float max = *((float *)data); + if (pos == OUT) { + if (max < actual_flow) actual_flow = max; + } else { + if ((2*max) < actual_flow) actual_flow = 2*max; + } + } + break; + default: + Transport::recieve_msg(msg, who, data); + } +} + +void Union::update() +{ + // 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; + send_msg(OUT, MSG_QUERY_MAX_FLOW); + send_msg(IN, MSG_QUERY_MAX_FLOW); +} + +void Union::simulate() +{ + if (!updated) { + return; + } + + std::cout << name << "::Flujo actual = " << actual_flow << std::endl; + updated = false; +} + -- 2.43.0