lunes, febrero 20, 2012

VFP: Manejador de eventos en tiempo de ejecucion

Hay muchas situaciones en las que terminamos necesitando que una instancia de una clase propia pueda ejecutar codigo arbitrario en uno o mas de sus eventos, como por ejemplo en clases que se instancian en tiempo de ejecucion en lugar de hacerlo en tiempo de diseño.

Habiéndome topado con estos casos muchas veces, hace unos dias terminé escribiendo una clase que me permite añadir un manejador de eventos dinámicos a cualquier clase de forma sencilla. El primer paso es crear un manejador de eventos en la clase. Para esto le añadimos una propiedad que contendrá la instancia del manejador de eventos, la cual es creada en el constructor de la clase (evento Init):

THIS.Events = CREATEOBJECT("VEEventHandler")

Lo siguiente es definir los eventos que estarán disponibles y la forma de manejar los mismos. La clase permite dos formas de manejar los eventos declarados cuando estos son invocados.

Usando una clase controller
Consiste en asociar un metodo de una clase controladora al evento declarado de modo que, cuando se invoque el evento indicado este procesa a invocar el metodo indicado en la clase controladora. La principal ventaja de este metodo es que la asociacion entre el evento y su controlador puede ser modificada sin que esto afecte el código existente. La forma de definir estos eventos seria así:

THIS.Events.Add("sayHello","Hello",oController)

Lo que estamos diciendo aqui es:
define un evento llamado "sayHello" el cual, cuando sea invocado, llamará al método "Hello" del objeto "oController".

Usando codigo dinámico
Consiste en asociar un codigo VFP válido al evento, de modo que cuando este sea invocado se ejecute el método asociado al evento. La ventaja principal de este método es que no necesitamos de un segundo objeto que maneje los eventos y ademas el código asociado al evento puede cambiar dinámicamente sin afectar el resto del codigo de la aplicación. La forma de definir estos eventos es:

THIS.Events.Add("sayHi",cSayHiCode)


Como invocar los eventos
Una vez definidos los eventos que estarán disponibles en la clase, lo único que queda es invocarlos cuando sea necesario. La clase ofrece dos formas de invocar estos eventos:

Invocación directa
Consiste en invocar el evento directamente por su nombre:

miObjeto.Events.sayHello.Raise("World!")

El método Raise acepta hasta 10 parámetros, los cuales son pasados al método del controller asociado al evento, o a la sentencia PARAMETERS o LPARAMETERS del código asociado al mismo.

Invocación indirecta
Esta forma permite invocar el evento indirectamente, mediante un string que identifica el nombre del evento:

miObjeto.Events.Raise("sayHello","Mundo!")

El primer parámetro del metodo Raise recibe el nombre del evento a invocar y a partir de ahi los parámetros son pasados directamente al evento.

La clase con su código fuente y ejemplos puede ser descargada desde aqui.


NOTA IMPORTANTE
Mucha de la funcionalidad proporcionada por esta clase, sobre todo usando la figura de controllers, puede ser implementada de forma nativa en VFP a partir de la introducción del comando BINDEVENTS.  La ventaja que da esta clase es que la misma es compatible con cualquier versión de VFP (solo usando eventos manejados por controller; los eventos con código dinámico requieren de VFP 7 o superior).

No hay comentarios: