Implementando la carga dinámica de clases en Processing

Introducción

La carga dinámica de clases es una característica muy conocida de los lenguajes orientados a objetos que permite crear instancias de clases con solo conocer su nombre.  Esto permite a los desarrolladores crear aplicaciones que utilicen clases que sean creadas después de la aplicación sin necesidad de recompilar la misma.  También es muy útil cuando se desea generalizar la creación de un conjunto de objetos mediante el patrón de fábrica.

Gracias a la reflexión en Java y otros lenguajes como C# es muy fácil de implementar, sin embargo en Processing (derivado de Java) su implementación fue un poco mas elaborada ya que las clases que implementa el usuario son en realidad clases internas del proyecto desarrollado.

Explicación

En Processing cuando se crea un Proyecto y en él se implementan las clases A, B y C, y este se compila, internamente se crea un archivo de código fuente Java conteniendo a este código de la siguiente manera.

import processing.core.*;

// Imports del usuario

// Otros imports

public class Proyecto extends PApplet {

    class A
    {
        // ...
    }

    class B
    {
        // ...
    }

    class C
    {
        // ...
    }

    static public void main(String args[]) {
        PApplet.main(new String[] { "--bgcolor=#DFDFDF", "Proyecto" });
    }
}

Implementación

Para realizar la implementación de una versión simple del patrón de fábrica utilizando la carga dinámica de clases en Processing se supondrá que existe la clase Padre de la cual se derivan las clases Hijo1 e Hijo2 del proyecto Demostracion.

Crear un objeto donde se almacenará la instancia a crearse de manera dinámica.

Padre instance = null;

Recuperar la referencia al cargador de clases del sistema.

ClassLoader classLoader = ClassLoader.getSystemClassLoader();

Cargar la referencia de la clase a partir de su nombre (className), en este caso podría ser Hijo1 o Hijo2.  Recuerde que esta clase es realmente interna a la clase Demostracion.

Class loadedClass = classLoader.loadClass("Demostracion$" + className);

Obtener una referencia al constructor que se desea utilizar para crear la instancia.  En este caso se eligió un constructor que recibe dos parámetros: una cadena y un real.  Nótese además que todos los constructores reciben una referencia al applet de Processing, en este caso de Demostracion (que hereda a su vez de PApplet).

java.lang.reflect.Constructor constructor = loadedClass.getConstructor(new Class[] {PApplet.class, String.class, float.class});

Crear la nueva instancia utilizando el constructor obtenido en el paso anterior.  Al método newInstance se le especifican los valores de los parámetros que serán suplidos en el constructor.

instance = (Padre) constructor.newInstance(new Object[] {applet, str, flt});

Nótese como el primero de ellos, applet, hace referencia al applet de Processing que se está ejecutando.  Al no encontrar una forma mas elegante para obtener esta referencia al applet, declarar una variable global para almacenarlo.

PApplet applet;

Y obtener su valor en el procedimiento setup.

void setup()
{
    // ...

    applet = this;

    // ...
}

En el código mostrado anteriormente se deberán manejar las excepciones ClassNotFoundException y ClassCastException para poder llevar a feliz término su ejecución.

Enlaces

Construcción de la librería Simple-OpenNI para Processing bajo Ubuntu de 32 bits

Introducción

Simple-OpenNI es una librería de Processing que actúa como un recubrimiento (wrapper) para utilizar fácilmente OpenNI desde este lenguaje de programación.

La distribución binaria de esta librería puede ser descargada directamente desde el sitio web del proyecto.  En el presente artículo se describirán los pasos necesarios para construír esta librería a partir de su distribución de fuentes lo cual resulta interesante para garantizar compatibilidad con las versiones de las librerías nativas instaladas y mantener la última versión disponible, así como utilizar arquitecturas cuyas distribuciones binarias no se encuentren disponibles.

Prerequisitos

Para poder construír la librería bajo GNU/Linux Ubuntu es necesario contar con los siguientes requisitos previamente instalados.

  1. OpenNI y NITE
  2. Java Development Kit.
    $ sudo aptitude install openjdk-6-jdk openjdk-6-jre openjdk-6-jre-headless openjdk-6-jre-lib
    Activar la versión recién instalada: /usr/lib/jvm/java-6-openjdk/jre/bin/java
    $ sudo update-alternatives –config java
  3. CMake
    $ sudo aptitude install cmake
  4. Swig >= v2.0.2
    $ sudo aptitude install swig
  5. Eigen >= v3.0
    $ sudo aptitude install libeigen3-dev
  6. Boost >= v1.46 (use the static build)
    $ sudo aptitude install libboost-all-dev

Procedimiento

Obtener la última versión del código fuente de la librería.

