Planet

FreeGemas

Hace unos pocos días comencé el proyecto FreeGemas, una versión open source del clásico Bejeweled escrita, cómo no, en C++ y Gosu.
Entre la noche del 7 y la mañana del 8 de julio tenía la parte del principal del motor andando. Creo que ha sido un gran ejercicio de diseño y desarrollo rápido, y espero seguir desarrollándolo. Huelga decir que todas las imágenes y recursos son libres. Ahora estoy en la búsqueda de sonidos libres, ¿sugerencias?.
En la web del proyecto podréis encontrar las instrucciones de instalación, que son casualmente similares a las de oFlute
Espero que os guste.

[Boost en español II] Bind y Function

Seguimos con la segunda entrega de esta serie de posts sobre Boost en español. En esta ocasión hablaremos de las bibliotecas Bind y Function, que nos facilitan el uso de objetos función, punteros a funciones y cosas parecidas.
Conceptos previos
Un objeto función es una instancia de una clase que tiene definido el operador (). Esto nos permite usar el objeto como si de una función se tratara:
struct Functor{
void operator()(){
cout << "Waking up in vegas" << endl;
}
};
int main(){
Functor F;
F();
}
El verdadero potencial de estos objetos radica en que permiten expandir de manera sencilla la mayoría de los algoritmos de la STL de C++, ya que suelen poder recibir objetos función que modifiquen su funcionamiento para adaptarlo a nuestras necesidades.
Por ejemplo, el algoritmo for_each, contenido en la cabecera algorithm, nos permite iterar sobre un contenedor y aplicar una función por cada elemento (for each element). En estos casos, es útil utilizar un objeto función como extensión al algoritmo:
#include <iostream>
#include <boost/array.hpp>
#include <algorithm>
using namespace std;
struct Botella{
string etiqueta;
Botella(string e) : etiqueta(e) { }
};
struct Impresor{
string destino;
int n;
Impresor(string d = "ERROR") : destino(d), n(0){ }
void operator() (Botella & B){
cout << destino << "(" << n++ << "): " << B.etiqueta << endl;
}
};
int main(int argc, char *argv[])
{
boost::array<Botella, 3> vector = { {Botella("Cruzcampo"),
Botella("San Miguel"),
Botella("Mahou") } };
Impresor I("DEBUG");
for_each(vector.begin(), vector.end(), I);
return 0;
}
En la STL hay un gran número de algoritmos que podemos usar. Para más información, recomiendo la lectura del punto 8, capítulo 7, del libre “Fundamentos de C++”, del Servicio de Publicaciones de la UCA.
La pega que tiene el uso de los objetos función en los algoritmos de la STL es que la sobrecarga del operador() debe tener un solo parámetro del tipo del contenedor, lo cual nos limita bastante.
Boost.Bind
Bind nos da la posibilidad de ligar los parámetros de una función o un objeto función a un valor concreto, o a otra posición. ¿Qué quiere decir esto? Si tenemos, por ejemplo, un objeto función que recibe dos parámetros y nos interesa que uno de ellos sea siempre el mismo, podemos usar bind. Notar que bind siempre devuelve un objeto función cuyo operador () estará ligado a la función original.
#include <iostream>
#include <algorithm>
#include <boost/array.hpp>
#include <boost/bind.hpp>
using namespace std;
struct Elemento{
int n;
Elemento(int n = 0) : n(n) { }
};
struct Comparador{
void operator() (int n, Elemento & E){
if(E.n > n)
cout << "HOYGAN, parece que este elemento (" << E.n
<< ") es mayor que " << n << endl;
}
};
int main(int argc, char *argv[])
{
boost::array<Elemento, 3> arr = {{Elemento(2),
Elemento(4),
Elemento(8)}};
for_each(arr.begin(), arr.end(),
boost::bind<void>(Comparador(), 3, _1));
return 0;
}
Si os fijáis, la sintaxis de bind es sencilla: Recibe un parámetro de plantilla que indica el tipo de dato de vuelto por la función ligada. Normalmente es capaz de deducir qué tipo de datos se devuelve, pero hay casos en los que es necesario indicarlo explícitamente.
Luego, recibe como argumentos la función u objeto función a ligar, y seguidamente los parámetros de ésta. Podemos indicar directamente el valor, o utilizar placeholders, que nos permiten ligar los parámetros de entrada con los de salida. En nuestro ejemplo, _1 que está en el segundo lugar indica que el segundo parámetro de la función será el primero que reciba bind.
La reorganización de parámetros se puede ver mejor con este otro ejemplo:
#include <iostream>
#include <algorithm>
#include <boost/bind.hpp>
using namespace std;
void fun (int A, int B){
cout << "A: " << A << endl
<< "B: " << B << endl;
}
int main(int argc, char *argv[])
{
boost::bind(fun, _2, _1) (1, 2);
return 0;
}
Boost.Function
En ocasiones nos interesará tener la función ligada como un objeto con el que trabajar, por ejemplo para poder recibirla como argumento de una función. Para esos casos, boost nos proporciona function. Se trata de una clase paramétrica cuyo operador () se sobrecargará para llamar a la función ligada.
class miClase{
public:
void hacerSuma(int a){
cout << "Hago una suma: " << a << endl;
}
void hacerResta(int a){
cout << "Hago una resta: " << a << endl;
}
};
int main(){
boost::function<void(miClase, int)> operacion;
if(1 == 0){
operacion = boost::bind(&miClase::hacerSuma, _1, _2);
}else{
operacion = boost::bind(&miClase::hacerResta, _1, _2);
}
miClase c;
operacion(c, 2);
}

