Un poco de TDD en aplicaciones Windows 8 Modern UI

En una aplicación que estamos haciendo, necesitamos clasificar un texto según 3 tipos de promociones: %, cuotas u otro. En este caso usamos qunit como framework de test unitario para javascript.

Estos son los test:

https://gist.github.com/ferclaverino/5594014#file-test-js

Y el código que pasa los test:

https://gist.github.com/ferclaverino/5594014#file-benefit-js

Para mantener el código organizado (ya que en las aplicaciones Windows 8 suele haber mucho código javascript), necesitamos definir un namespace usando WinJS:

WinJS.Namespace.define("Benefit", {
  parseBenefit: parseBenefit
});

Gracias a la magia de javascript, podemos crear en los test un arnés para definir un namespace fuera de una aplicación windows 8 y ejecutar los test en una aplicación html + javascript estándar.

var Benefit;
var WinJS = {};
WinJS.Namespace = {};
WinJS.Namespace.define = function(name, object) {
  if (name == "Benefit") {
    Benefit = object;
  }
}

De esta forma, y separado las responsabilidades, podemos fácilmente hacer TDD en aplicaciones Windows 8 Modern UI.

Cómo renderizar imágenes obteniéndolas de BD y cachearlas a nivel navegador con MVC3?

Muy buenas a todos!

Este post se podría dividir en dos partes: la primera sería, tal como el título indica, cómo mostrar en una vista una imagen que no se encuentra alojada en el servidor como archivo de formato jpg/png/etc. sino que está almacenada en una base de datos como array de bytes. Lo anterior, si bien no deja de ser “piola”, es algo dentro de todo sencillo. La segunda parte es una vuelta de tuerca más de la primera: “okey, ya puedo ver la imagen… cómo hago para que el navegador no la trafique cada vez que recargo la página?”.

1) Partimos de código HTML en el cual aparece una imagen:

<img src="../content/img/categories/5.png" alt="Una foto">

2) Editamos el archivo Global.asax.cs. Lo que vamos a hacer es agregarle una ruta para que justamente rutee las direcciones del tipo “content/img/categories” a una acción de un controlador nuestro:

public static void RegisterRoutes(RouteCollection routes)
{
   routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

   routes.MapRoute(
      "Default", // Route name
      "{controller}/{action}/{id}", // URL with parameters
      new { controller = "Account",
            action = "LogOn",
            id = UrlParameter.Optional });

   //Ruta que agrego
   routes.MapRoute(
      "ImagenCategory",
      "content/img/Categories/{filename}",
      new { controller = "Image",
            action = "LoadCategory" });
}

Notar que pusimos un parámetro en la ruta llamado “filename”. Este parámetro va a ser el id de la imagen en la base de datos.

3) También agregamos nuestro controlador (llamado “ImageController”) y nuestra acción (“LoadCategory”), que son estos:

namespace Ejemplo
{
    using System.IO;
    using System.Web.Mvc;

    public class ImageController : Controller
    {
        public ActionResult LoadCategory(string filename)
        {
            //El catálogo me devuelve un objeto que tiene dos
            //atributos: el byte[] de la imagen y la fecha de modificación
            ImageAssociation image = new CategoryRepository().GetImage(filename);

            return this.File(new MemoryStream(image.Image), "image/jpg");
        }
     }
}

Es importante como devolvemos el resultado!

Entonces, a partir de ahora, cada vez  que aparezca una referencia con ese formato en el html, se va a invocar a esta acción en vez de buscar la imagen en el path virtual del servidor. Y con esto cubrimos la primera parte!

Ahora vamos a enfocarnos en el manejo del cacheo de la imagen…

Si vamos a Fiddler o a la solapa red del Firebug, tal como estamos hasta el momento y cada vez que recarguemos la página, vamos a ver que la llamada correspondiente a la imagen devuelve un código 200 y que trafica preciosos KB. Lo que queremos es que si la imagen ya la descargamos previamente y no se modificó devuelva un código 304 y la obtenga de la caché del navegador sin traficar nada más.

Para esto vamos a modificar la acción de esta manera:

public ActionResult LoadCategory(string filename)
{
   ImageAssociation image = new CategoryRepository().GetImage(filename);

   var headerValue = Request.Headers["If-Modified-Since"];
   if (headerValue != null)
   {
      var modifiedSince = DateTime.Parse(headerValue).ToUniversalTime();
      if (Math.Abs(modifiedSince.Subtract(image.Date).TotalMinutes) < 1)
      {
         Response.SuppressContent = true;
         Response.StatusCode = 304;
         Response.StatusDescription = "Not Modified";
         Response.AddHeader("Content-Length", "0");

         return new EmptyResult();
      }
   }

   Response.AddHeader("Last-Modified", image.Date.ToString("R"));

   return File(new MemoryStream(image.Image), "image/png");
}

