O documento discute as vantagens de usar linguagens de script como Tcl e XOTcl para desenvolvimento rápido de aplicações. Ele apresenta ferramentas como Starkits, Critcl e Bibliotheca que permitem empacotar scripts e extensões de forma portável e criar interfaces gráficas ricas. O documento também descreve como XOTcl adiciona suporte a objetos, classes, filtros e slots para Tcl, permitindo desenvolvimento orientado a objetos.
2. 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, ...)
3. 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.
4. 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.
5. 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).
7. 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.
8. 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.
10. Bibliotheca (5)
proc showDoc {fn} {
global P
after cancel setupButMotion
switch [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)]
}
11. Critcl
●
Permite criar novos comandos (extensões para
o Tcl) em C, em scripts.
package provide fork 1.0
critcl::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:
13. Libavformat/avcodec + SDL
interfaceados 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
14. Dual vídeo extension
package 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;
}
. . .
. . .
15. 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
16. 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);
17. 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
19. 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
20. configurador.xotcl
Object 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
}
} my
my [self]
[self]
return $r
}
21. 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
}
22. 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).
24. Classes e Objetos
●
Uma classe generaliza operações e variáveis
dos objetos (instâncias).
Class Curso
Curso instproc init args {
my set pre-requisitos ""
}
Curso instproc sethorario hr {
my set horario $hr
}
Curso historia -sethorario 10:30
28. Filtros (2)
●
Filtros “por objeto” e “por classe”
Class Painel
Painel p1
Painel p2
Painel instproc observaFiltro args {
puts "observaFiltro para objeto: [self]"
set r [next]
puts "observaFiltro (obj=[self]) retornou: $r"
}
Painel instfilter observaFiltro
29. Mixins
Class Agent
Agent instproc move {x y} {
# do the movement
}
Class InteractiveAgent -superclass Agent
Class MovementLog
MovementLog instproc move {x y} {
# movement logging
next
}
Class MovementTest
MovementTest instproc move {x y} {
# movement testing
next
}
InteractiveAgent i1; InteractiveAgent i2
i1 mixin MovementLog
i2 mixin MovementTest MovementLog
30. Slots
●
System slots: superclass, class, mixin, instmixin,
filter, instfilter.
●
Attribute slots.
Class Person -slots {
Attribute name
Attribute salary -default 0
Attribute projects -default {}
-multivalued true
} Acessa o slot meta-objeto
Person slot name
Person rildo
rildo name “Rildo Pragana”
rildo name
31. 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