--- /dev/null
+<html>\r
+\r
+<head>\r
+<meta http-equiv="Content-Language" content="es-mx">\r
+\r
+<title>New Page 1</title>\r
+</head>\r
+\r
+<body>\r
+\r
+<h1>Trabajo práctico final</h1>\r
+<h1>Introducción</h1>\r
+<p>Diseñar un sistema destinado a la simulación y control de una planta química.</p>\r
+<p>El sistema consta de 3 aplicaciones independientes destinadas al diseño, \r
+simulación y control de la planta, respectivamente. Estas tres aplicaciones se \r
+explican a continuación:</p>\r
+<h1>1 - Diseño de la planta</h1>\r
+<p>Aplicación Windows, ya sea basada en un diálogo o SDI (Single Document \r
+Interface), destinada al diseño de la planta en forma gráfica.</p>\r
+<p>El sistema debe poder cargar y grabar el diseño de la planta en un archivo de \r
+texto.</p>\r
+<h2>Parte 1 - Modelo de la planta</h2>\r
+<p>El diseño de la planta debe incluir los siguientes elementos:</p>\r
+<ul>\r
+ <li>caños: horizontal, vertical. La longitud de los caños debe poder variarse</li>\r
+ <li>codos de caños, en todas las 8 direcciones posibles.</li>\r
+ <li>bifurcaciones de caños</li>\r
+ <li>uniones de caños</li>\r
+ <li>tanque</li>\r
+ <li>bomba (fuente)</li>\r
+ <li>drenaje (salida)</li>\r
+ <li>válvula</li>\r
+</ul>\r
+<p>El programa debe permitir insertar, borrar y mover cada uno de estos \r
+elementos.</p>\r
+<p>Algunos de estos elementos de la planta tendrán atributos y estados, tal como \r
+se detalla en la siguiente tabla:</p>\r
+<table border="1" cellpadding="0" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="100%" id="AutoNumber1">\r
+ <tr>\r
+ <td width="33%"><b><font size="4">Elemento</font></b></td>\r
+ <td width="33%"><b><font size="4">Atributos</font></b></td>\r
+ <td width="34%"><b><font size="4">Estados</font></b></td>\r
+ </tr>\r
+ <tr>\r
+ <td width="33%">caños</td>\r
+ <td width="33%">caudal máximo (litros / seg.)</td>\r
+ <td width="34%"> </td>\r
+ </tr>\r
+ <tr>\r
+ <td width="33%">codos</td>\r
+ <td width="33%"> </td>\r
+ <td width="34%"> </td>\r
+ </tr>\r
+ <tr>\r
+ <td width="33%">bifurcaciones</td>\r
+ <td width="33%"> </td>\r
+ <td width="34%"> </td>\r
+ </tr>\r
+ <tr>\r
+ <td width="33%">uniones</td>\r
+ <td width="33%"> </td>\r
+ <td width="34%"> </td>\r
+ </tr>\r
+ <tr>\r
+ <td width="33%">tanque</td>\r
+ <td width="33%">capacidad (en litros)</td>\r
+ <td width="34%">cantidad de litros en el tanque (valor real)</td>\r
+ </tr>\r
+ <tr>\r
+ <td width="33%">bomba</td>\r
+ <td width="33%">caudal máximo (litros / seg.). Color del líquido.</td>\r
+ <td width="34%">encendida/apagada (valor binario)</td>\r
+ </tr>\r
+ <tr>\r
+ <td width="33%">drenaje</td>\r
+ <td width="33%"> </td>\r
+ <td width="34%"> </td>\r
+ </tr>\r
+ <tr>\r
+ <td width="33%">válvula</td>\r
+ <td width="33%"> </td>\r
+ <td width="34%">abierta/cerrada (valor binario)</td>\r
+ </tr>\r
+</table>\r
+<p>Cada elemento del sistema deberá poder asociarse un atributo adicional que \r
+será el nombre del objeto</p>\r
+<p>A continuación se muestra como ejemplo el diseño de una planta.</p>\r
+<p><img border="0" src="TPf.ht1.gif" width="800" height="559"></p>\r
+<p>A continuación se muestra el despiece de la planta en los diferentes objetos \r
+que la componen.</p>\r
+<p><img border="0" src="TPf.ht2.gif" width="797" height="547"></p>\r
+<h2>Parte 2 - Sistema de control</h2>\r
+<p>Seleccionando alguna opción en la aplicación se debe pasar al diseño del \r
+sistema de control de la planta.</p>\r
+<p>En este modo, no se podrá modificar los objetos que componen la planta, sino \r
+que se mostrarán y permitirá modificar los elementos que determinan el control \r
+de la misma.</p>\r
+<p>Como se mencionó anteriormente, algunos objetos pueden tener estados \r
+asociados. El programa debe desplegar dos entradas, que permitan modificar dicho \r
+estado (abrir/cerrar) y <br>\r
+una salida que permita leer dicho estado. En el caso del tanque, sólo se tendrán \r
+2 salidas que indicarán si el contenido del mismo es superior/inferior a un \r
+porcentaje dado.<br>\r
+<br>\r
+Estas entradas y salidas deben poder conectarse utilizando un editor gráfico, y \r
+debe permitir agregar los símbolos binarios AND y OR, el símbolo unitario \r
+NEGADOR, un pulsador y un<br>\r
+temporizador, tal como se muestra en el diagrama.</p>\r
+<p><img border="0" src="TPf.ht3.gif" width="451" height="528"></p>\r
+<p><br>\r
+Esta lógica debe grabarse en el archivo con la descripción de la planta en \r
+formato texto, utilizando la nomenclatura que los alumnos prefieran.</p>\r
+<h1>2 - Simulación</h1>\r
+<p>Aplicación de consola, destinada a la simulación de la planta.</p>\r
+<p>El programa debe cargar una planta de un archivo de texto generada por la \r
+aplicación de diseño descripta anteriormente, simular el funcionamiento de la \r
+misma y comunicarse con el programa de control para permitir la visualización y \r
+control de la planta.</p>\r
+<p>Todos los parámetros requeridos por esta aplicación deben recibirse por línea \r
+de comandos.</p>\r
+<p>Esta aplicación debe constar de 2 partes o módulos.</p>\r
+<h2>Módulo Simulación</h2>\r
+<p>Debe simular el funcionamiento de la planta en base al modelo que se describe \r
+en el apéndice I</p>\r
+<h2>Servidor TCP/IP.</h2>\r
+<p>Debe implementar la comunicación con una o más aplicaciones de control de la \r
+planta.</p>\r
+<p>El protocolo utilizado para la comunicación debe ser en formato texto, y debe \r
+basarse en la filosofía web-services, que se describe a continuación:</p>\r
+<p>El cliente (aplicación de control) envía un requerimiento al servidor en \r
+formato texto (preferentemente XML). Estos requerimientos pueden interpretarse \r
+como llamadas a funciones, donde se pasa el nombre de la "funcion" a invocar y \r
+sus parámetros. </p>\r
+<p>El servidor responde con un texto (preferentemente en formato XML).</p>\r
+<p>Las funciones a implementar deben permitir:</p>\r
+<p>1 - Obtener una descripción de la planta</p>\r
+<p>2 - Obtener el estado de un elemento de la planta.</p>\r
+<p>3 - Modificar el estado de un elemento de la planta</p>\r
+<h1>3 - Aplicación de control.</h1>\r
+<p>Aplicación win32 similar a la descripta en el punto 1 y con similar interfaz \r
+gráfica. El programa no debe permitir modificar la planta, sino que debe mostrar \r
+el estado de la misma.</p>\r
+<p>Esta aplicación debe mostrar el estado de todos los elementos que componen la \r
+planta en forma gráfica, animando cada elemento para indicar los flujos de \r
+líquido, con el color correspondiente a cada líquido.</p>\r
+<p>Si la capacidad máxima de un tanque es superada, el programa debe emitir una \r
+alerta.</p>\r
+<p>El sistema deberá mostrar el contenido de los tanques con el color de los \r
+líquidos que lo llenaron.<br>\r
+ </p>\r
+<h1>Apéndice I - Modelo de simulación</h1>\r
+<p>La planta puede entenderse como un grafo dirigido, donde cada objeto \r
+representa un nodo del grafo y cada caño una arista. Si bien en un caño el \r
+líquido puede fluir en ambas direcciones,<br>\r
+simplificaremos el modelo suponiendo que el liquido fluye en una única \r
+dirección.<br>\r
+<br>\r
+Los objetos de la planta pueden dividirse en 3 tipos:</p>\r
+<p>1 - Fuentes. (ejemplo: bomba)<br>\r
+2 - Drenajes. (ejemplo: salida)<br>\r
+3 - Los restantes objetos (válvulas, bifurcaciones, uniones, etc) son \r
+idealizados suponiendo que no almacenan líquido.</p>\r
+<p>Un caso particular de dispositivo es el tanque, que constituye una fuente y \r
+drenaje al mismo tiempo.</p>\r
+<p>Para simular la planta, se analizan todos los flujos de liquido entre todas \r
+las fuentes y drenajes.</p>\r
+<p>Las bifurcaciones son simplificadas suponiendo que divide el flujo de líquido \r
+en dos.<br>\r
+Las uniones son simplificadas suponiendo que sólo aceptan el 50% del caudal \r
+posible de cada entrada.</p>\r
+<p>Si una válvula / bomba está cerrada, el programa debe considerar que dicha \r
+parte del grafo no está presente.<br>\r
+<br>\r
+Ejemplo:</p>\r
+<p>Tomando el diseño de la planta dado anteriormente, se lo dividirá en un \r
+grafo, tal como se muestra a continuación:</p>\r
+<p><img border="0" src="TPf.ht4.gif" width="827" height="571"></p>\r
+<p>El sistema deberá iterar n veces por segundo, determinando los caudales en \r
+cada arista del grafo. Una vez hecho esto se actualizará los contenidos de \r
+líquido en cada tanque en base a los caudales determinados.</p>\r
+<p>En primer lugar se determinan los posibles caminos fuente-drenaje:</p>\r
+<p>1 - 4<br>\r
+3 - 4<br>\r
+4 - 8<br>\r
+4 - 10<br>\r
+8 - 10<br>\r
+10 - 12</p>\r
+<p>Una vez hecho esto se determinará el caudal en cada arista, tal como se \r
+muestra a continuación:</p>\r
+<p><b>Flujo en arista 1<br>\r
+</b>Si la bomba 1 está apagada: 0<br>\r
+Si la bomba 1 está encendida y la 2 apagada:<br>\r
+mínimo entre:<br>\r
+* caudal max. entregado por la bomba<br>\r
+* caudal max. arista 1<br>\r
+* caudal máx. arista 3<br>\r
+Si la bomba 1 y 2 están encendidas:<br>\r
+* caudal max. entregado por la bomba<br>\r
+* caudal max. arista 1<br>\r
+* mitad del caudal máx. arista 3.<br>\r
+<br>\r
+<b>Flujo en arista 2<br>\r
+</b>Similar flujo en arista 1<br>\r
+<br>\r
+<b>Flujo en arista 3<br>\r
+</b>Suma de los flujos por las aristas 1 y 2<br>\r
+<br>\r
+<b>Flujo en arista 4<br>\r
+</b>Si la válvula 5 está cerrada, el flujo será 0.<br>\r
+En caso contrario:<br>\r
+Si la bomba 8 está apagada, el grafo se reduce y el flujo estará<br>\r
+dado por el mínimo caudal entre<br>\r
+* máximo caudal posible en arista 4<br>\r
+* máximo caudal posible en arista 5<br>\r
+* máximo caudal posible en arista 8 por dos, ya que sólo la mitad<br>\r
+del caudal se irá por esta arista.<br>\r
+* máximo caudal posible en arista 6 por dos, ya que sólo la mitad<br>\r
+del caudal se irá por esta arista.<br>\r
+* máximo caudal posible en arista 9 por dos.<br>\r
+<br>\r
+Si la bomba 8 está abierta, el análisis es similar solo que el <br>\r
+último flujo será directamente:<br>\r
+* máximo caudal posible en arista 9.<br>\r
+<br>\r
+<b>Flujo en arista 5<br>\r
+</b>Será idéntico al flujo por la arista 4<br>\r
+<br>\r
+<b>Flujo en arista 6<br>\r
+</b>Será la mitad del flujo en la arista 5<br>\r
+<br>\r
+<b>Flujo en arista 8<br>\r
+</b>Será la mitad del flujo en la arista 5<br>\r
+<br>\r
+<b>Flujo en arista 9<br>\r
+</b>Suma de los flujos en aristas 6 y 7<br>\r
+<br>\r
+Los restantes flujos pueden ser determinados por los alumnos.<br>\r
+<br>\r
+En este análisis no se tuvo en cuenta la existencia de líquido en un tanque. Si \r
+un tanque está vacío, debe considerarse que no hay flujo de líquido (válvula \r
+cerrada). Si un cuanto de flujo de líquido resulta ser superior al líquido \r
+existente en un tanque, dicho caudal deberá ser limitado al caudal existente.</p>\r
+<p>Una vez determinado el caudal en cada arista del grafo, el programa debe \r
+actualizar el contenido de todos los tanques.</p>\r
+<p>Tener en cuenta que cada bomba de la planta entrega líquidos de distinto tipo \r
+(color) lo cual deberá ser tenido en cuenta al actualizar los volúmenes de cada \r
+tanque, de tal forma que el color mostrado en el grafo sea proporcional (en \r
+forma aproximada) a la densidad de los líquidos entrantes.</p>\r
+<p>Por ejemplo:</p>\r
+<p>Si un tanque contiene 10 litros de líquido rojo (255,0,0) y recibe 10 litros \r
+de líquido de verde (0,255,0), el color resultante será:</p>\r
+<p>(255 * 90 / 100, 255 * 10 / 100, 0)</p>\r
+<p>Utilizar números double para minimizar errores de redondeo.</p>\r
+\r
+</body>\r
+\r
+</html>
\ No newline at end of file
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">\r
+<!-- saved from url=(0045)http://cscene.org/topics/misc/cs7-04.xml.html -->\r
+<HTML><HEAD><TITLE>Callbacks in C++: The OO Way</TITLE>\r
+<META content="text/html; charset=iso-8859-1" http-equiv=Content-Type><LINK \r
+href="default.css" rel=stylesheet \r
+type=text/css>\r
+<META content="MSHTML 5.00.2920.0" name=GENERATOR></HEAD>\r
+<BODY>\r
+<TABLE width="100%">\r
+ <TBODY>\r
+ <TR>\r
+ <TD><A href="http://cscene.org/"><IMG alt="cscene logo" border=0 \r
+ class=logo height=52 src="logo.gif" \r
+ width=120></A></TD>\r
+ <TD align=middle width="100%"><A \r
+ href="http://cscene.org/index.html">C-Scene</A> <A \r
+ href="http://cscene.org/issues.html">Issues 1..9</A> <A \r
+ href="http://cscene.org/bios.html">Authors</A> <BR><A \r
+ href="http://cscene.org/topics/algo.xml.html">Algorithms</A> <A \r
+ href="http://cscene.org/topics/books.xml.html">Books</A> <A \r
+ href="http://cscene.org/topics/patterns.xml.html">Patterns</A> <A \r
+ href="http://cscene.org/topics/graphics.xml.html">Graphics</A> <A \r
+ href="http://cscene.org/topics/misc.xml.html">Miscellaneous</A> <A \r
+ href="http://cscene.org/topics/unix.xml.html">UNIX</A> <A \r
+ href="http://cscene.org/topics/web.xml.html">Web & XML</A> <A \r
+ href="http://cscene.org/topics/windows.xml.html">Windows</A> <BR><A \r
+ href="http://cscene.org/feedback.html">Feedback</A> <A \r
+ href="http://cscene.org/faqs.html">FAQs</A> <A \r
+ href="http://cscene.org/changes.html">Changes</A> <A \r
+ href="http://cscene.org/submit.html">Submissions</A> </TD>\r
+ <TD>\r
+ <FORM action=http://www.google.com/search method=get><INPUT name=hl \r
+ type=hidden value=en><INPUT name=safe type=hidden value=off><INPUT \r
+ name=domains type=hidden value=cscene.org><INPUT name=sitesearch \r
+ type=hidden value=cscene.org><INPUT maxLength=256 name=q size=31><INPUT name=btnG type=submit value=Search></FORM></TD></TR></TBODY></TABLE>\r
+<H1 class=s1>Callbacks in C++: The OO Way</H1>\r
+<DIV class=toc>\r
+<H2 class=s2 id=N1698364>Content</H2>\r
+<OL>\r
+ <LI><A href="http://cscene.org/topics/misc/cs7-04.xml.html#N7895983">What are \r
+ Callbacks?</A>\r
+ <LI><A href="http://cscene.org/topics/misc/cs7-04.xml.html#N310499">A simple \r
+ Thread class</A>\r
+ <LI><A href="http://cscene.org/topics/misc/cs7-04.xml.html#N7751758">Thread \r
+ implementation</A>\r
+ <LI><A href="http://cscene.org/topics/misc/cs7-04.xml.html#N3038356">A real \r
+ Thread class</A></LI></OL></DIV>\r
+<DIV class=article>\r
+<P>by <I>Jürgen Hermann</I><BR>last updated <I>2001/08/02</I> (version \r
+<I>1.1.1.1</I>)<BR>also available as <A \r
+href="http://cscene.org/topics/misc/cs7-04.xml.txt">XML</A></P>\r
+<DIV class=s2>\r
+<H2 class=s2 id=N7895983>What are Callbacks?</H2>\r
+<P>Many operating systems and other subsystems (like GUI libraries) feature a \r
+special type of hook into those systems, named callbacks or callback functions. \r
+Upon initialization or by calling an API function you pass pointers to the \r
+callback into the subsystem, for later use. The problem with those functions is, \r
+since these subsystems are nowadays not yet OO, that they have no notion of what \r
+an object is. So if you want to have a <EM>callback object </EM> instead of \r
+a mere function, some OO magic is called for.</P>\r
+<P>As an example, consider the <CODE>BeginThread</CODE> API that many OSes have \r
+in a quite similar form; we assume that it takes a pointer to the function that \r
+provides the actual code for the newly created thread plus a <EM>data \r
+pointer </EM> that is passed to that function as a startup parameter. Thus, \r
+we end up with <CODE>BeginThread (void (*thread_func) (void*), void* \r
+startup_data)</CODE>. Now let's make a <CODE>Thread</CODE> class of \r
+that.</P></DIV>\r
+<DIV class=s2>\r
+<H2 class=s2 id=N310499>A simple Thread class</H2>\r
+<P>What we want to have is an ABC (abstract base class) that you can inherit \r
+from, creating specialized thread classes and in turn thread objects (i.e. \r
+actual threads). The code of the thread is located in a <EM>pure \r
+virtual </EM> function <CODE>code</CODE> that is provided by the inherited \r
+class. <CODE>code</CODE> is then similar to the <CODE>thread_func</CODE> \r
+parameter of the <CODE>BeginThread</CODE> call, but is a full-blown member \r
+function, not just a C function. So, we get this interface for the \r
+<CODE>Thread</CODE> class:</P><PRE class=source>class Thread {\r
+public:\r
+ virtual ~Thread();\r
+ void run();\r
+\r
+protected:\r
+ Thread();\r
+ virtual void code() = 0;\r
+\r
+private:\r
+ int running;\r
+\r
+ static void dispatch(void* thread_obj);\r
+};\r
+</PRE>\r
+<P>This might seem quite unusual to you (like having a protected constructor), \r
+but things will be explained in due course.</P></DIV>\r
+<DIV class=s2>\r
+<H2 class=s2 id=N7751758>Thread implementation</H2>\r
+<P>When we put the thread concept into a class, we have to consider lifetime. A \r
+thread exists as long as the thread function does not return, thus the object \r
+has to have the same lifetime. Because of this, an <CODE>auto</CODE> thread \r
+object does not make much sense; we insure that every thread object exists on \r
+the heap by making the ctor protected and providing a static factory method \r
+<CODE>create</CODE> for thread objects in each derived class:</P><PRE class=source>Thread::Thread() \r
+ : running(0) \r
+{\r
+}\r
+\r
+DerivedThread& DerivedThread::create()\r
+{\r
+ return *new DerivedThread;\r
+}\r
+</PRE>\r
+<P><CODE>create</CODE> has to be added to every inherited class, returning an \r
+object of that class.</P>\r
+<P>Next, we need a <CODE>run</CODE> method that actually starts the thread. This \r
+can't be done in the ctor: when <CODE>code</CODE> would be registered as a \r
+thread of execution in the <EM>base class </EM> ctor, the superclass would \r
+not yet be fully created and calling <CODE>code</CODE> would be quite invalid \r
+and dangerous. <CODE>run</CODE> does its job by registering the \r
+<CODE>dispatch</CODE> function as a thread, giving that thread the object \r
+pointer as a startup parameter; since <CODE>dispatch</CODE> is static, it has a \r
+prototype that matches the <CODE>void(*)(void*)</CODE> parameter of \r
+<CODE>BeginThread</CODE>.</P><PRE class=source>void Thread::run()\r
+{\r
+ // Don't start two threads on the same object\r
+ if (running) return;\r
+\r
+ // Create an OS thread, using the static callback\r
+ BeginThread(Thread::dispatch, this);\r
+ running = 1;\r
+}\r
+</PRE>\r
+<P>So finally, <CODE>dispatch</CODE> is called and performs the step from a \r
+procedural callback to the callback object:</P><PRE class=source>void Thread::dispatch(void* thread_obj)\r
+{\r
+ // Call the actual OO thread code\r
+ ((Thread*)thread_obj)->code();\r
+\r
+ // After code() returns, kill the thread object\r
+ delete (Thread*)thread_obj;\r
+}\r
+</PRE></DIV>\r
+<DIV class=s2>\r
+<H2 class=s2 id=N3038356>A real Thread class</H2>\r
+<P>A real-world thread class has to consider a few things we have ignored here. \r
+These things include: </P>\r
+<OL class=userlist>\r
+ <LI>more access to the thread data, like a method giving the thread ID. \r
+ <LI>a method for killing the thread, including the deletion of the thread \r
+ object. </LI></OL>\r
+<P>Developed and tested on Windows NT, this is the <A \r
+href="http://cscene.org/archives/callback.cpp.txt">source</A> for a little \r
+example program that implements the above in the real world. If you run it, you \r
+get something similar to the following output:</P><PRE class=source>[\cscene\callback]callback\r
+Started thread #80 for dice1\r
+Started thread #84 for dice2\r
+dice1 rolled 1\r
+dice2 rolled 1\r
+dice2 rolled 3\r
+dice1 rolled 1\r
+dice2 rolled 4\r
+dice1 rolled 6\r
+dice1 rolled 3\r
+dice2 rolled 3\r
+dice1 rolled 1\r
+dice1 rolled 4\r
+dice2 rolled 4\r
+dice2 rolled 3\r
+dice1 rolled 1\r
+dice2 rolled 6\r
+dice1 rolled 2\r
+dice2 rolled 2\r
+dice1 rolled 1\r
+dice2 rolled 4\r
+dice2 rolled 1\r
+dice1 rolled 4\r
+dice1 rolled 5\r
+dice2 rolled 1\r
+dice1 rolled 3\r
+dice2 rolled 3\r
+dice1 rolled 2\r
+dice1 rolled 6\r
+dice2 rolled 2\r
+dice1 rolled 1\r
+dice2 rolled 3\r
+dice1 rolled 4\r
+dice1 rolled 5\r
+dice2 rolled 3\r
+dice2 rolled 6\r
+dice1 rolled 4\r
+</PRE>\r
+<P>Have fun!</P></DIV>\r
+<P><SMALL><EM>This article is Copyright © 1997-98 by Jürgen Hermann<BR>and \r
+Copyright © 1999 by C-Scene. All Rights Reserved. </EM></SMALL></P></DIV>\r
+<DIV class=lastwords>\r
+<HR>\r
+Copyright © 1997-2000 by C-Scene. All Rights Reserved.<BR><BR>Part of the \r
+graphics and stylesheets used to generate this site are<BR>Copyright © 1999-2000 \r
+by Apache Software Foundation. </DIV></BODY></HTML>\r