Las claves de esto son los headers “If-Modified-Since” y “Last-Modified” que nos permiten comparar si la versión de la imagen cacheada en el navegador cambió o no (para esto es que teníamos la clase ImageAssociation con el byte[] y la fecha de modificación) respecto a la que está en base de datos. Si bien estamos yendo a la base para obtener la imagen y su fecha de modificación (mismo se podría separar estos datos para que la consulta sea más liviana), esto es una operación mucho menos costosa -despreciable- en tiempo que traficar la imagen por la red.
Finalmente, si la imagen no cambió devolvemos un EmptyResult con el código 304 y conseguimos lo que buscábamos!

Espero que les sirva!
Saludos

Desarrollo de videojuegos con HTML5 – Parte 7

Después de un tiempo de descanso, es hora de retomar este paso a paso para realizar nuestros juegos con HTML5 y JavaScript.

En esta oportunidad hablaremos sobre una de las características básicas de todo juego, las colisiones.

Detectar colisiones en un videojuego es una tarea común, no solo para poder saber si dos objetos del juego se tocan, como por ejemplo, una bala disparada por nuestro personaje impactando contra un enemigo, sino que además, la interacción con el puntero del ratón, o los dedos en una pantalla táctil para acceder a un determinado menú del juego también representa una colisión.

Existen muchos métodos para detectar que dos objetos se están tocando, cada uno de estos más eficientes que los otros en determinados casos. Podemos encontrar colisiones en forma de caja (La que usaremos para el ejemplo), por píxeles, verificando que solo píxeles de color de un objeto estéen tocando los píxeles del otro objeto, mediante proyección de líneas (Ray Casting), y muchos otros métodos.

La colisión por cajas, entonces, es una de las más simples y puede resultar efectiva si nuestro juego no cuenta con gran cantidad de elementos para detectar si están en colisión o no, ya que si bien no es dependiente de este tipo de colisión, se suele hacer un escaneo por todos los elementos del juego y verificar, uno a uno, si nuestro objeto están en contacto con otro.

Para entender la mecánica de esta forma de detectar colisiones, pensemos en nuestro objeto de juego al cual le dibujamos una caja que lo contenga. Esta caja poseerá tanto las coordenadas X e Y donde se sitúa, además de las dimensiones de ancho y alto. Luego, teniendo el objeto contra el cual probar la colisión, dibujaremos otra caja con datos similares. Cuando ambas cajas entran en contacto, entonces entendemos que existe una colisión.

Este tipo de colisiones no promete detectar correctamente la misma si las formas son irregulares.

Como vemos en la imagen, si las formas (Gráficos) son irregulares, al crearse una caja para contenerlo, puede quedar mucho espacio sin uso, pero que será tomado como válido para la colisión. Para mejorar este comportamiento, una colisión por píxel sería más adecuada, ya que la misma detectará solo aquellos píxeles de color y no los transparentes en nuestro sprite, por supuesto, realizar el cálculo para dicha detección resulta algo más costosa en cálculos computacionales.

Entonces, para detectar mediante la colisión por cajas necesitamos saber las coordenadas de los dos objetos además de sus dimensiones. Una excelente solución es la que nos propone Matthew Casperson con su clase Rectangle en JavaScript.

function Rectangle()
{
    this.left = 0;
    this.top = 0;
    this.width = 0;
    this.height = 0;

    this.startupRectangle = function(left, top, width, height)
    {
        this.left = left;
        this.top = top;
        this.width = width;
        this.height = height;
        return this;
    }

    this.intersects = function(other)
    {
        if (this.left + this.width < other.left)
            return false;
        if (this.top + this.height < other.top)
            return false;
        if (this.left > other.left + other.width)
            return false;
        if (this.top > other.top + other.height)
            return false;

        return true;
    }
}

La sección más importante está dentro de la función intersects, la cual toma los dos rectángulos y compara los mismos para saber que una parte del primero se encuentre en alguna parte del segundo.

Para este ejemplo, dibujaremos un rectángulo en el trayecto de nuestro personaje. Cuando el mismo toque dicho rectángulo, este dejará de avanzar.

contextBuffer.save();
	contextBuffer.fillStyle = "black";
	contextBuffer.fillRect(300, 10, 30, 40);
