Cairngorm: Secuenciado de Commands

En según qué ocasiones podemos requerir que nuestra aplicación ejecute una serie de Commands de forma asíncrona siguiendo un órden determinado.
Cairngorm viene de serie con la capacidad de encadenar Commands asíncronamente. La clase com.adobe.cairngorm.commands.SequenceCommand es la que se ocupa de que esto sea posible.
En esta entrada veremos dos formas de implementar el secuenciado. Una de forma estática y la otra de forma dinámica.

Encadenado estático

De forma nativa Cairngorm soporta encadenado estático de Commands, esto significa que para una secuencia dada deberemos crear una serie de Commands exclusiva para ésta.
El principal problema que se nos puede plantear en este caso es que si queremos reutilizar un Command que ya forma parte de una secuencia no podremos. Nos veremos forzados a duplicar código.
La causa de este problema viene del hecho que la clase SequenceCommand, la clase de la que extienden nuestros Commands a secuenciar, utiliza una propiedad nextEvent que es la que decide cuál es el siguiente Evento (y por consiguiente Command) que se va a ejecutar. La forma en la que los Commands son lanzados hace que sea imposible parametizar esta propiedad y por lo tanto se mantega estática.

Un ejemplo de un Command que forma parte de una secuencia:

HolaCommand.as (ejemplo estático)

Actionscript 3:
  1. package com.madeinflex.command
  2. {
  3.     import com.adobe.cairngorm.commands.ICommand;
  4.     import com.adobe.cairngorm.commands.SequenceCommand;
  5.     import com.adobe.cairngorm.control.CairngormEvent;
  6.     import com.madeinflex.event.MundoEvent;
  7.     import mx.controls.Alert;
  8.     import mx.events.CloseEvent;
  9.     public class HolaCommand extends SequenceCommand implements ICommand
  10.     {
  11.         public function HolaCommand()
  12.         {
  13.             nextEvent = new MundoEvent( MundoEvent.MOSTRAR_MUNDO );
  14.         }
  15.         override public function execute( evt:CairngormEvent ):void
  16.         {
  17.             Alert.show( "Hola", "HolaCommand", Alert.OK, null, onClose );
  18.         }
  19.         private function onClose( evt:CloseEvent ):void
  20.         {
  21.             executeNextCommand();
  22.         }
  23.     }
  24. }

Encadenado dinámico

El encadenado dinámico es mucho más flexible que el estático dado que permite crear de forma dinámica las secuencias de Commands, de este modo podremos reutilizar un mismo Command para formar parte de diferentes secuencias o para ser lanzado individualmente.
Para conseguir este objetivo nos vamos a servir de una colaboración que Bjorn Schultheiss ha hecho al repositorio de recursos para Cairngorm: cairngormdocs.com.
Se trata de dos clases: com.bjorn.event.ChainEvent y com.bjorn.event.EventChainFactory.
La clase ChainEvent es un wrapper de com.adobe.cairngorm.control.CairngormEvent que añade la propiedad nextChainedEvent:ChainEvent, y la clase EventChainFactory es la que se ocupa de enlazar dinámicamente las diferentes instancias de eventos que queremos secuenciar. Se le pasa un Array de instancias de ChainEvent y va asignando de mayor a menor (en índice) cual es su nextEvent.

Un ejemplo de un Command que se añade dinámicamente a una secuencia, su evento relacionado y la forma de crear la secuencia:

HolaCommand.as (ejemplo dinámico)

Actionscript 3:
  1. package com.madeinflex.command
  2. {
  3.     import com.adobe.cairngorm.commands.ICommand;
  4.     import com.adobe.cairngorm.commands.SequenceCommand;
  5.     import com.adobe.cairngorm.control.CairngormEvent;
  6.     import com.bjorn.event.ChainEvent;
  7.     import com.madeinflex.event.MundoEvent;
  8.     import mx.controls.Alert;
  9.     import mx.events.CloseEvent;
  10.     public class HolaCommand extends SequenceCommand implements ICommand
  11.     {
  12.         override public function execute( evt:CairngormEvent ):void
  13.         {
  14.             nextEvent = ChainEvent( evt ).nextChainedEvent;
  15.             Alert.show( "Hola", "HolaCommand", Alert.OK, null, onClose );
  16.         }
  17.         private function onClose( evt:CloseEvent ):void
  18.         {
  19.             executeNextCommand();
  20.         }
  21.     }
  22. }

HolaEvent.as (ejemplo dinámico)

Actionscript 3:
  1. package com.madeinflex.event
  2. {
  3.     import com.bjorn.event.ChainEvent; 
  4.     import flash.events.Event;
  5.     public class HolaEvent extends ChainEvent
  6.     {
  7.         public static const MOSTRAR_HOLA:String = "mostrar_hola";
  8.         public function HolaEvent( type:String )
  9.         {
  10.             super( type );
  11.         }
  12.         override public function clone():Event
  13.         {
  14.             return new HolaEvent( type );
  15.         }
  16.     }
  17. }

Creación dinámico de la secuencia

Actionscript 3:
  1. //(...)
  2. private function empezarSecuencia1():void
  3. {
  4.     var evts:Array =
  5.     [
  6.         new HolaEvent( HolaEvent.MOSTRAR_HOLA ),
  7.         new MundoEvent( MundoEvent.MOSTRAR_MUNDO ),
  8.         new ExclamacionEvent( ExclamacionEvent.MOSTRAR_EXCLAMACION )
  9.     ];
  10.     var chainEvent:ChainEvent = EventChainFactory.chainEvents( evts );
  11.     chainEvent.dispatch();
  12. }
  13. //(...)

Proyectos de ejemplo

Incluyo dos proyectos muy simples de ejemplo. Uno para secuenciado estático y otro para secuenciado dinámico:

Comparte:



7votos  Vota!!

Acerca de esta entrada