Ocorreu um erro neste gadget

quarta-feira, 30 de junho de 2010

Introdução a NCL e Lua: Desenvolvendo Aplicações Interativas para TV Digital

Escrito por Ramon Rosa e Vagner Oliveira


Resumo. A televisão é um dos maiores meios de comunicação do mundo, como também é uma grande fonte de informação, entretenimento e cultura. Além dos benefícios trazidos com a qualidade de som e imagem, a TV possibilita inúmeras facilidades e oportunidades para os programas de televisão. Os telespectadores poderão ter acesso a jogos e programas interativos, ou seja, o usuário deixará de ser um mero espectador e passará a interagir com a programação, moldando o conteúdo de acordo com a sua escolha. Este artigo traz um estudo sobre o as linguagens NCL (Nested Context Language) e Lua e um estudo de caso com a implementação de uma aplicação interativa para TV Digital.
Palavras-chave: televisão digital interativa, NCL, Lua.
1. Introdução
A televisão é um dos maiores meios de comunicação do mundo, como também é uma grande fonte de informação, entretenimento e cultura. Em 2006, o governo brasileiro criou o SBTVD (Sistema Brasileiro de Televisão Digital), baseado no padrão japonês. O SBTVD inovou no seu middleware, o Ginga, que consiste de máquinas de execução das linguagens oferecidas, e bibliotecas de funções, que permitem o desenvolvimento rápido e fácil de aplicações.
    O Ginga é fruto do desenvolvimento de projetos coordenados pelos laboratórios Telemídia da PUC-Rio (Pontifícia Universidade Católica do Rio de Janeiro) e LAViD da UFPB (Universidade Federal da Paraíba). O nome Ginga foi escolhido em reconhecimento à cultura, arte e contínua luta por liberdade e igualdade do povo brasileiro.
    Uma aplicação de TV Digital pode ser declarativa, procedural ou híbrida. A seguir esses conceitos são apresentados:
Linguagens Declarativas – são mais intuitivas (de mais alto nível), mais fáceis de usar e, normalmente, não exigem um perito em programação. Enfatiza a declaração descritiva de um problema, sem se preocupar como realmente implementará essas tarefas.
Linguagens Procedurais – são mais complexas e usualmente requer um perito em programação. O programador deve informar ao computador cada passo a ser executada, ou seja, deve implementar uma solução algorítmica. No entanto, o programador possui um maior controle do código.
Aplicações Híbridas – conjunto de entidades possui tanto conteúdo do tipo declarativo quanto procedural. Frequentemente fazem uso de scripts, cujo conteúdo é de natureza procedural.
    A seção a seguir descreve a linguagem Lua que pode ser inserida em documentos NCL, trazendo poder computacional adicional às aplicações declarativas.
2. Linguagem Lua
Lua é uma linguagem de programação em script criada em 1993, em um laboratório de pesquisa da PUC-Rio. É muito parecida com outras linguagens como Python, PHP, Ruby, ShellScript.
    Lua destaca-se pelo seu tamanho pequeno, seu núcleo é inferior a 200k, sua rapidez na execução, analistas informam que é a linguagem mais rápida das interpretadas com tipagem dinâmica, simplicidade, tem a programação simples em conformidade com as demais linguagens, portabilidade, Lua é feita com a junção de C ANSI com C++ ANSI.
    Lua é a única linguagem a ser utilizada em todo mundo, que foi desenvolvida fora dos EUA, Europa e Japão.
    Atualmente a linguagem Lua está sendo utilizada principalmente para o desenvolvimento de jogos como World of Warcraft, The Sims e Sim City, e  aplicações para TV digital interativa.
2.1 Executando lua
Um trecho de código lua pode ser entrado no modo interativo (diretamente no console lua), pode ser escrito em  um arquivo com extensão “lua” e executado pelo interpretador ou compilado e depois executado pelo interpretador.
2.1.1 Modo interativo
Para executar trechos de código do lua em modo interativo deve-se primeiro chamar o interpretador da linguagem com o comando lua no terminal, exemplo:
    $ lua
    Lua 5.1.4  Copyright (C) 1994-2008 Lua.org, PUC-Rio

    >
Com o interpretador lua em execução você pode entrar com comandos de acordo com a sintaxe da linguagem, e após teclar “enter” serão executados pelo interpretador lua, exemplo:
    $ lua
    Lua 5.1.4  Copyright (C) 1994-2008 Lua.org, PUC-Rio

    > varA = 'Hello'

    > varB = 'World'

    > print(varA .. ' ' .. varB)

    Hello World

    >

    Como podemos constatar o interpretador define dinamicamente o tipo das variáveis (varA e varB) , e ao chamar o método print ele o interpretador executa e informa a saída no console.
2.1.2 Executando arquivo pelo interpretador
Podemos executar trechos de código lua através de arquivos para isto basta criar um arquivo contendo o código e depois chamar o interpretador com o nome do arquivo como parâmetro, por exemplo:
    $ nano hello.lua
    varA='Hello '

    varB='World'

    print(varA .. varB)
    $ lua hello.lua
    Hello World

    $
    Neste caso o arquivo é compilado e depois executado.
2.1.3 Compilando e executando
Uma maneira mais eficaz de se executar trechos lua é compilando e depois executando o arquivo que contem o trecho, por exemplo:
    $ nano hello.lua
    varA='Hello '

    varB='World'

    print(varA .. varB)
    $ luac hello.lua
    $ ls *.out

    luac.out

    $ lua luac.out

    Hello World

    $
    Neste caso sua execução é mais eficaz pois o arquivo já está compilado pele luac quando o arquivo é executado não existe a necessidade de um pre compilamento.   
3. Linguagem NCL
NCL (Nested Context Languagem), Linguagem de Contextos Aninhados, é uma linguagem baseada em XML, destinada à criação de documentos hipermídia e utilizada para reunir objetos de mídia em uma apresentação multimídia. Estes objetos de mídia podem ser de qualquer tipo, aúdio, vídeo, documento HTML ou mesmo um objeto procedural.
3.1 Estrutura de um documento NCL
Todo o conteúdo de um documento NCL é definido dentro do elemento <ncl> sendo sua estrutura dividida em duas grandes partes, o cabeçalho e o corpo do documento. A figura 1 demonstra a estrutura de um documento NCL.

Figura 1


Figura 1. Estrutura de um documento NCL
    No cabeçalho são definidas as características de apresentação do documento, através das regiões e descritores, os relacionamentos que serão utilizados para a sincronização dos nós, através dos conectores, entre outras facilidades.
    No corpo definimos os elementos e a sincronização entre eles. Além da definição dos nós e elos, o corpo de um documento NCL pode também definir composições para melhorar sua estrutura e organização.
4. Integração NCL-Lua
O ambiente Ginga-NCL permite o uso de Lua dentro de aplicações NCL. Dessa forma, o poder de uma linguagem declarativa é elevado quando integrada com uma linguagem procedural. A aplicação passa a ter acesso a recursos computacionais genéricos, ou seja,  qualquer tipo de recurso que necessite estrutura de dados e algorítmicos, tais como cálculos, interação com a interface gráfica, entrada de dados por parte do telespectador,  etc.
    Esta seção descreve como é feita essa integração, a qual permite um aumento do potencial dos programas para a televisão digital.
4.1. Scripts NCLua
Os scripts NCLua usam a mesma abstração para objetos de mídia utilizada para imagens, vídeos e outras mídias. Esses scripts seguem sintaxe idêntica à de Lua e possuem um conjunto de biblioteca similar. Ou seja, a linguagem Lua possui adaptações para funcionar embutida em documentos NCL.
    O arquivo Lua deve ser escrito em uma arquivo (com extensão .lua) separado do documento NCL, que apenas o referencia como qualquer outro nó de mídia. O ciclo de vida do script é controlado pelo documento NCL que o referencia, ou seja, o NCL determina quando o programa Lua inicia.
    As bibliotecas disponíveis são divididas em quatro módulos essenciais:
Módulo event – permite a comunicação do NCLua com o formatador NCL através de eventos.
Módulo canvas – oferece uma API para desenhar primitivas gráficas e imagens.
Módulo settings – exporta a tabela settings com variáveis definidas pelo autor do documento NCL e variáveis de ambiente reservadas.
Módulo persistent – oferece uma API para exportar a tabela persistent com variáveis definidas em uma área reservada, restrita do middleware.
    A seção a seguir  propõe um estudo de caso com a implementação de uma aplicação interativa para TV Digital.
5. Aplicação proposta
A aplicação proposta informa o valor do salário líquido após o usuário fornecer o salário bruto através do controle remoto. A aplicação desconta a porcentagem de INSS conforme o valor informado.
    O objetivo é demonstrar um pouco da capacidade e interatividade das aplicações de TV Digital. A seguir é descrito o comportamento esperado:
Um campo de entrada e outro de saída são exibidos na tela.
O usuário preenche o campo de entrada.
Quando o usuário aperta a tecla ENTER, o valor do salário líquido é exibido no campo de saída.

5.1 Principais trechos da aplicação
Para execução correta da aplicação, alguns comandos são necessários, como o mapeamento do controle remoto da televisão:
    local MAP = {
['1'] = { '1', '.', ',' }

    ,['2']={'a','b','c','2'}
,['3']= 'd','e','f','3'}

    ,['4']={'g','h','i','4'}
,['5']={'j','k','l','5'}

    ,['6']={'m','n','o','6'}    ,['7']={'p','q','r','s','7'}

    ,['8']={'t','u','v','8'}    ,['9']={'w','x','y','z','9'}

    , ['0'] = { '0' }
}

    Função que calcula o salário:
    function calcula_salario(var)

        if var <= 1024.97 then

            return var - (var * 0.08)

        elseif var >= 1024.98 and var <= 1708.27 then

            return var - (var * 0.09)

        else

            return var - (var * 0.11)

        end   

    end

    Corpo da arquivo NCL da apresentação:

<body>

<port id="entryPoint" component="input"/>

<media type="application/x-ginga-settings" id="programSettings">