contextBuffer.restore();

A continuación del dibujado de nuestro personaje, dibujamos un rectángulo de color negro. Podemos notar en el código que estamos utilizado dos funciones, save y restore. Estas funciones sirven para guardar el estado del lienzo de dibujo en ese momento, poder realizar cualquier modificación, agregar elementos, y luego retornar el lienzo al estado anterior. De esta forma, el cambio de color mediante fillStyle no afectará otras funciones que usen este color para rellenar formas.

El bloque negro se interpone en el camino de nuestro personaje.

El siguiente paso, para detectar la colisión será verificar el estado de los dos objetos tras cada actualización del juego.

var boxBlock = new Rectangle();
boxBlock.startupRectangle(300, 10, 30, 40);
var boxYoda = new Rectangle();

Debido a que sabemos de antemano la posición del rectángulo negro, no es necesario actualizarlo cada vez que el juego se modifica, por lo que escribiremos el código anterior fuera del bucle principal del juego. Finalmente, en el bucle, comprobaremos la posición actual del personaje y su intersección con el bloque.

boxYoda.startupRectangle(x, 10, 42, 39);
if (!boxYoda.intersects(boxBlock)) {
	x++;
}

Solo si el personaje no está en colisión con el bloque, podrá avanzar un píxel.

Como decíamos, este tipo de comprobación suele ser costosa, pero eficiente para darnos una solución rápida para nuestros juegos.

Manejo de excepciones

En una aplicación MVC en la cual estaba trabajando tenia que loguear en la base de datos toda excepción que se dispare de un controller en especial.

Para esto, cree un nuevo controller, que llame BaseController, el cual será donde logueare en la base de datos la excepción obtenida.

   1: public class BaseController : Controller

   2: {

   3:     

   4: }

 

Como se puede ver, cuando se crea un controller, empieza heredando de Controller. Esto es importante ya que dicho Controller es el que posee el método OnException del cual queremos sobrescribir.

Por tal motivo, sobrescribimos el método OnException para poder loguear la excepción obtenida y poder setearle un mensaje default ante cualquier falla en la aplicación.

   1: public class BaseController : Controller

   2: {

   3:     private LogService logService = new LogService();

   4:  

   5:     protected override void OnException(ExceptionContext filterContext)

   6:     {

   7:         this.logService.LogError("Se ha producido un error", filterContext.Exception.Message, filterContext.Exception.StackTrace);

   8:  

   9:         base.OnException(filterContext);

  10:     }

  11: }

 

Utilice una clase que la llame LogService en la cual tengo el método para poder loguear en la base de datos.

Luego, al controller que quiero loguear sus excepciones, en este caso el HomeController, hice que herede del BaseController reemplazando la herencia que tenia con Controller.

   1: public HomeController : BaseController

   2: {

   3:     // Code...

   4: }

 

De esta forma pude manejar la excepción independientemente de donde se este disparando y asi hacer una misma funcionalidad para todos los casos.

Espero que les haya gustado…chau!

Escribiendo HTML Helper propios

Estaba desarrollando una aplicación con jQuery Mobile que tenía formularios extensos. Me di cuenta que perdía mucho tiempo escribiendo el HTML, aun con Razor porque los controles de jQuery Mobile tienen características particulares. Entonces decidí escribirme unos HTML Helpers que me hicieran la tarea más fácil.

Los helpers de HTML son simples extensiones a la clase HtmlHelper. Se definen creando una clase más o menos así:Ejempo simple de extensiones a HTML

La parte con el comentario “Uso” debería ser en una vista.

Ahora bien, mis helpers son muy cómodos para crear HTML sin parámetros, pero yo quería usarlo como los que vienen con MVC3. La idea era usarlos de la siguiente forma:

@Html.MobileYesOrNo(m => m.UnaProperty)

Les dejo la implementación del método MobileYesOrNo:

Ejemplo de control mobile con HTML Helpers 1

Como ven, el método escribe varias líneas en HTML. Eso me simplifica bastante las vistas y reduce mi esfuerzo.

Otra ventaja es que lo puedo testear, ya que el resultado es un string:

Test del Mobile YesOrNo

Para el manejo de la property que se pasa por parámetro me valgo de algunos métodos que no se ven en la imagen. Si lo desean, pueden hacer click en ella para ver el código.

Espero que les sirva. Saludos.

Cómo conectarse a un servicio WCF sin agregarlo como service reference