PFC SIMOCAP 10 Matrícula de Honor

Pues ya presente el proyecto Simocap como Proyecto fin de carrera de Ingeniería Superior en Informática en mi Escuela, (Escuela Técnica Superior de Ingeniería Informática de la Universidad de Sevilla), y he recibido la clasificación de Sobresaliente 10 Matrícula de Honor,  además esto se une a la Mención Especial recibida en el Premio local de Sevilla del Concurso Universitario de Software Libre.
Dejo aquí el vídeo de una demostración de uso del software.
http://www.youtube.com/watch?v=DWw3AswAjVA
Y con esto voy a denener el desarrollo del proyecto hasta nuevo aviso.
La dirección de descarga del software y de la documentación es la siguiente:
https://forja.rediris.es/projects/cusl4-simocap/

Instalar pentaho como servicio UNIX

Bueno hace poco me pidieron instalar Pentaho como si fuera un servicio cosa que me pareció muy útil ahí dejo la receta seguramente la mayoría ya sepa como hacerlo pero para el resto ahí va:
bajamos Pentaho y aqui hay dos variantes o te generas el war y lo metes en ...

DataBases OpenSource ¿Cual?

Bueno ahora que MySQL esta en peligro y que nadie sabe como va a ser el futuro, todo el mundo busca una salida, además se une que ha habido un gran movimiento en las bases de datos se ha creado el movimiento NOSQL y se han creado distintas bases de ...

Sumidero en tu escritorio: RenderApplet

Siguiendo la veda iniciada en las dos entradas del blog anteriores, en esta entrada voy a presentaros RenderApplet.RenderApplet es un programa escrito en Python que utiliza el servicio MMDeviceCreator de negociación. El programa está escrito en forma de applet de escritorio para Gnome: al activarlo se registrará en el servicio de negociación y, a partir de ese momento, dicho servicio negociará en su nombre las conexiones AVStreams, pasándole a RenderApplet la cadena de conexión resultado de dicha negociación.La utilización como veis es bastante sencilla. Para poderlo probar sin necesidad de añadir el applet de escritorio también puede ejecutarse como aplicación "independiente" (aunque queda mucho peor :P).Al estar escrito en Python, el código fuente y el ejecutable es el mismo. Para obtenerlo, descargad mi repositorio con Mercurial:$ hg http://arco.esi.uclm.es/~josel.segura/pfcExplorar en el directorio pfc/software/src/RenderApplet/RenderApplet y encontraréis el código de la aplicación.Dos saboresComo he comentado anteriormente, el programa puede ejecutarse tanto como aplicación GTK normal y corriente y como applet de escritorio de Gnome.Si eliges utilizar esta segunda opción, deberás realizar, antes de instalar, una configuración para que Gnome sea capaz de encontrar el applet en la ruta de instalación. No instalo directamente en la ruta por defecto dónde lo encontraría por no ensuciar los directorios que gestiona muy bien tu sistema gestor de paquetes ;)Argos Render como appletSi te decides a instalarlo como applet, deberás realizar lo siguiente antes de instalar:

  1. Instala el programa bonobo-activation-sysconf. En sistemas Debian-based se encuentra en el paquete libbonobo2-bin.
  2. Ejecuta, como super-usuario, lo siguiente:

