Palestra2009

33
Desenvolvimento Desenvolvimento Rápido de Rápido de Aplicações com Aplicações com Tcl e XOTcl Tcl e XOTcl

Transcript of Palestra2009

Desenvolvimento Desenvolvimento Rápido de Rápido de

Aplicações com Aplicações com Tcl e XOTclTcl e XOTcl

Porque usar scripts?

● Interatividade: não há o ciclo “edita-compila-testa”.

● Menos linhas de código (alto-nível).● Melhor representação dos dados (no Tcl, por

exemplo, tudo é string).● Portabilidade. (Linux (e outros unices),

Windows, Mac, mobile, embedded, ...)

O que podemos fazer com Tcl?

● MITO: linguagens de script são muito lentas, não devem ser usadas em aplicações velozes (processamento de vídeo, por exemplo)

● REALIDADE: só uma pequena fração do código precisa ter velocidade extrema; scripts nos fornecem mais controle, flexibilidade e menos linhas de código.

Starkits

● Scripts e extensões encapsulados em um único arquivo (.kit), portável (Linux/Windows/Mac)

● Executável separado para cada plataforma: tclkit, tclkit.exe

● Diretório virtual. Pode conter scripts, bibliotecas (multiplas versões, uma para cada OS), documentação. Implementado no topo do banco de dados Metakit.

Manipulando kits

● Utilitário sdx● sdx qwrap programa.tcl

– Gera um kit a partir do script fornecido● sdx unwrap programa.kit

– Expande o kit como o diretório programa.vfs

● sdx wrap programa.kit– Reempacota o kit usando o diretório programa.vfs

– Opcionalmente, podemos usar -runtime tclkit para produzir um starpack (tudo em um só executável).

Bibliotheca

Bibliotheca (2)

● Cada livro é representado por uma imagem (capa) de tamanho reduzido.

● Formatos dos arquivos (livros): pdf, djvu, chm, ps,...(outros podem ser suportados facilmente)

● Comandos para incluir novos livros, reorganizar as “estantes”, criar ícones para um livro, ou até para transferir o conteúdo (ssh) a partir de um servidor.

Bibliotheca (3)

● Informações sobre livros armazenados numa lista:

<arquivo_do_livro> <ícone> <estante>

● Todos os livros localizados em um diretório único, configurável.

● Ícones de tamanho até 96x128 pixels, variável.

● Cada “estante virtual” agrupa livros de assunto similar.

Bibliotheca (4)

Bibliotheca (5)proc showDoc {fn} {global Pafter cancel setupButMotionswitch [file extension $fn] {

".Chm" -".chm" {

set P(chan) [open "|xchm \"$fn\"" r+] }".Pdf" -".pdf" -".PDF" {

set P(chan) [open "|acroread \"$fn\"" r+] }".djvu" { set P(chan) \

[open "|djview \"$fn\"" r+] }default { set P(chan) [open "|gv \"$fn\"" r+] }

}fileevent $P(chan) readable \

[list execHndl $P(chan)]}

Critcl

● Permite criar novos comandos (extensões para o Tcl) em C, em scripts.package provide fork 1.0critcl::ccode {

#include <unistd.h>}critcl::cproc fork {} int {

return fork();}

● Compilado com: critcl -pkg fork● Extensão produzida pode ser incluida na

aplicação normalmente, com:package require fork

Aplicação com dual vídeo

Libavformat/avcodec + SDLinterfaceados com Tcl

● libavformat/avcodec (ffmpeg)● Decodifica vídeo/áudio● Redimensiona os quadros (video frames)

● SDL● Preenche os buffers de vídeo na tela, usando MMX

e outras tecnologias para obter maior desempenho● Tcl

● Aplicação principal: controla todo o contexto

Dual vídeo extensionpackage provide embvideo 1.0

critcl::cheaders -g -I. -DLINUX \-I/usr/local/include/ffmpeg/ -I/usr/local/include/

critcl::clibraries -L/usr/lib -L/usr/local/lib \ -lavformat -lavcodec -lavutil -lSDL -lSDL_image -lz

critcl::ccode {#include "embvideo.c"

}

::critcl::cproc vidinit { Tcl_Interp* ip int wid int dual } ok {

...return TCL_OK;

}. . .. . .

Dual vídeo extension (2)● Usa 3 buffers (shared memory) para enviar video

frames, comandos e status entre os processos de vídeo/audio, sincronizando a comunicação por meio de signals.

mmfd = open("/dev/zero",O_RDWR);

mmpixels = mmap(0,sfrw*sfrh*3, PROT_READ|PROT_WRITE, MAP_SHARED, mmfd, 0);close(mmfd);

● Comandos ofertados ao script tcl:● vidsetmovie <audio/video_filename>vidcmd <large | small>vidinit <window id> <flags>vidcheckend, vidwait, vidquit

Protocolo do libavformat

URLProtocol decrypt_protocol = { "decrypt", decrypt_open, decrypt_read, NULL /*decrypt_write*/, decrypt_seek, decrypt_close,};

decrypt:arquivo_video_audio

Registrando o novo protocolo em libavformat:register_protocol(&decrypt_protocol);

XOTcl (exotickle)

● Sistema de objetos poderoso, baseado no CLOS (Common Lisp Object System)

● Adiciona dois novos comandos apenas: Object e Class.

● Introspecção completa em todos os aspectos dos objetos através do comando standard já presente no tcl, info.

