Un tiempo después

No, no voy a comerntar sobre el aburrido programa de “Solita” :D, solo que hoy estuve arreglando unos bugs de Oregano y me di cuenta que habían pasado ya unos 18 meses desde el último commit que hice!

En fin, mucho tiempo, pero ya tengo un lindo TODO de cosas a ir haciendo, con muy baja prioridad por la Tesis, pero que quizás para mi cumple esté para hacer otro release, esperemos no colgarme de nuevo.

Mientras tanto se arreglaron dos bugs molestos :

  • Se arregló el export a PNG con fondo transparente
  • Se implementó finalmente la opción de exportar en escala de grises

oregano_grayscale

Anuncios

Take A Photo – Fotos instantáneas desde tu web

En la última semana estuve trabajando en agregar nuevas funcionalidades a un sitio de un cliente y entre los pedidos estaba una especie de Fotoblog para los usuarios (y bue, hay que pagar las cuentas a fin de mes :P).

La cosa salió rápido, usando Paperclip que guarda las imágenes que se suben, se muestra en orden, etc, nada del otro mundo. Pero hablando con el cliente surgió la idea de hacer que el usuario se pueda tomar una foto directamente desde la web usando su webcam, así que después de decir “si, se debe poder hacer” mentalmente me salió un “doh!, que dije!“. Lo último que se dijo en esa reunión fue “Lo quiero” :D.

Ya había visto juegos flash que utilizan la webcam así que empecé por ahí, para ver como sacaban un frame del video, lo cual era muy fácil. Lo siguiente era serializarla. A falta de algo mejor hice un serializador de imágenes muy pedorro, pero que anda (aunque es lento), que envía por POST la información de cada pixel.

La parte de Ruby fue fácil y decidí encapsularla en un plugin de Rails para poder reutilizarlo luego o por si a alguien más le sirve :). Además se puede integrar con Paperclip o AttachmentFu para hacer la persistencia de la imagen en donde sea.

La única parte que usa Flash es el capturador de la cámara, porque otra no quedaba, pero luego el botón para tomar la foto y los eventos se manejan todo por Javascript.

El plugin tiene varios TODOs, pero por si a alguien le sirve está en github.

Update : A falta de demo, algunas de las fotos tomadas con la aplicación de ejemplo que hice hoy durante Locos x rails.

Refactoring de “Fat Methods” – Episodio 5

Pasar programadores PHP a Ruby no siempre es una tarea trivial, mayormente porque lo primero que tratan de hacer es escribir código en lugar de pensar que es lo que quieren hacer :). No es que me queje, a todos nos pasa que resolvemos el problema como primero sale (más aún cuando las fechas de entrega son apretadas :).

El otro día queriendo modificar un código me encuentro con este before_filter en un controller :

def setprofile
  @viewer = false
  if (!params['id'] && !params['profile_id'])
    @profile = @passport
  else
    if params['profile_id']
      pid = params['profile_id']
    else
      pid = params['id']
    end
    @profile = Passport.find_by_id(pid)			
    if (!@profile) 
      redirect_to(:controller => 'my3dg', :action => 'show') and return false
    end
    if (@profile.id != @passport.id)
      @viewer = true
    end			
  end
end

Lo primero que pense “uff, que paja, que complicado” hasta que miré mejor la estructura y ahí comprendí que en realidad era muy simple, solo que estaba escrito de forma complicada. Lo primero que me gustó de Ruby cuando empecé a entenderlo fue el uso de “||” para reemplazar esos molestos if anidados cuando tengo más de una opción. “Si no está a, poner a en el valor default”. En ruby es un simple “a || valor_default” (ojo con los valores de verdad en ruby).

Lo otro que veo mucho (incluso en los trabajos que corrijo en la facultad) es utilizar un if para después setear una variable en true o false, cuando casi todos los lenguajes aceptan expresiones booleanas del lado derecho de la igualdad.

Refactorizando el método anterior obtenemos el siguiente código :

def setprofile
  @profile = Passport.find_by_id(params['profile_id'] || params['id']) || @passport
  @viewer = @profile.id != @passport.id
  redirect_to(:controller => 'my3dg', :action => 'show') unless @profile
  return false unless @profile
end

Como nota, uso find_by_id porque retorna nil en caso de no encontrar el registro, en cambio find tira una excepción RecordNotFound, de esa forma puedo acoplar otro “||” para setear el valor default (@passport es la credencial del usuario loggeado en este caso).

Do it right! – Manejo de dependencias

En estos días he tenido varias discusiones sobre algunas prácticas muy acostumbradas en varios proyectos, que a mi parecer están muy lejos de lo útil. Es por eso que decidí escribir un par de artículos denominados “Do it right!” (hazlo bien!, si mi inglés no es tan malo como pienso :D). En esta primer entrega voy a tratar el tema de manejo de dependencias.

Escenario

Muchas veces uno se encuentra con un software que necesita y le es útil. Vamos a suponer de entrada que no tiene paquete para su distribución y/o sistema operativo favorito. En al leer el README vemos que depende de muchas cosas : alguna biblioteca de procesamiento de imágenes, algún captcha system o lo que sea.

Mirando mejor nos encontramos con una realidad muy fea : todas las dependencias están incluidas en el archivo que nos bajamos originalmente, y alguna veces se cargan por métodos poco ortodoxos.

Cualquiera que haya bajado cosas en PHP o Java seguramente se ha encontrado con esto : Clases bajadas de phpclasses.org o miles de archivos JAR en un directorio lib de la aplicación Java que se cargan en el classpath. También lo he visto en varios proyectos Rails últimamente.

La excusa que siempre escucho es “Because it makes the app more self contained“, si, si, BWTF. Pero la pregunta es : ¿es la forma correcta?. Si respondes que si, estás muy lejos de la realidad y seguramente tu sysadmin te odia mucho, pero mucho :).

El Problema

Entonces, ¿cuál es el problema con esto?. En principio parece una maravilla, nos facilita todo, descomprimimos y ya está!, el sysadmin (nosotros) agradecido, pero si el sysdamin es otra persona y se respeta los va a putear mucho, pero muuuuuucho.

Uno de los problemas con empaquetar todas las dependencias es la facilidad de solucionar problemas a futuro. El mejor ejemplo que he vivido es el típico cambio de time zone en nuestro país. PHP, por ejemplo, tiene su propia DB de timezones, y si actualizamos el tzdata de nuestro servidor, maravillosamente PHP ni se entera. Está bien que en este caso como programadores no podemos hacer mucho, es el lenguaje el que está mal, pero el ejemplo ilustra mi punto.

Un software con el que tuve que trabajar, vBulletin, va aún más allá. Tiene su propia DB de timezones por arriba de la que tiene PHP!, hardcodeada en un array!. ¿La excusa? Que la de PHP no anda bien en Windows y es mejor de esta manera.

Otro ejemplo que puedo dar es el otro día cuando migré unos sitios en el trabajo. Uno de los admines se quejó que dejó de andar porque usaba la función “dl” de PHP para cargar extensiones en tiempo de ejecución! (es decir, cualquier script PHP puede cargar un .so que extiende PHP de cualquier manera, incluso para saltearse otras medidas de seguridad), lo que no solo es una chanchada, sino que es un potencial problema de seguridad.

Tener el manejo de dependencias con la aplicación además nos prohíbe actualizar fácilmente un bug de seguridad, usabilidad o lo que sea de esa dependencia. No podemos en muchos casos hacer un upgrade de ese paquete que está embebido dentro de un todo llamado “aplicación”.

En rails he visto ya muchos que acostumbran a usar “rake gems:unpack” para meter las gemas de las que dependen en el directorio vendors/gems, así no las tienen que instalar aparte. Rubygems disgusta en muchos ambientes, no voy a entrar en eso hoy :). Si uno depende  de una versión específica la forma correcta sería especificar en el environment.rb la versión, y luego que el que hace el deploy haga un “rake gems:install” para asegurar que se cumplan las dependencias. Con Capistrano es una papa hacer esta tarea automáticamente ;).

Entonces, ¿nunca más lo hago?

No me gustan los extremos y creo que estas malas prácticas que se ven hoy tiene usos muy específicos.

Supongamos que el proyecto X usa la lib Y, pero tal cual la provee upstreem no me sirve. Lo lógico es hacer un patch para upstream solucionando el problema o agregando la característica.

Mientras upstream acepta el patch y realiza un nuevo release, ahí si tiene sentido tal vez, y de forma temporal tener esa dependencia embebida.

Un ejemplo donde yo lo estoy haciendo es con el uso de la gema contacts, que depende de la gema json. En una aplicación con Rails 1.2.6 no hay ningún problema, pero en otra que usa Rails 2.1 si, porque este último integra un parser de JSON y conflictua con la gema del mismo nombre. La opción lógica sería migrar la aplicación 1.2.6 a una nueva versión de Rails, cosa que no siempre es fácil y se necesita el tiempo. Como no se pudo, es más fácil meter en uno de los proyectos la gema de manera que no moleste al resto de los proyectos en el transcurso de la actualzación.

Seguro hay algún otro caso, ahora no se me ocurre alguno que realmente lo justifique.

State Machine

Varios días atrás tuve que hacer un juego simple, un memotest para ser exacto, para correr en unos “kioskos” para un cliente. Ya que tenía pendiente aprender a usar RubyGame, lo hicimos con este framework para ver que onda, ya que hasta ahora veníamos usando pyGame.

El juego salió super rápido, sin mayores problemas, pero la lógica de juego no me gustaba porque teníamos que andar trackeando el estado actual a mano, muchos ifs y comprobaciones que hacían del loop de juego un choclo de código.

Es por eso que me puse a ver un poco como aprovechar el tener bloques de código para encapsular la lógica del juego un poco más prolijo. Antes de comenzar encontré la gema Statemachine pero a primera vista no la entendí mirando los ejemplos 🙂 y luego de jugar un rato no me terminó de convencer ya que parece mucho más de lo que yo necesitaba.

El resultado de un par de horas de tirar “magia” fue poder definir la lógica de la siguiente manera (el ejemplo está simplificado, omitiendo los efectos y parte de la lógica) :

class Logic
  include StateMachine
  # Esperando interacción del usuario
  state :user_input do
    @events.each { |event|
      case event
      when MouseDownEvent
        selected event.pos
      when QuitEvent
        end_game
      end
    }
  end

  # Oculta las piezas seleccionadas cuando no hubo match
  state :clear do
    @selected.each {|f| f.hide }
    @selected = []
  end

  # Cambio de estado
  transition :user_input, :clear do
    @selected.size == 2
  end

  # Cambio de estado
  transition :clear, :user_input do
    true
  end
end

Cada declaración de state tiene el código que se debe ejecutar cuando estamos en dicho estado, mientras que las transition son usadas automáticamente para saber a qué estado nos debemos mover. La primer transition que retorne true, se toma el estado destino y se asigna como el actual.

Por el lado del game loop, lo único que se debe hacer es llamar a un método que se encarga de ejecutar el estado actual y luego verificar si alguna transición retorna “true” y se cambia al nuevo estado.

class Game
  include Rubygame
  include Logic

  def event_loop
    loop do
      current_state

      return if game_ended?

      draw
      @clock.tick
      @screen.update
    end
  end
end

En Game hay otros métodos auxiliares como game_ended, draw y selected, que no vienen mucho al caso en este momento.

El próximo paso ahora es limpiar un poco esto, ver si no hay una forma mejor de hacerla y publicar el esqueleto completo (la idea a futuro es tener un generator) para poder tener un mini framework para hacer juegos simples.

Si buscan un framework interesante les recomiendo Shattered Ruby (git repo), aunque al momento de escribir este post el sitio principal no responde.

state_machine.rb

MovieClip Factory en Flash

Para un videojuego que nos pidió un cliente tuve que solucionar un problema que me costó bastante y es por eso que lo comparto. Si bien no me gusta mucho escribir por acá sobre software privativo, en este caso encontré tan poca información que me pareció bueno compartirlo.

El juego en cuestión es un scroller horizontal, en donde van entrando chimeneas (mas bien techos con sus chimeneas) y Papá Noel tiene que hacer el delivery de regalos :). El problema apareció cuando empecé a agregar más y más techos al escenario.

La forma en que inicialmente lo manejaba era con un gran MovieClip que tenía adentro los techos en sus respectivas posiciones y luego moviendo el gran MovieClip movía todo. Simple, pero inefectivo. Según parece (aunque no hay nadie que lo confirme) Flash se lleva mal con las técnicas de clipping básicas y por eso el mover un MovieClip enorme (estamos hablando de 4000 o 5000px de ancho) le es costoso (algo así como consumir el 95% del CPU). Otra cosa que incrementaba el problema es que el juego tiene 3 layers para hacer un efecto de Parallax scrolling.

Esto hizo que empezara a investigar opciones, y la solución que mejor se adapta es crear los objetos antes de que entren en pantalla (unos pixels antes) y destruirlos al salir. Ahora bien, crear y destruir objetos on-the-fly es aún peor en muchos casos que el problema inicial :). La solución real al problema es reutilizar las instancias en lugar de eliminarlas. ¿Cómo?. Seguí leyendo.

