Ginga y TVD
Tarea Redes de Computadores II

NCL y Lua

El siguiente es un primer acercamiento a NCL y LUA. Esta página no pretende ser un refinado material de referencia, sino que ser el punto de partida a lo que se enfrentará al aprender estos lenguajes.

En la red existe documentación muy buena sobre NCL y LUA. En el caso de NCL, al enfrentarse a una etiqueta desconocida, lo mejor es consultar el Handbook de NCL. (si la página carga muy lento, intente deteniendo la ejecución de scripts en ella). Por otro lado, la referencia de LUA junto con la descripción del módulo canvas de LUA serán muy útiles a la hora de comprender los códigos escritos en LUA.

Para el desarrollo de la tarea se sugiere revisar los ejemplos de aplicaciones mostrados en esta pagina. Entenderlo y aplicarlos a lo que es necesario para la tarea

Todos los ejemplos se pueden encontrar aquí.

1. Elementos básicos de una aplicación NCL

NCL es un lenguaje descriptivo, basado en XML, que usa etiquetas del tipo <elemento>...</elemento> para definir los componentes, características y acciones de la aplicación.

Usted puede ver algunos ejemplos básicos de NCL aquí. Ademas se Recomienda relizar este ejercicio
el cual usted podrá reutilizarlo posteriormente para la tarea.

Antes de ver los ejemplos es necesario entender antes la estructura básica de un código NCL, esto se describe a continuación.

1.1 Elementos de NCL

Los elementos básicos de un archivo NCL son el <head> y el <body>.

EL ELEMENTO <head>

En <head> se definen las reglas, regiones, descriptores y conectores que serán utilizados en <body> para crear la aplicación. Los elementos a utilizar se agrupan en "Bases": <ruleBase>, <transtitionBase>, <regionBase>(¿Donde va?), <descriptorBase>(¿Como va?), <connectorBase>(¿Cuando va?).

<regionBase> (¿Donde va?)

Es la base encargada para la especificación de regiones Una región es la descripción de un espacio a utilizar dentro de la pantalla.. A estos se les define, al menos, una ID, y sus características espaciales: ancho, alto y distancia desde los bordes, ya sea en pixeles o porcentaje.

Ejemplo:

	<region id="rg01" width="50%" height="20%" left="0" top="0" />
	<region id="rg02" witdh="50% height="50%" left="0" top="50%" >
		<region id="rg02a" width="50%" height="50%" left=50%" top="0" />
	</region>

El ejemplo anterior se definen 3 regiones, entre esta la primera, llamada rg01 que ocupa el 50% de la pantalla en ancho, y el 20% de la pantalla en alto, esta además se ubica en la esquina superior izquierda de la pantalla. La región llamada rg02a es una sub-region contenida dentro de rg02 (si se fijan la región rg02 no finaliza con /> al declararla por lo que esta base debe terminar con un </region> y todo lo que este dentro de esto es una sub-región)

Cabe destacar que las regiones se pueden solapar unas sobre otras, sin generar errores en el script. Sin embargo, si no se define el orden no se sabe a ciencia cierta cuál se desplegará encima de otra. Así, el parámetro zIndex permite darles un orden de profundidad: un zIndex bajo indica que la región está más atrás que una con zIndex más alto:

	<regionBase>
		<region id="rgVideo" width="100%" height="100%" zIndex="0" /> 		
		<region id="rgQst" width="700" height="170" bottom="5" left="10" zIndex="1" />
	</regionBase>
	

En el ejemplo anterior, la region rgQst se mostrará encima de la región rgVideo.

<descriptorBase> (¿Como va?)

Es la base que agrupa a los elementos <descriptor>, los cuales definen los valores iniciales para las propiedades de los elementos <media>. Estos valores iniciales son definidos como atributos de los elementos los cuales definen si el medio se ve con transparencia, por cierto tiempo, etc.

La propiedad clave a definir son las regiones. Para referirse a una región, siempre se debe hacer a través del descriptor asociado. Al menos debe tener definido una ID y la región que describe.
Ejemplo:

	<descriptorBase>	
		<descriptor id="dVideo" region="rgVideo" />
		<descriptor id="dQst" region="rgQst" transIn="tFade"/>
	</descriptorBase>

En el ejemplo, se asignó el id dVideo a la región rgVideo, y el id dQst a la región rgQst. Adicionalmente, se describe un elemento de transición de entrada a través del parámetro transIn. En la descripción de <transitionBase> se explicará el origen de la etiqueta tFade asignada.