● Suporte a muitas abstrações como filtros, mixins, slots, nested classes, method forwarding, ...

XOTcl (2)

Exemplo: configurador.xotcl

● Definindo (ou adicionando) uma ou mais opções:

● config state {width 800 height 600 background “cadet blue”}

● Apagando todas as opções armazenadas:● config state -clear yes

● Obtendo todas as opções existentes:● config state

● Outros comandos: config load, config save

configurador.xotclObject config

config proc state {{-clear 0} {newstate ""}} {if {$newstate != ""} {

foreach {v contents} $newstate {my set $v $contents

}} set r {}foreach v [my info vars] {

lappend r $v [my set $v] }if $clear {

foreach v [my info vars] {my unset $v

}}return $r

}

my [self]my [self]

configurador.xotcl (3)

config proc save {filename} {set f [open $filename w]puts $f [my state]close $f

}

config proc load {filename} {set f [open $filename r]my state [read $f]close $f

}

Peculiaridades do XOTcl

● XOTcl tem caraterísticas diferentes do tradicional (C++/Java):● Sistema de classes dinâmico. Tudo pode ser mudado a

qualquer instante.● É voltado aos objetos e não às classes, ou seja, cada

objetos tem vida independente, podendo ter suas próprias “procs”, variáveis específicas do objeto, etc.

● É completamente reflexiva (um programa pode observar seu próprio comportamento e modificá-lo, se desejado).

XOTclIDE

Component browserComponent browser

Object BrowserObject Browser

Classes e Objetos

● Uma classe generaliza operações e variáveis dos objetos (instâncias).

Class CursoCurso instproc init args {

my set pre-requisitos ""}Curso instproc sethorario hr {

my set horario $hr}

Curso historia -sethorario 10:30

Precedência do nextClass TerrestreClass MaritimoTerrestre instproc desc args {return "-terrestre-[next]"}Maritimo instproc desc args {return "-maritimo-[next]"}

Class Anfibio -superclass {Terrestre Maritimo}Anfibio instproc desc args {return "-anfibio-[next]"}

Terrestre automovelMaritimo lanchalancha proc desc args {return "-lancha-[next]"}

Anfibio hovercraft hovercraft proc desc args {return "-hovercraft-[next]"}-terrestre-

-lancha—maritimo--hovercraft--anfibio--terrestre--maritimo-

Nested objects● historia contains {Object idade_media}

● Class Point -parameter {{x 100} {y 300}}Class Rectangle -parameter {color}Rectangle r0 -color pink -contains {

Rectangle r1 -color red -contains { Point x1 -x 1 -y 2 Point x2 -x 1 -y 2

}Rectangle r2 -color green -contains {

Point x1 Point x2

}}

::historia::idade_media

historia idade_media

Filtros

Object instproc exempFiltro {args} {puts "self = [self]"puts "calledproc = [self calledproc]"puts "args = $args"puts ---------------------------next

}

Class TesteClassTesteClass filter exempFiltroTesteClass umObjeto

className instproc FilterName args { pre-part next post-part }

Filtros (2)

Class PainelPainel p1Painel p2

Painel instproc observaFiltro args {puts "observaFiltro para objeto: [self]"set r [next]puts "observaFiltro (obj=[self]) retornou: $r"

}

Painel instfilter observaFiltro

● Filtros “por objeto” e “por classe”

MixinsClass AgentAgent instproc move {x y} { # do the movement}Class InteractiveAgent -superclass Agent

Class MovementLogMovementLog instproc move {x y} { # movement logging next}Class MovementTestMovementTest instproc move {x y} { # movement testing next}

InteractiveAgent i1; InteractiveAgent i2i1 mixin MovementLogi2 mixin MovementTest MovementLog

Slots

● System slots: superclass, class, mixin, instmixin, filter, instfilter.

● Attribute slots.Class Person -slots {

Attribute nameAttribute salary -default 0Attribute projects -default {}

-multivalued true}Person slot name

Person rildorildo name “Rildo Pragana”rildo name

Acessa o slot meta-objeto

A função primitiva self self – retorna o nome do objeto em execução self class – retorna a classe que define a instproc corrente self proc – retorna a proc ou instproc em execução self callingclass – retorna a classe que chamou

este método self callingobject – objeto que chamou este método self callingproc – a proc (ou método) que chamou

o método corrente self calledclass – a classe que contem essa

proc (mixins, filters) self calledproc – nome do método da proc alvo

(só em filtros). self isnextcall – retorna 1 se chamado por “next” self next – retorna o path do próximo “next” self filterreg – em um filtro: retorna o nome da classe/objeto

onde foi registrado na forma 'obj filter nomeDoFiltro' ou 'classe instfilter nomeDoFiltro'

self callinglevel – nível da chamada self activelevel – nível da pilha onde a proc foi chamada

Links interessantes

● http://www.pragana.net - Adventures in LinuxProgramming

● http://wiki.tcl.tk - Tcler's wiki (fartadocumentação!)

● http://www.tcl.tk - Tcl developer exchange● http://media.wu-wien.ac.at - XOTcl homepage● http://www.xdobry.de/xotclIDE/ - XOTclIDE

homepage● http://openacs.org - OpenACS (toolkit para

aplicações web)● http://wfr.tcl.tk - Tcler's wiki versão francesa

(independente do original)

Perguntas

? ??