La idea básica es que cuando un MovieClip sale de pantalla, en lugar de eliminarlo lo ocultamos. De esta forma Flash lo ignora al hacer el render. Si en algún momento necesitamos crear un objeto del mismo tipo, en lugar de crear uno nuevo, reutilizamos el que teníamos oculto y lo hacemos visible (previo acomodarlo donde corresponde). Ahora multipliquen esta idea por 10 tipos de objetos diferentes, y que además son generados al azar antes de empezar cada nivel (no puedo predecir cuantos de cada tipo necesito).

Esto hace que en lugar de tener una lista de MovieClips tengamos una lista de puntos, y solo movemos los puntos. En cada frame nos fijamos que puntos están por entrar a la pantalla y creamos el nuevo objeto y lo ponemos en la posición del punto. Mi código luce más o menos así :

// Crea los objetos que deben estar visibles
// en un momento dado.
while (i  (Stage.width+10)) {
    // Este punto está muy afuera y como
    // están ordenados, el resto también.
    break;
  }

  // Si estoy a 10 pixels de entrar lo creo
  var t:Techo = factory.create(o.techo, "techo"+last_id, 9000+last_id);
  // Acomodo el nuevo objeto, ya sea nuevo nuevo u obtenido del cache
  t._x = o.x;
  t._y = Stage.height - 125;
  // Esta lista tiene los Techos reales que estan visibles en pantalla
  techos.push(t);
  last_id++;
  ++i;
}
// Elimino los puntos que ya use
chimeneas = chimeneas.splice(i);

La solución que implementé fue esto que llamo “MovieClip Factory” que adjunto al final del post para quien quiera descargarla. La idea es que en lugar de crear un nuevo MovieClip con attachMovie, lo hago con la factory. Esta clase se encarga de manejar al lógica de caching de manera transparente.

Cuando no necesitamos más un objeto simplemente lo devolvemos a la fábrica y así esta lo deja a la espera de ser reusado. Un ejemplo de uso sería algo como sigue :

/* mc sería el MovieClip que queremos usar como padre */
factory = new Factory(mc);
factory.registerCode(1, "Techo01");

var t:MovieClip = factory.create(1, "un_id", 1);
// Devuelvo el objeto al factory.
factory.push(t);

/* A este punto t y u son el mismo objeto */
var u:MovieClip = factory.create(1, "un_id", 1);

Haciendo las cuentas, si en promedio mis techos miden 250px cada uno, de hacerlo de la manera inicial tendría que crear unos 16 techos para un escenario de 4000px de ancho. Usando el factory, suponiendo que más de 4 techos a la vez no puedo ver (por el ancho del área visible) en el peor de los casos tengo 4 de cada tipo de techo (2 completos y 2 mitades, una que entra y una que sale), es decir 20 objetos en memoria siendo el consumo mayor.

Sin embargo al generar el escenario en forma aleatoria yo valido que no toquen 2 iguales seguidos porque quedaban feos, por lo que la cuenta en realidad da 2 objetos simultáneos máximo de cada tipo, siendo 10 en total en memoria.

La otra ventaja es que puedo hacer el escenario infinitamente largo a costo constante de uso de memoria 🙂

Descargar MovieClip Factory

Cómo perder un bit

Un proyecto que hicimos a principio de año es un soft que maneja una PC para una rockola con su respectiva interfaz de hardware (“la caja” de ahora en más) para interactuar con la botonera. En estos días el cliente nos pidió que agregaramos alguna validación para que la caja y el programa se aseguren que son “originales” (no es algo que me agrade agregar, pero el software es del cliente).

En fin, la cosa es que estuve todo el viernes y todo el lunes sin poderlo hacer andar. La caja me respondía perfecto salvo en un caso: cuando me llegaba 0x3F pinchaba. Lo peor es que era un valor que me llegaba sospechosamente seguido para ser aleatorio.

Le dimos mil vueltas con Tulku hasta que finalmente encontramos el problema, que obviamente era yo :), o más bien la implementación de SerialPort de .NET (de Microsoft al menos, el programa no corre en Mono todavía) que tiene defaults ridículos :).

El problema era que yo estaba usando un método que lee todo lo que está pendiente, pero justo ese método pasa los bytes por un Encoder, ¿y a que no adivinan? … Si, el Encoder por default es ASCII7BIT, por lo que me tiraba a la basura el bit más significativo del byte leído, haciendo que no hubiera chance de responder correctamente para terminar el handshaking.

Reemplazando el método por un while y leyendo byte a byte de manera RAW, el problema se solucionó.