En distintos proyectos tuvimos que generar conexiones a servicios wcf. La manera práctica de hacer esto es agregar el servicio como service reference y automaticamente tendríamos todo lo necesario para poder invocar al servicio externo.
En este post nos gustaría mostrarles como realizar una conexión a cualquier servicio wcf sin necesidad de agregarlo como service reference. También se podrá ver como generar un dummy del servicio y como resolver dependencias con spring.
Para realizar este procedimiento necesitamos contar con la interfaz del servicio.

Comencemos…

Interfaz del servicio wcf
Interfaz

El servicio wcf expone una interfaz que contiene un método: IsValid.

El siguiente paso es definir una clase abstracta ServiceResolver, que expondrá un método ResolverWcfService y tendrá una propiedad ServiceAddress:
ServiceResolver

Como comentamos anteriormente, la idea es realizar una conexión real y una dummy, por lo tanto vamos a tener dos clases que van a heredar de ServiceResolver (WCFServiceResolver y DummyServiceResolver):

WCFServiceResolver:
WCFServiceResolver

Esta clase realiza la conexión real, mediante una url real (Address), que más tarde explicaremos como setearla y un binding que deberá estar especificado en la configuración de nuestro cliente de la siguiente manera:
config

DummyServiceResolver:
DummyServiceResolver
Esta clase simula la conexión real mediante una clase DummyServiceImplementation que esta definida de la siguiente manera:
DummyServiceImplementation
Esta clase implementa la interfaz del servicio WCF (WCFServiceInterface) y siempre que se invoque al método IsValid va a devolver true.

Ahora sí, estamos en condiciones de implementar el cliente:Client

Vayamos por partes…
El cliente tiene una propiedad del tipo ServiceResolver y un método ClientMethod.
En el método, el cliente se genera un objeto de tipo WCFServiceInterface (la interfaz del servicio WCF), utilizando el método ResolveWcfService del objeto ServiceResolver y luego invoca al método IsValid del mismo, obteniendo el resultado.
La pregunta es, ¿Cómo se instancia el objeto ServiceResolver?
La respuesta es simple. Utilizando Spring. Por configuración especificamos de qué manera se va a instanciar esa propiedad.

Primero deberiamos generar un archivo spring.config:
springConfigWCF
De esta manera especificamos que la propiedad ServiceResolver se va a instanciar con un objeto WCFServiceResolver (conexión real) y la url del servicio sería “http://wcfserviceurl.com”.
Si quisieramos realizar una conexión dummy, el spring.config debería ser:
springConfig
En este caso, configurar la service address no tiene sentido, dado que el DummyServiceResolver no utiliza esta propiedad para nada.

Para finalizar, habría que actualizar el archivo de configuración de nuestro cliente de la siguiente manera:
finalconfig

En conclusión, solamente teniendo la interfaz del servicio wcf, generamos una conexión real al mismo, una simulación de la conexión y una implementación dummy del mismo, y mediante spring configuramos la alternativa que nos conviene utilizar.

Hardcodear es bueno

Título chocante para que la gente lea, de todas formas lo sostengo. En algunas ocasiones es mejor escribir código harcodeado. Y arranco con el que para mí, es el caso más claro: los tests unitarios.

[Test]
public void CryptTest1()
{
    Assert.AreEqual("qKdUrarYfJg=", new Cryptographer().Crypt("test", "012345678901234567890123"));
}

[Test]
public void CryptTest2()
{
    var crypted = new CryptLibrary.TripleDESCrypter("test", "012345678901234567890123");
    Assert.AreEqual(crypted, new Cryptographer().Crypt("test", "012345678901234567890123"));
}

CryptTest1 y CryptTest2 prueban exactamente el mismo código. En este ejemplo Cryptographer es una clase de mi aplicación que internamente usa el TripleDESCrypter (de una biblioteca externa).

Hay 2 grandes ventajas del primer test sobre el segundo:

  1. Es más claro.
  2. No depende de una implementación externa.

Es más claro

Para mí es muy claro que el primer test espera que la encriptación de como resultado el string “qKdUrarYfJg=”. En cambio, en el segundo test, parece que compara 2 funciones distintas de alguna forma.

En general un test debe ser simple y agregar esa llamada a una biblioteca externa lo hace más complejo.

No depende de una implementación externa

Supongamos que la biblioteca que yo estoy usando tiene un bug, en lugar del string “qKdUrarYfJg=”, retorna “error”. En este ejemplo nuestro test continuará pasando ya que el Cryptographer internamente usa este método.

¿Por qué pasa esto? Porque nuestro test prueba que nuestra implementación devuelva lo mismo que una implementación externa cuando debería probar un caso concreto.