$ svn checkout http://simple-openni.googlecode.com/svn/trunk/ simple-openni-read-only

$ cd simple-openni-read-only/SimpleOpenNI/

Ajustar el script de construcción modificando la invocación a cmake de la siguiente manera.  (Ajustar las rutas que se consideren convenientes, en especial a DP5_JAR)

$ vi buildLinux32.sh

(actualizar)

cmake -DOPEN_NI_INCLUDE=/usr/include/ni/
      -DXN_NITE_INCLUDE=/usr/include/nite/
      -DXN_NITE_LIB=/usr/lib/
      -DEIGEN3D_INCLUDE=/usr/include/eigen3/
      -DP5_JAR=~/Processing/2.0a4/lib/core.jar
      -JAVA_INCLUDE_PATH=/usr/lib/jvm/java-6-openjdk/include/
      -JAVA_INCLUDE_PATH2=/usr/lib/jvm/java-6-openjdk/include/linux
      ..

Realizar la construcción de la librería.

$ ./buildLinux32.sh

Instalar la librería recién construída.

$ ./installLinux.sh

Verificar la instalación de la librería

El procedimiento anterior construye e instala la librería de Simple-OpenNI bajo ~/sketchbook/libraries/SimpleOpenNI/ dejándola lista para ser utilizada con Processing.

$ tree -d ~/sketchbook/libraries/SimpleOpenNI/

/home/jimezam/sketchbook/libraries/SimpleOpenNI/
├── documentation
│   ├── resources
│   └── SimpleOpenNI
├── examples
│   ├── eclipse
│   ├── Nite
│   │   ├── CircleCtrl
│   │   ├── Hands
│   │   └── Slider2d
│   └── OpenNI
│       ├── AlternativeViewpoint3d
│       ├── DepthImage
│       ├── DepthImageXml
│       │   └── data
│       ├── DepthInfrared
│       ├── DepthMap3d
│       ├── Hands3d
│       ├── MultiCam
│       ├── RecorderPlay
│       ├── Scene
│       ├── SceneDepth
│       ├── Threaded
│       ├── User
│       ├── User3d
│       ├── User3dCallback
│       ├── UserSaveCalib
│       └── UserScene3d
└── library

Enlaces

Instalar Java (de Oracle) en GNU/Linux CentOS 6

Introducción.

A continuación se describe el procedimiento necesario para instalar el ambiente de desarrollo (JDK) de Java desarrollado por Oracle en GNU/Linux CentOS 6.  Este procedimiento probablemente funcione con GNU/Linux Fedora.

Instalación.

Descargar la última versión en RPM disponible en la siguiente ubicación.

# wget -o s1 -b -c http://download.oracle.com/otn-pub/java/jdk/7/jdk-7-linux-i586.rpm

# rpm -i jdk-7-linux-i586.rpm

Si se cuenta con otras versiones de Java (OpenJDK por ejemplo) deberá ajustar la versión por defecto que utilizará el sistema operativo.  Es posible que deba ajustar el índice (2 en el ejemplo) de la versión que se está instalando.

# alternatives –install /usr/bin/java java /usr/java/jdk1.7.0/bin/java 2

# alternatives –config java

Verificación.

Para verificar el funcionamiento de la versión de Java recién instalada, abra una consola y ejecute los siguientes comandos.

# java -version

java version “1.7.0”Java(TM) SE Runtime Environment (build 1.7.0-b147)
Java HotSpot(TM) Server VM (build 21.0-b17, mixed mode)

# javac -version
 
javac 1.7.0

Problemas para reproducir sonidos en Processing con Minim bajo Ubuntu 10.10

Introducción.

Minim parece ser una muy buena librería para la reproducción y manipulación de archivos de audio utilizando a Processing como lenguaje de desarrollo.

Experimentando con esta librería intentaba reproducir dos sonidos provenientes de dos archivos WAV diferentes, sin embargo siempre obtenía el siguiente mensaje de error a pesar de que cuando lo intentaba con uno sólo funcionaba correctamente.

JavaSound Minim error
==== Couldn’t open the line: line with format PCM_SIGNED 44100.0 Hz, 16 bit, mono, 2 bytes/frame, little-endian not supported. ====

Este problema me sucedía tanto al utilizar AudioSample como con AudioSnippet.

Solución.

Aparentemente el problema está relacionado con la plataforma Ubuntu ya que esta apuesta por OpenJDK como máquina virtual de Java por encima de la distribución oficial de Oracle (sun-java6) y por este motivo desafortunadamente olvidaron agregarle el soporte para el sistema PulseAudio que utiliza por defecto esta distribución.