¿Para qué sirve este descriptor? En el body del archivo NCL, se tendrá que declarar la lógica con la que los elementos <media> se despliegan y comunican entre sí. Estos elementos, tienen como condiciones iniciales para su despliege, la descripción entregada en los elementos descriptor. Así, por ejemplo un archivo multimedia de un video, podría invocar al descriptor dQst, lo que producirá que se reproduzca en la región rgQst con un efecto de entrada tFade.

EL ELEMENTO <body>

Dentro de la etiqueta body es donde se define el contenido de la aplicación GINGA. Mientras que el header sólo se encarga de determinar el layout, las propiedades y las relaciones causa-efecto de los elementos del software, es en el body en donde éstos son invocados y especificados. Así, en body se pueden especificar contenidos de media (con <media>), otros elementos <context> anidados, elementos <switch> y relaciones <link>.

<media>

Los principales elementos body son los elementos <media>, que corresponden a aquellos que definen los componentes a exponer en la aplicación. Estos pueden ser imágenes, texto, audio, video, y en general cualquier medio soportados por el emulador o el set-top-box usado para ejecutar la aplicación GINGA. Se definen mediante un ID y deben tener, al menos, un descriptor y la ruta donde está ubicado el objeto. Por ejemplo,

	<media id="img01" descriptor="dImg01" src="media/img01.jpg" />

individualiza al archivo de medios con el id img01, le asigna la descripción con id dImg01 y tiene como fuente de origen una carpeta local en donde se guarda el archivo img01.jpg.

<context> y <port>

Un elemento <context> es el elemento que permite estructurar a la aplicación NCL. Puede incorporar contenidos de media, otros elementos <context> anidados, elementos <switch> y relaciones <link>. En estricto rigor, el <body> es un tipo especial de <context>, pero que representa a la aplicación completa.

El elemento <port> define, como indica su nombre, un puerto mediante el cual se puede acceder a un elemento de media, ya sea dentro del <body> como dentro de un <context>, desde el exterior. Ver más adelante el elemento "link".
Ejemplo.

	<context id="ctx01">
		<port id="p01" component="imgC" />
		<media id="imgC" descriptor="d" src="imgC.png"/>
	</context>
Para referirse a la "imgC" desde fuera del contexto, se debe decir: component="ctx01" interface="p01".
El elemento <port> en <body> señala aquellos elementos de media que se iniciarán al comenzar la aplicación.

Aplicando lo aprendido

Con estos ejemplos básicos usted puede hacer la estructura básica para la tarea, implemente lo aprendido poder visualizar en la aplicación GINGA los paneles solicitados en la tarea, además de un vídeo que simule el contenido del canal.

2. Reaccionando ante eventos con NCL

En esta sección usted podrá conectar las regiones que usted definió anteriormente con eventos, como uso de teclas del control o eventos posteriores al inicio o fin de un medio. Para esto usted debe entender el uso de los conectores lo cuales definen la estructura de los eventos y los elementos link que definen los medios a usar en la interactividad ante eventos.

<connectorBase>

Esta base es la encargada de agrupar a los elementos conector. Los elementos <connector> son aquellos que definen la(s) causa(s) y efecto(s) en la ejecución o interacción de los elementos de media (imágenes, video, texto, etc.). Así, se definen condiciones simples o compuestas así como también acciones simples o compuestas con el fin de asignarle roles a los elementos de media que se desee estén envueltos en relaciones causa-efecto. Presionar un botón para desplegar una imagen, o esperar 10 segundos para que se detenga un video, son ejemplos de relaciones causa-efecto para elementos de media.

Los elementos de media pueden adquirir estos roles a través de la etiqueta <link>. La idea es que primero se definen todos los roles y relaciones causa-efecto, para luego asociarselas a través de <link> a cada elemento de media, en el <body> del código NCL.

En el siguiente ejemplo se muestra el uso de condiciones simples y acciones simples:

	<connectorBase>	
		<causalConnector id="cC" >
			<simpleCondition role="onBegin" />
			<simpleAction role="start" />
		</causalConnector>
	</connectorBase>

Cada vez que el elemento asociado al rol "onBegin" comience, implicará que el elemento asociado a "start" inicie como efecto. Cabe destacar que cada acción (simpleAction) debe ser correctamente asignada a un sólo elemento de media. Si se desea asignar una misma acción a más de un elemento media, se debe agregar como parámetro max="unbounded". En general, el parámetro max indica la cantidad de elementos media que pueden tener asignada una misma simpleAction.

<link>

Los elementos <link> son aquellos que permiten la interactividad y el que suceda, en general, el inicio y término de los componentes de media.
Aquí se le asigna un rol a un <media> en la relación causa-efecto definida en los conectores en <head>.
Ejemplo.

	<link xconnector="onBeginStop">
		<bind component="img02" role="onBegin" />
		<bind component="img01" role="stop" />
	</link>