<property name="service.currentKeyMaster" value="inputIdx"/>
</media>

<media id="input" src="input.lua"  descriptor="dsInput">

<area id="select"/>

<property name="text"/>

</media>


<media id="output2" src="output.lua" descriptor="dsOutput2">

<property name="text"/>

</media>


<link xconnector="onBeginStart">

<bind role="onBegin" component="input"/>

<bind role="start"   component="output2"/>

</link>


<link xconnector="onBeginSet">

<bind role="onBegin" component="input" interface="select"/>

<bind role="set" component="output2" interface="text">

<bindParam name="var" value="$get"/>

</bind>

<bind role="get" component="input" interface="text"/>

</link>

</body>


Referências

http://www.lua.org/
http://www.ncl.org.br/
http://www.ginga.org.br/
http://www.gingancl.org.br/
http://www.gingadf.com/blogGinga/?tag=ginga-ncl
http://www.peta5.com.br/
http://www.telemidia.puc-rio.br/~francisco/nclua/

segunda-feira, 21 de junho de 2010

Exemplo processo BPMN Pedido de Férias (Com jbpm)



<?xml version="1.0" encoding="UTF-8"?>
<definitions id="Pedido de Férias-id"  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://schema.omg.org/spec/BPMN/2.0 ../../../../../../../../../../bpmn/src/main/resources/BPMN20.xsd" xmlns="http://schema.omg.org/spec/BPMN/2.0" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://jbpm.org/example/bpmn2/vacation_request" xmlns:jbpm="http://jbpm.org/bpmn2">  <process id="Pedido de Férias" name="Pedido de Férias">
<startEvent id="startNode" />
<userTask id="Formulário  de Pedido de Férias" name="Formulário  de Pedido de Férias" implementation="other"> <potentialOwner resourceRef="user">
<resourceAssignmentExpression>
<formalExpression>Usuario.Usuario</formalExpression>
</resourceAssignmentExpression>
</potentialOwner>
<rendering id="pedido-ferias.html-form">
<jbpm:form>pedido-ferias.html</jbpm:form>
</rendering>
</userTask>
<userTask id="Verificar Pedido de Férias" name="Verificar Pedido de Férias" implementation="other">
<potentialOwner resourceRef="user">
<resourceAssignmentExpression>
<formalExpression>Usuario.Usuario</formalExpression>
</resourceAssignmentExpression>
</potentialOwner>
<rendering id="verifica-pedido-ferias.html-form">
<jbpm:form>verifica-pedido-ferias.html</jbpm:form>
</rendering>
</userTask>
<endEvent id="node-aceitar-ferias-id" name="node-aceitar-ferias-name" />
<endEvent id="node-recusar-ferias-id" name="node-aceitar-ferias-id" />
<sequenceFlow id="startFlow" name="startToFistNode"
    sourceRef="startNode" targetRef="Formulário  de Pedido de Férias" />
<sequenceFlow id="Pedir Férias" name="Pedir Férias"
    sourceRef="Formulário  de Pedido de Férias" targetRef="Verificar Pedido de Férias" >
<conditionExpression xsi:type="tFormalExpression">${jbpm_outcome == 'Pedir Férias'}</conditionExpression>
</sequenceFlow>
<sequenceFlow id="Aceitar Férias" name="Aceitar Férias"
    sourceRef="Verificar Pedido de Férias" targetRef="node-aceitar-ferias-id" >
<conditionExpression xsi:type="tFormalExpression">${jbpm_outcome == 'Aceitar Férias'}</conditionExpression>
</sequenceFlow>
<sequenceFlow id="Recusar Férias" name="Recusar Férias"
    sourceRef="Verificar Pedido de Férias" targetRef="node-recusar-ferias-id" >
<conditionExpression xsi:type="tFormalExpression">${jbpm_outcome == 'Recusar Férias'}</conditionExpression>
</sequenceFlow>
</process>
</definitions>


Formulários:

Formulário de Pedido de Férias

<h1>Pedido de férias</h1>
<h2>Aqui você faz seu pedido de férias</h2>
<table border="0">
<tbody>
<tr><td>Usuário Pedido de Férias: </td>
<td><input id="usuarioPedidoFerias" name="usuarioPedidoFerias" type="hidden" value="#{userLogin}" />
    #{userLogin}
</td></tr>
<tr><td>Dias de férias: </td>
<td><input id="diasFerias" name="diasFerias" type="text" value="${diasFerias}" /></td>
</tr>
</tbody>
</table>


Formulário de Verificação de Férias

<h1>Verificação de pedido de férias</h1>
<h2>Dados do pedido de férias:</h2>
<table border="0">
<tbody><tr><td>Usuário: : </td>
<td><input id="usuarioPedidoFerias" name="usuarioPedidoFerias" type="hidden" value="${usuarioPedidoFerias}" />
${usuarioPedidoFerias}</td>
</tr><tr><td>Quantidade de  dias: </td><td><input id="diasFerias" name="diasFerias" type="hidden" value="${diasFerias}" />${diasFerias}</td></tr>
</tbody>
</table>