# bonobo-activation-sysconf --add-directory=/usr/local/lib/bonobo/serversDeberéis cambiar esta línea si habéis cambiado la ruta de instalación en el Makefile del prorgamaInstalandoPara instalar Argos Render Applet deberás ir, dentro del repositorio Mercurial, al directorio software/src/RenderApplet y ejecutar simplemente:$ make installEsto copiará todos los ficheros a sus rutas correspondientes.Haciendo que Gnome encuentre el appletSi vas a usar el applet deberás reiniciar el servicio de búsqueda de applets de Gnome para que busque los nuevos recién instalados y puedas añadirlos a los paneles. Para ello hay dos opciones:

  • Reiniciar la sesión de tu usuario
  • "Matar" los procesos "bonobo-activation-server" y "gnome-panel". Durante unos instantes desaparecerán todos tus paneles, pero a los pocos segundos volverán, tranquilo :)

Fichero de configuraciónComo aplicación Ice que se precie, lo habitual es pasarle los parámetros de funcionamiento (como el default locator o proxys que necesite utilizar la aplicación a través de un fichero de configuración. Si lanzamos la aplicación como programa (no como applet) tan solo deberemos pasarle cualquier opción en la forma habitual que Ice la "parsearía" (--Ice.Config=... --Ice.Default.Locator=...).Sin embargo, si se trata de un applet no podemos ejecutar y elegir que parámetros se le pasan al ser ejecutado, ya que esta ejecución la realizará el panel de Gnome. Por ello, el programa por defecto buscará en el directorio home del usuario un directorio que se llame .argos y, dentro de él, el fichero ice_config.Todas las aplicaciones de usuario que voy a desarrollar cogerán su configuración de ese fichero si no la encuentran entre los parámetros de ejecución, sí que sería recomendable que esté escrito desde ya con parámetros que puedan utilizar todos los programas. Un ejemplo mínimo sería el siguiente:Ice.Default.Locator=IceGrid/Locator -t:tcp -h peter -p 4061Argos.MMDeviceDeployer = MMDeviceCreator -t:tcp -h peter -p 15000Ejecución del programa

  • Ejecución como applet: Sobre alguno de los paneles de Gnome pulsamos con el botón derecho del ratón en una zona libre y seleccionamos la opción "Añadir al panel". Se abrirá una ventana dónde podremos encontrar el "Argos Media Render Applet". Lo seleccionamos y le damos a "Añadir" y debería aparecernos un círculo rojo en nuestro panel (el applet).
  • Ejecución como programa externo: vamos a la ruta del código fuente dónde está el programa o bien a la ruta de instalación (por defecto /usr/local/share/argos-render-applet) y ejecutar como un programa normal desde la terminal el fichero RenderApplet.py, pasándole como primer argumento la palabra "window". Aparecerá una nueva y pequeña ventana que incluye el mismo icono que podríamos ver en el panel si hubiéramos realizado la otra opción.

En ambos casos, una vez hecho esto, si pulsáis en el círculo rojo (o el icono que aparezca, depende del tema de iconos de Gnome) éste pasará a ser verde y significará que, si las configuraciones son correctas, el programa se ha comunicado con el MMDeviceCreator para que cree un MMDevice y el resto de elementos AVStreams necesarios para gestionar la configuración. Una forma de comprobar que todo ha ido bien es, en el programa icegrid-gui, conectar con el registry y observar los objetos bien conocidos: debería aparecer un nuevo objeto, de tipo ::AVStreams::MMDevice, llamado $USER_render (dónde $USER es el nombre de tu usuario en tu máquina).En la próxima entrada explicaré brevemente como utilizar un pequeño programa de configuración para poder conectar entre si un sumidero y una fuente multimedia, y poderle así dar un uso visual al applet.Hasta pronto :)

Usar el entorno abstract con la clase book de LaTeX

En la clase report de LaTeX podemos hacer lo siguiente: \begin{abstract} Este sería el abstract del documento. \keywords{Palabras,clave} \end{abstract} El entorno abstract viene muy bien para hacer el resumen del ...