La solución propuesta en los foros es copiar los archivos necesarios desde los directorios de OpenJDK a sus equivalentes de SunJava6.  En mi caso que utilizo exclusivamente la última versión fue necesario que instalara temporalmente el paquete openjdk-6-jre-lib, copiara los siguientes archivos y lo desinstalara nuevamente.

$ sudo cp /usr/lib/jvm/java-6-openjdk/jre/lib/[ARCH]/libpulse-java.so /usr/lib/jvm/java-6-sun/jre/lib/[ARCH]/

$ sudo cp /usr/lib/jvm/java-6-openjdk/jre/lib/ext/pulse-java.jar /usr/lib/jvm/java-6-sun/jre/lib/ext/

Se debe tener cuidado al reemplazar la subcadena [ARCH] contenida en la primera instrucción a ejecutar con la correspondiente plataforma instalada realmente, ya sea de 32 bits (será entonces i386) o de 64 bits (amd64).  La ejecución del comando uname -m debería brindar información suficiente al respecto.

Enlaces.

Charla introducción a Processing en 2010/09

La semana anterior tuve una charla con algunos ingenieros de sistemas de la ciudad de Armenia (Quindío) en la cual los introduje al lenguaje de programación Processing.

La charla se dividió en dos sesiones cortas cuya finalidad era explicar el lenguaje desde la perspectiva de los usuarios (para qué sirve) como desde la perspectiva de los desarrolladores (cómo se usa).  En la primera sesión se trataron las siguientes preguntas básicas.

  1. Qué es ?
  2. Qué se puede hacer con él ?
  3. Cómo se obtiene ?
  4. Cómo se instala ?
  5. Cómo es su ambiente de desarrollo ?
  6. Hola Mundo Processing.
  7. Cómo se exporta el sketch ?

Para esto preparé una presentación estilo documento muy resumido con la información mas importante del lenguaje y vínculos para ampliar estos conocimientos.

En la segunda sesión de la charla se realizó una rápida introducción al API del lenguaje de programación y se realizó paso a paso un ejemplo práctico básico para ejemplificar parte de la funcionalidad mas utilizada del lenguaje: el sketch Laberinto.

Ejemplo práctico de demostración del lenguaje Processing

El ejemplo práctico quedó documentado en dos versiones: una versión procedimental que es mas simple, fácil de entender pero menos elegante y una versión orientada a objetos un poco mas elaborada, ambas con la misma funcionalidad.

El applet del laberinto puede ser accedido mediante el siguiente enlace.

http://demo.jorgeivanmeza.com/Processing/Laberinto/0.1/applet/

Las teclas que deben utilizarse en el sketch son las siguientes.

  • Flechas del cursor: mover al jugador.
  • R: reiniciar el juego.
  • Espacio: teletransportar al jugador.

El código fuente del sketch, tanto de la versión prcedimiental como el de la orientada a objetos, puede ser descargado de la siguiente ubicación.

http://demo.jorgeivanmeza.com/Processing/Laberinto

Burbujas 2, ahora en el escritorio con Processing

Introduccion.

Después de bastante tiempo, hay una nueva versión de uno de mis juegos preferidos: Burbujas.  Esta vez para el escritorio y la web, desarrollado con Processing.  Por este motivo es necesario contar con la máquina virtual de Java para su ejecución.

Bubbles 2

El código del pequeño juego ha sido publicado bajo la licencia Attribution-NonCommercial motivo por el cual su código fuente puede ser obtenido, estudiado y modificado.

Misión.

El juego se trata de la mayor cantidad de burbujas posibles.  Al hacer esto se debe tener en cuenta que sólo es posible explotar grupos de burbujas que reunan a por lo menos dos burbujas del mismo tipo en cualquiera de las cuatro direcciones: norte, sur, oriente y occidente.

El primer disparo selecciona las burbujas del mismo tipo que se encuentren adyacentes y el segundo disparo las hace explotar.  La selección de las burbujas puede hacerse con el ratón o con las flechas del teclado y los disparos pueden hacerse con el clic derecho del ratón o con la barra de espacio del teclado.

Otras teclas útiles en el juego son R (reset) reinicia el juego, H (hint) modo de ayuda y Q (quit) termina la sesión de juego.

Enlaces.

The falling things: jugando con Processing

Introducción.

Processing es en muy pocas palabras un lenguaje multiplataforma (Linux, MacOS y Windows) basado en Java muy interesante que permite desarrollar rápida y fácilmente pequeñas aplicaciones (o sketches) que incluso personas con pocos conocimientos en desarrollo de software pueden implementar.

Por ahora mi experiencia con el lenguaje es muy limitada, sin embargo después de instalarlo he estado un poco con él.  Para esto decidí hacer un sketch muy sencillo en el que se controla mediante el teclado una base que tiene como misión recoger las cosas que caen.

