}
nodo = nodo->next;
}
- std::cout << "AAACCCCAA : " << tmp << std::endl;
return tmp == "true";
}
* sí para determinar cual es el flujo que manejan en una iteración.
*/
virtual void update(int dir=OUT) = 0;
+
+ /** Actualiza el color de fluido */
+ virtual void update_color();
+
/** Hace la simulación de esta iteración
*
* Por simulacion se entiende que el modelo debe avisar a las vistas
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_QUERY_COLOR,
+ MSG_RESPONSE_COLOR,
MSG_LAST
};
RGB fluid_color;
// es de solo lectura
std::string name;
- bool updated;
+ bool updated, color_updated;
float actual_flow;
private:
// Hago que no se puedan copiar objetos ElementosPlanta
protected:
int in_on_zero;
int in_ready;
+ int in_colors;
+ RGB color1, color2;
+ float flow1, flow2;
private:
Union(const Union &):Transport("null") {}
Union &operator = (const Union &) { return *this; }
{
// Si ya me actualice, no lo tengo que hacer de nuevo
if (updated) {
- std::list<IConector *>::iterator i = in_list.begin();
- if (i != in_list.end()) {
- PlantItem *o = (PlantItem *)(*i);
- set_color( o->get_color() );
- }
return;
}
// Seteo mi actualizar en true para evitar entrar de nuevo
- actual_flow = 99999;
updated = true;
actual_flow = max_flow;
send_msg(OUT, MSG_QUERY_MAX_FLOW_OUT, (void *)&actual_flow);
std::cout << name << "::Flujo actual = " << actual_flow << " de " << max_flow << std::endl;
#endif
updated = false;
+ color_updated = false;
}
void Drainage::simulate()
{
- std::list<IConector *>::iterator i = in_list.begin();
- if (i != in_list.end()) {
- PlantItem *o = (PlantItem *)(*i);
- set_color( o->get_color() );
- }
#ifdef DEBUG
std::cout << name << "::Flujo recibido = " << actual_flow << std::endl;
#endif
updated = false;
+ color_updated = false;
actual_flow = 0;
}
void Exclusa::update(int dir)
{
- std::list<IConector *>::iterator i = in_list.begin();
- if (i != in_list.end()) {
- PlantItem *o = (PlantItem *)(*i);
- set_color( o->get_color() );
- }
// Primero me fijo si la entrada esta operando, es decir
// si hay alguien conectado para automatizar.
if (input->is_operational()) {
#ifdef DEBUG
std::cout << name << ": " << ((is_open)?"Abierta":"Cerrada") << std::endl;
#endif
+
+ updated = false;
+ color_updated = false;
}
void Exclusa::recieve_msg(int msg, IConector *who, void *data)
}
i++;
sim->simulate();
- std::cout << sim->get_state_as_xml() << std::endl << std::endl;
+ //std::cout << sim->get_state_as_xml() << std::endl << std::endl;
}
delete sim;
-
#include "plantitem.h"
+#include <iostream>
using namespace PlaQui::Model;
name = _name;
updated = false;
fluid_color = RGB(255,255,255);
+ color_updated = false;
}
PlantItem::PlantItem(unsigned ins, unsigned outs):IConector(ins, outs)
// TODO
return;
break;
+ case MSG_QUERY_COLOR:
+ if (color_updated) {
+ who->recieve_msg(MSG_RESPONSE_COLOR, this, &fluid_color);
+ }
+ update_color();
+ who->recieve_msg(MSG_RESPONSE_COLOR, this, &fluid_color);
+ break;
+ case MSG_RESPONSE_COLOR:
+ {
+ RGB *c = ((RGB *)data);
+ set_color(*c);
+ }
+ break;
default:
IConector::recieve_msg(msg, who, data);
}
}
+void PlantItem::update_color()
+{
+ if (color_updated) return;
+
+ send_msg(IConector::IN, MSG_QUERY_COLOR);
+ color_updated = true;
+}
+
void PlantItem::get_state_as_xml(std::stringstream &out)
{
out << "\t<float name=\"" << name << "\">" << std::endl;
input = new ByPass();
output = new ByPass();
((ByPass *)output)->set_control(this);
+ /* El color de la bomba siempre esta actualizado */
+ color_updated = true;
}
Pump::~Pump()
if (updated) return;
// Me fijo si me tengo que apagar automaticamente
open = input->get_output();
- std::cout << name << " open = " << (open?"true":"false") << std::endl;
if (active && open)
actual_flow = max_flow;
else
std::cout << ((active && open)?" (funcionando)":" (apagada)") << std::endl;
#endif
updated = false;
+ color_updated = true;
}
bool Pump::get_output()
if (tmp < actual_flow) actual_flow = tmp;
}
break;
+ case MSG_RESPONSE_COLOR:
+ /* Por las dudas, la bomba no debe cambiar de color */
+ ;
+ break;
default:
Source::recieve_msg(msg, who, data);
}
(*i1)->update();
std::list<PlantItem *>::iterator i2;
- for(i2=items.begin(); i2!=items.end(); i2++)
+ for(i2=items.begin(); i2!=items.end(); i2++) {
(*i2)->update();
+ (*i2)->update_color();
+ }
for(i2=items.begin(); i2!=items.end(); i2++)
(*i2)->simulate();
// bien, es a la entrada!, obtengo el item al cual lo tengo que conectar
to_connect = find((char *)XML_GET_CONTENT(conector3->children));
// y lo conecto
- if (!current_item->connect(to_connect, IConector::IN)) {
- std::cout << s << " Error al conectar " << std::endl;
- }
+ current_item->connect(to_connect, IConector::IN);
} else if (xmlStrcmp(conector3->name, BAD_CAST"salida") == 0) {
// Era a salida, es casi lo mismo que arriba
to_connect = find((char *)XML_GET_CONTENT(conector3->children));
- if (!current_item->connect(to_connect, IConector::OUT)) {
- std::cout << s << " Error al conectar " << std::endl;
- }
+ current_item->connect(to_connect, IConector::OUT);
}
}
nodo = nodo->next;
return;
}
- std::list<IConector *>::iterator i = in_list.begin();
- if (i != in_list.end()) {
- PlantItem *o = (PlantItem *)(*i);
- set_color( o->get_color() );
- }
#ifdef DEBUG
std::cout << name << "::Flujo actual = " << actual_flow << std::endl;
#endif
updated = false;
+ color_updated = false;
}
void Tank::simulate()
{
if (!updated) return;
- RGB in_color;
-
- std::list<IConector *>::iterator i = in_list.begin();
- if (i != in_list.end()) {
- PlantItem *o = (PlantItem *)(*i);
- in_color = o->get_color();
- }
// le sumo lo que recibo
litros += actual_in_flow;
// calculo el nuevo color
- int r, g, b;
- float l = litros;
-
- r = (int)(fluid_color.r()*litros/l + in_color.r()*actual_in_flow/l);
- g = (int)(fluid_color.g()*litros/l + in_color.g()*actual_in_flow/l);
- b = (int)(fluid_color.b()*litros/l + in_color.b()*actual_in_flow/l);
-
- if (r>255) r = 255;
- if (g>255) g = 255;
- if (b>255) b = 255;
- fluid_color = RGB(r,g,b);
// le resto lo que entrego
litros -= actual_out_flow;
std::cout << " Litros : " << litros << std::endl;
#endif
updated = false;
+ color_updated = false;
}
void Tank::recieve_msg(int msg, IConector *who, void *data)
if (*((float *)data) < actual_out_flow)
actual_out_flow = *((float *)data);
}
+ break;
+ case MSG_RESPONSE_COLOR:
+ RGB c = *((RGB *)data);
+ PlantItem *ic = static_cast<PlantItem *>(*(in_list.begin()));
+ int r,g,b;
+ float total = litros + ic->get_actual_flow();
+
+ r = (int)(get_color().r()*litros/total + c.r()*ic->get_actual_flow()/total);
+ g = (int)(get_color().g()*litros/total + c.g()*ic->get_actual_flow()/total);
+ b = (int)(get_color().b()*litros/total + c.b()*ic->get_actual_flow()/total);
+ r %= 256;
+ g %= 256;
+ b %= 256;
+ set_color(RGB(r,g,b));
}
}
float tmp;
if (updated) {
- who->recieve_msg(MSG_RESPONSE_MAX_FLOW, this, &actual_flow);
+ float tmp = actual_flow/2.0f;
+ who->recieve_msg(MSG_RESPONSE_MAX_FLOW, this, &tmp);
break;
}
updated = true;
}
}
break;
+ case MSG_RESPONSE_COLOR:
+ if (in_colors == 0) {
+ color1 = *((RGB *)data);
+ flow1 = static_cast<PlantItem *>(who)->get_actual_flow();
+ in_colors++;
+ } else {
+ color2 = *((RGB *)data);
+ flow2 = static_cast<PlantItem *>(who)->get_actual_flow();
+
+ /* Ya tengo mis 2 colores, los sumo */
+ int r,g,b;
+ int n=2;
+ if (flow1 == 0) n--;
+ if (flow2 == 0) n--;
+ float suma = flow1+flow2;
+ if (n != 0) {
+ r = (int)(color1.r()*flow1/suma + color2.r()*flow2/suma)/n;
+ g = (int)(color1.g()*flow1/suma + color2.g()*flow2/suma)/n;
+ b = (int)(color1.b()*flow1/suma + color2.b()*flow2/suma)/n;
+ r %= 256;
+ g %= 256;
+ b %= 256;
+ set_color(RGB(r,g,b));
+ } else {
+ set_color(RGB(0,0,0));
+ }
+ color_updated = true;
+ }
+ break;
default:
Transport::recieve_msg(msg, who, data);
}
void Union::update(int dir)
{
// Si ya me actualice, no lo tengo que hacer de nuevo
- RGB c_in1, c_in2;
- unsigned r=0,g=0,b=0;
- float c_f1, c_f2; // para ver los flujos de cada uno
-
- if (updated) {
- std::list<IConector *>::iterator i = in_list.begin();
- if (i != in_list.end()) {
- PlantItem *o = (PlantItem *)(*i);
- c_in1 = o->get_color();
- c_f1 = o->get_actual_flow();
- i++;
- o = (PlantItem *)(*i);
- c_in2 = o->get_color();
- c_f2 = o->get_actual_flow();
- }
-
- set_color( RGB(r,g,b) );
- if ((c_f1 != 0) && (c_f2 != 0)) {
- // Si ambas entradas traen flujo, sumo sus colores
- int total = c_f1+c_f2;
- r = ((int)((c_in1.r()*c_f1/total+c_in2.r()*c_f2/total)))%256;
- g = ((int)((c_in1.g()*c_f1/total+c_in2.g()*c_f2/total)))%256;
- b = ((int)((c_in1.b()*c_f1/total+c_in2.b()*c_f2/total)))%256;
- set_color(RGB(r,g,b));
- } else {
- // Veo que entrada trae color
- if (c_f1 != 0) {
- set_color( c_in1 );
- }
- if (c_f2 != 0) {
- set_color( c_in2 );
- }
- }
- return;
- }
+ if (updated) return;
+
// Seteo mi actualizar en true para evitar entrar de nuevo
// FIXME : 99999 == INFINITO!!
actual_flow = 99999;
std::cout << name << "::Flujo actual = " << actual_flow << std::endl;
#endif
updated = false;
+ color_updated = false;
in_on_zero = 0;
in_ready = 0;
+ color_updated = false;
+ in_colors = 0;
}