Publicada la versi&oacute;n 0.1 del protocolo Kraken

La especificación del protocolo Kraken 0.1 ha sido publicada y está disponible para la descarga en http://groups.google.com/group/kraken-spec/web/protocolo.pdf Esta especificación está pendiente de ser revisada, aunque los cambios que puede sufrir ...

Dominous summer of code


Ahora que se acerca el verano hay que buscar formas más atractivas de enfrentarse al proyecto :-D
Hasta ahora el proyecto iba avanzando sin problemas, haciendo sesiones de desarrollo largas y divirtiéndome con los problemas que van apareciendo, diseñando la aplicación y disfrutando con los grandes cambios que iba sufriendo cada poco tiempo.
CUSL

MMDeviceCreator: instalación y puesta en marcha

Como comenté en mi entrada anterior (Servicio de negociación), he escrito un servicio IceBox que proporciona, a aquellos clientes que lo necesiten, toda la negociación que puedan necesitar para realizar conexiones AVStream.En este post detallaré como instalar dicho servicio y como ponerlo en marcha. Allá vamos.InstalaciónPara instalarlo, en entornos Debian, solo habrá que tener esta línea en el fichero /etc/apt/sources.listdeb http://babel.esi.uclm.es/gnesis/ unstable mainy realizar lo siguiente:# aptitude update# aptitude install libmmdevicecreatorPara el resto de entornos GNU/Linux, libmmdevicecreator.tar.gz: este fichero contiene tanto la librería (fichero .so) como dos ficheros, nombrados "config" y "config_MMDCS", que serán explicados en el siguiente punto.Puesta en marchaComo el resto de servicios implementados utilizando las ventajas de IceBox, para lanzarlo solamente hará falta escribir un par de ficheros de configuración: en uno de ellos, que será el que acepte el ejecutable de IceBox, se describirá como debe lanzarse el servicio (nombre de la librería, versión, orden en el caso de lanzarse varios servicios a la vez...). El otro fichero de configuración se le pasará al servicio propiamente dicho, y tendrá las variables que necesite para su ejecución. Estos ficheros se corresponden, respectivamente, con los que encontramos en el tarball.Para lanzar el servicio, lo primero, deberemos tener la librería en una ubicación bien conocida para el ejecutable de IceBox. En el caso del paquete Debian no habrá ningún problema, pero en el caso del tarball deberemos copiar el fichero .so a /usr/local/lib o bien hacer que la variable de entorno LD_LIBRARY_PATH contenga el directorio dónde se encuentre el fichero.El fichero "config" tiene tan solo la configuración del "Default Locator" de nuestro entorno y la configuración de carga de la librería:Ice.Default.Locator=IceGrid/Locator:tcp -h peter -p 4061IceBox.Service.MMDCS=MMDeviceCreator:createService --Ice.Config=config_MMDCSCon esa configuración definimos un servicio IceBox llamado "MMDCS", el cual intentará cargar la librería "libMMDeviceCreator" a través de su punto de entrada "createService", pasándole la configuración del fichero config_MMDCS.Este otro fichero es el que configura realmente el servicio, y además de la configuración del Default Locator, deberá incluir la configuración del endpoint para el MMDeviceCreatorAdapter, el proxy al PropertySetDefFactory, que nos proporciona el servicio de propiedades, y un par de variables Registry.username y Registry.password que contendrán, si los hubiera, el nombre de usuario y la password administrativa del Registry al que estamos conectados.Para lanzarlo:$ icebox --Ice.Config=configAl lanzarlo, obtendremos por la salida en el terminal algo como lo siguiente:[INFO] [MMDevice Creator] Starting service[INFO] [MMDevice Creator] PropertySetDefFactory proxy: PropertySetFactory -t @ AutoPropertyService.Adapter[INFO] Negotiator -t:tcp -h 192.168.1.2 -p 15000Esa última línea es la que los clientes deberán utiliazr para poder utilizar el servicio. Si se realizara un despliegue a a través de IceGrid, este ñultimo proxy sería un objeto bien conocido, por lo que el acceso para los clientes sería más sencillo aún.En la próxima entrada os contaré como utilizar el primer cliente que hice para este servicio: un sumidero que se activa a través de un applet de escritorio y que, por ahora, podréis probar con una cámara Axis, si es que la tenéis claro :P

Distribuir contenido