Este problema se evita escribiendo tests hardcodeados. Al escribir el string que debe devolver estamos definiendo empíricamente el caso correcto. No dependemos de lo que otra librería define como correcto. Además si por alguna razón nuestra implementación debe devolver otra cosas, o un caso particular, basta con modificar el string.

Saludos.

HTML5: Local Storage

Una gran feature que presenta HTML5 es local storage. Esto nos permite guardar datos client-side en forma clave/valor usando JS.

Un ejemplo muy sencillo puede ser:

localStorage.setItem('nombre', 'pedro');
// ...
alert(localStorage.getItem('nombre'))

Lo interesante es que podemos ejecutar la primer línea en una página y la segunda en todas las subsiguientes.

¿Por qué es tan bueno?

Como siempre que agregamos funcionalidad del lado del cliente, se libera carga al servidor. Lo novedoso es que nos permite llevar adelante trabajos que antes no se podían hacer: ahora podemos guardar en cualquier parte (o tiempo) de la aplicación y utilizarlo en otro.

  • Podemos recuperar un estado si guardamos periódicamente.
  • Podemos hacer que no se pierdan los datos si se pierde la conexión a internet.
  • Podemos persistir menus desplegados/contraidos por el usuario.

Los usos para local storage son múltiples y limitados por nuestro ingenio. La interfaz es muy simple y está soportado por [casi] todos los browsers modernos.

Lectura recomendada: HTML5 local storage

Desarrollo de videojuegos con HTML5 – Parte 6

En la cuarta entrega nos quedó, al final del mismo, un tema pendiente cuando aprendimos a crear objetos animados.

Cuando ejecutábamos el juego pudimos notar que nuestro personaje modificaba sus gráficos de forma muy rápida no pudiéndose apreciar la animación.

Este comportamiento se debe, en principio, a que el juego está disparando más de 30 cuadros de redibujado por segundo y tras cada cuadro nuestro código cambia el gráfico a mostrar, por lo que en vez de tener una animación algo más apreciable, simplemente se ven algunos píxeles que se cambian de lugar, lo que resulta en una animación pobre, incluso para dos cuadros de animación.

Por lo tanto tendremos que encontrar una forma para disparar el cambio de cuadro en nuestro personaje cada cierta cantidad de cuadros dibujados en pantalla.

Una solución rápida podría ser contar cuantos cuadros se han dibujado y luego cambiar al siguiente gráfico de nuestro personaje. Si bien es una alternativa, esto puede causar que una variación en la cantidad de cuadros posibles a ser dibujados en pantalla haga que nuestra animación se dispare más veces por segundo, o menos, dependiendo de cuál sea esta variación, lo que nos daría una sensación de que el juego a veces se acelera y a veces se hace más lento.

Otra posibilidad, y es la que veremos aquí, es la de contar tiempo entre cuadros. Esto es, contabilizar cuanto tiempo ha pasado entre un cuadro y el otro, y luego de llegar a determinada suma, realizar el cambio. Esto nos garantizará que el cambio sea constante en el tiempo, incluso si contamos con problemas en la cantidad de cuadros dibujados por segundo. Por supuesto, esta técnica no puede ser considerada como infalible, ya que a baja performance del equipo que ejecute el juego, también veremos ciertos problemas, pero salvaremos esto en equipos con mayor capacidad.

Para esto necesitaremos algunas variables para calcular el tiempo actual y la diferencia en relación al cuadro actual.

var lastFrame = 0;
var counter = 0;
function dibujar() {
var thisFrame = new Date().getTime();
var delta = (thisFrame - lastFrame) / 1000;
lastFrame = thisFrame;
...

Cada vez que un nuevo cuadro es dibujado se calcula el tiempo en milisegundos (Podría ser cualquier otra unidad) en el cual se dibujó el cuadro anterior y el tiempo actual. Esto nos dará un valor delta (Diferencia en el cambio entre el valor anterior y el actual) con el que podremos realizar nuestros cálculos.

counter += delta;
if (counter > 0.4) {
walkFrame = (walkFrame + 1) % 2;
counter = 0;
}

Sumando este valor delta a un contador iremos acumulando las diferencias. Cuando la misma llegue a un valor determinado, entonces será el momento de realizar el cambio del gráfico a mostrar, logrando una animación más agradable.

En Frameworks avanzados este valor delta suele ir encapsulado con otras propiedades, pero siempre podremos encontrarlo ya que es vital no solo para este tipo de cálculos, sino que resulta también de utilidad en cálculos de trayectorias, proyectiles, colisiones y otros.