Caso botones del control

También es posible agregar parámetros a las condiciones, para así reutilizar una misma condición en diferentes elementos de media. El ejemplo más claro de este uso es la capacidad de detener un elemento de media de acuerdo al botón presionado. En vez de generar diferentes conectores causales para cada botón, es más simple dejar el botón como parámetro a definir en el momento en el que se asignen los conectores causales a determinado elemento de media:

	<causalConnector id="onKeySelecionDelayedStop">
<connectorParam name="keyCode"/>
<simpleCondition role="onSelection" key="$keyCode"/>
<simpleAction role="stop" delay="1s" />
</causalConnector>

En este ejemplo, el parámetro del keyCode es utilizado para gatillar la acción simple "stop", luego de un retardo de 1 segundo. La condición es, "si se selecciona la tecla especificada en el parámetro keyCode, el elemento de media asociado se detendrá luego de 1 segundo".

En el caso de asignar parámetros, éstos se pueden ingresar a través de un <bindParam>. En este ejemplo se asigna el valor "RED" al parámetro "keyCode", que como hemos visto anteriormente en <causalConnector> servirá para que al momento de presionar la tecla RED del control remoto se gatille el causalConnector onKeySelecionDelayedStop sobre los elementos mOpt2 y mOpt1 (al presionar la tecla RED se activa la concidión y se detiene el elemento mOpt1).

	<link xconnector="onKeySelecionDelayedStop">
<bind component="mOpt2" role="onSelection">
<bindParam name="keyCode" value="RED"/>
</bind>
<bind component="mOpt1" role="stop"/>
</link>

Aplicando lo aprendido

Utilizando lo aprendido, implemente el uso del botón rojo para activar el panel de búsqueda (mostrarlo en pantalla). Posteriormente tendrá que utilizar mas conectores pero antes de aplicarlos debe entender como funciona LUA.

3. Lua (Básico)

Lua es el lenguaje para escribir algoritmos, en caso de que se necesite realizar algún procesamiento de datos.

Se relaciona a NCL y GINGA-NCL mediante las librerías de NCLua, que entregan (hasta la fecha) herramientas para relacionarse con los eventos de causa-acción, Módulo event, y la pantalla, Módulo canvas. Un elemento LUA se define en el archivo NCL como un media más, asignándole un descriptor de región, en donde, si se desea, se puede escribir o pintar.

Módulo event

El módulo event permite la conexión del código LUA con NCL. Define la estructura utilizada para acceder a los eventos que son manejados en el código NCL (los cuales pueden ser de tipo ncl, key, tcp o user) y así rescatar por ejemplo, los valores de algun parámetro seteado en el archivo NCL. La siguiente figura muestra la relación entre un evento de tipo ncl con el archivo NCL y con el script LUA, generando un puente entre ambos para el traspaso de información de ejecución y de parámetros:




Módulo canvas

El módulo canvas permite el dibujado de componentes en pantalla, de manera similar a las descripciones realizadas a través de NCL. Así, el lenguaje LUA consta con una poderosa herramienta para generar dinámicamente contenido en pantalla.

El dibujado se realiza directamente sobre la región que fue asignada al código LUA en el archivo NCL. Algunos de los métodos disponibles son los siguientes:

	-- en lua los comentarios se inician con doble barra.

	canvas:clear() -- permite limpiar los componentes dibujados

	canvas:attrColor(r,g,b,a) -- setea el color a utilizar a continuación, en formato RGBA

	canvas:attrFont(font,size) -- setea la fuente a utilizar para el texto, junto a su tamaño.

	canvas:drawText(x,y,text) -- dibuja el texto text en la posición x,y de la región

	canvas:flush() 	
 	-- actualiza el contenido en pantalla de acuerdo a los 
	-- cambios generados en código. Siempre al modificar algo, se debe hacer flush
	-- al final.	  

La lista completa de comandos para canvas se puede revisar aquí.

Aplicando lo aprendido

Utilizando lo aprendido, incorpore a la tarea las instrucciones para el usuario, escribiendo estas a través de LUA

4. Utilizando teclas en LUA

Mediante LUA usted puede interpretar los distintos botones asociados al control remoto, como los números o las flechas del control. Para esto LUA interpreta cada botón con un string característico dentro de su modulo evt, por ejemplo el string 'CURSOR_RIGHT' representa el botón derecho del control.

¿Como se utiliza?
Para esto es necesario incorporar un atributo global que logre interpretar los distintos botones disponibles, para esto usted debe incorporar al código NCL el currenteKeyMaster dentro de las configuraciones de x-ginga. Esto se realiza de la siguiente forma:

<media id="varGlobal" type="application/x-ginga-settings" descriptor="baseDesc">
	<property name="service.currentKeyMaster" value="1"/>
</media>

Para que la aplicación active el uso de currentKeyMaster usted inicialmente debe habilitarlo con la tecla ENTER (el borde se pone de color verde), este también lo puede desactivar con la tecla ERASE (el borde se pone de color azul)
Con esto cada vez que usted presione una tecla, el modulo evt de GINGA asociara inmediatamente esta acción cambiando sus atributos, por esto mismo usted dentro de LUA puede identificar esto sucesos de la siguiente forma:

if evt.class == 'key' then
	-- evt.type en este caso es es PRESS
	canvas:drawText(100,100,('TIPO DE ACCION: '..evt.type))
	 -- evt.key depende del boton presionado, ej: CURSOR_RIGHT para ->
	canvas:drawText(100,140,('BOTON PRESIONADO: '..evt.key))
	canvas:flush()
end

Aplicando lo aprendido

Revise los ejemplos 3 y 6 dentro de la carpeta lua y en base a esto incorpore a su tarea la opción de ingresar texto a través de los números del teclado. Recuerde que el objetivo no es que usted sepa todas las características de LUA, si no que usted sea capaz de utilizar la información disponible y algunos ejemplos para poder cumplir con los requisitos de esta tarea.

5. Paso de parametros a diferentes medios LUA

De igual forma que NCL puede pasarle parámetros a LUA, LUA puede pasarle parámetros a NLC y con esto da la posibilidad de pasar parametros entre distintos medios LUAs .

El paso de parámetros de LUA a NCL es bastante simple, basta con utilizar el modulo evt y re-asignarle su atributo evt.value

Para utilizar este valor y incorporarlo a otro medio lua, es necesario utilizar conectores para especificar el momento en que esto se realiza. Para esto se utiliza el símbolo $get para referirse al valor recibido desde lua. Por ejemplo:

<link xconnector="onEndAttributionSet">
 	-- Cada vez que cambia el atributo
	<bind role="onEndAttribution" component="input" interface="text"/>
	-- Se setea un parametro de otro codigo ($get)
	<bind role="set" component="output1" interface="text"> 
		<bindParam name="var" value="$get"/>
	</bind>
	-- Ese parametro corresponde al atributo text contenido en input
	<bind role="get" component="input" interface="text"/>
</link>

Aplicando lo aprendido

Revise el ejemplo 6 dentro de la carpeta LUA y en base a esto pase el contenido del texto desde el paneñ de búsqueda hacia el panel de resultado, mostrando en el panel de resultado el contenido de lo escrito.

6. Uso de Modulo TCP

Archivo tcp.lua

Este archivo es un utilitario a la hora de realizar conexiones tcp con algún servidor web. Permite la interacción del usuario, a través del código LUA, con un servidor web. Recibir información online en la aplicación interactiva, o enviar los resultados de alguna selección realizada por el usuario, son ejemplos típicos de los usos para una conexión tcp en una aplicación GINGA.

La estructura básica para uso del archivo tcp.lua es la siguiente:

	require 'tcp'
	tcp.execute(
		function()
			-- Usar funciones: connect, send, receive, disconnect
		end
	)

El uso de cada una de estas funciones se puede revisar en detalle en los ejemplos de encuentas online.

Aplicando lo aprendido

Revise el ejemplo 7 dentro de la carpeta lua y en base a esto antes de incorporarlo modifique este código para poder ver el contenido deseado de la pagina html requerida para esta tarea. Una vez ya probado que esto funciona correctamente incorporelo a su tarea.

7. Animaciones

Para incorporar animaciones a LUA no es necesario saber nada nuevo a lo aprendido hasta este punto , generalmente para poder realizar animaciones se implementan arreglos para definir las secuencia de imágenes a utilizar, finalmente mediante el uso del modulo timer de lua se logra recorrer cada cierto tiempo estas imágenes desplegándolas consecutivamente por pantalla agregando el efecto de animación.

Aplicando lo aprendido

En base al ejemplo 5, incorpore la animación a su tarea en el momento indicado. Siéntase libre de utilizar las imágenes del ejemplo dentro de su tarea, o bien incorporar una secuencia de imágenes diferentes.

MAS INFORMACION SOBRE NCL

_______________________________________

MAS DETALLE SOBRE BASES NCL

Documentación año anterior

DOCUMENTACIÓN OFICIAL DEL LENGUAJE NCL

Documentación NCL
_______________________________________