Sketch.

The Falling Things, versión 0.1

Enlaces.

Reemplazar OpenJDK con SunJDK en Ubuntu 10.04 debido a problemas con Processing

Introducción.

Este fin de semana estuve haciendo unas pruebas realmente sencillas en Processing 1.1 en mi portátil que utiliza GNU/Linux Ubuntu 10.04.  Previamente le había instalado OpenJDK sin embargo empecé a obtener comportamientos extraños durante las pruebas como el hecho de reiniciarse el sistema de ventanas frecuentemente.

Debido a que mis programas en Processing eran muy sencillos no tenía sentido que fueran estos, mas aún sabiendo que se terminan ejecutando en la Máquina Virtual de Java  y por ende no debería haber motivos para que interfirieran con otros programas externos.  Terminé dudando de la implementación de la máquina virtual que estaba utilizando.

A continuación se detalla el procedimiento para desinstalar OpenJDK e instalar SunJDK (ú Oracle) con el cual se solucionaron los extraños problemas que estaba obteniendo.

Procedimiento.

Agregar el repositorio donde están los paquetes del SunJDK.

$ sudo add-apt-repository “deb http://archive.canonical.com/ lucid partner”

Actualizar la base de datos del aptitude.

$ sudo aptitude update

Remover los paquetes del OpenJDK.

$ sudo aptitude remove –purge openjdk-6-jre

$ sudo aptitude remove openjdk-6-doc openjdk-6-jre-headless openjdk-6-jre-lib

Instalar los paquetes del SunJDK.

$ sudo aptitude install sun-java6-jre sun-java6-jdk sun-java6-plugin sun-java6-fonts

Instalar Processing en Linux Ubuntu 10.04

Introducción.

Processing es un lenguaje y un ambiente de desarrollo opensource diseñado para quienes trabajan con imágenes, animaciones e interacción.  Es utilizado por estudiantes, artistas, diseñadores, investigadores y entusiastas para aprendizaje, creación de prototipos y producción.  Fue creado inicialmente para la enseñanza de los fundamentos de la programación de computadores en un contexto visual, para servir como software para la creación de gráficos (sketches) y como una herramienta de producción profesional.

Es libre de descargar y se encuentra disponible para GNU/Linux, Mac OS X y Windows.

El proyecto fue iniciado por Ben Fry y Casey Reas y ha evolucionado a partir de las ideas exploradas en el grupo de Aesthetics & Computation del MIT Media Lab.

Tomado de http://processing.org/.

Instalación.

Requisitos previos.

Processing se fundamenta en Java, tanto su ambiente de desarrollo como su compilador e intérprete (el cual es finalmente la JVM).  A pesar de que incluye su propia distribución del Java Runtime Edition considero ventajoso el tener instalado previamente el Java Development Kit, ya sea el oficial de Oracle o el de OpenJDK.

Las instrucciones para hacer esto se pueden encontrar en el siguiente enlace.

Instalación estándar.

Esta instalación es útil en cualquier distribución de Linux ya que se basa en la distribución TGZ de Processing.

El primer paso es descargar la distribución mas reciente del lenguaje, en este caso la versión 1.1.

$ wget http://processing.org/download/processing-1.1.tgz

Verifique cual es la última versión disponible en la página de descargas.

Se crea un directorio para almacenar el software y se translada allí.

$ sudo mkdir -p /usr/local/processing

$ sudo mv processing-1.1.tgz /usr/local/processing

$ cd /usr/local/processing

Se descomprime el paquete recién descargado con la distribución del lenguaje.

$ sudo tar zxvf processing-1.1.tgz

Se renombra apropiadamente para permitir la coexistencia de varias versiones de ser necesario.

$ sudo mv processing-1.1 1.1

Se verifican los permisos de ejecución del ambiente de desarrollo.

$ sudo chmod +x /usr/local/processing/1.1/processing

Para ejecutar el ambiente de desarrollo y empezar a programar con Processing es necesario invocarlo desde la línea de comando o crear un acceso directo (lanzador) a él.

$ /usr/local/processing/1.1/processing

Instalación para Ubuntu.

Los sistemas operativos herederos de Debian, como Ubuntu, pueden realizar la instalación del lenguaje de una manera resumida.

Descargar la última versión disponible en formato DEB de la siguiente ubicación.

Realice la instalación del paquete recién descargado.

$ sudo dpkg -i processing_1.1-1_all.deb

Los pasos descritos en la sección anterior serán automáticamente implementados y además se creará un ícono en el menú de GNOME bajo la sección de Programming.

Enlaces.

tar zxvf processing-1.1.tgz