Dica para poupar muito tempo com savescreen e restscreen

Aqui você poderá oferecer suas Contribuições, Dicas e Tutoriais (Texto ou Vídeo) que sejam de interesse de todos.

Moderador: Moderadores

lwinter
Usuário Nível 3
Usuário Nível 3
Mensagens: 123
Registrado em: 07 Mar 2011 12:08
Localização: Campinas - SP

Dica para poupar muito tempo com savescreen e restscreen

Mensagem por lwinter »

Olá Pessoal, para quem ainda trabalha no console já deve se deparado com a mão de obra de ficar passando parâmetros nas funções saveScreen e restScreen. Alguns já devem ter feito libs próprias para facilitar o trabalho mas mesmo assim tenho verificado que muitos ainda passam os parâmetros de top, bottom, left e right. Ee isso, querendo ou não é ocupa um tempo precioso dos devs.
Ate entendo de onde veio esta preocupação do clipper. Antes tínhamos kilo bytes disponíveis na aplicação e economizar qualquer tipo de memoria fazia sentido. Afinal, porque guarda a janela inteira e “gastar” 2k se podíamos guardar apenas 300 bytes. Hoje com o Harbour temos disponíveis gigabytes para usarmos.
Pensando nisso crie duas rotinas bem simples que agilizam o desenvolvimento. Basta chamar openScreen () (sem parâmetros) que a função grava a tela numa pilha. Dai você pode montar a sua nova tela e ao retorna a tela anterior, basta chamar closeScreen () (também sem parâmetros) que retira a tela da pilha. Não há limites do numero de telas que podem ser empilhadas. Logo você pode chamar em cascata vários open e close.
Exemplo:
openScreen ()
@ 00,00@ say ‘minha nova tela1’
openScreen ()
@ 00,00 say ‘minha nova tela 2’
closeScreen ()
closeScreen ()

Basta incluir as rotinas assessorias junto com o seu fonte e pronto, não precisa iniciar nenhum objeto nem nada. Muito simples, e simples de programador. Caso você chamar duas closeSCreen() seguidas mesmo sem elemento na pilha a rotina não gera exceção de erro.
Exemplo:
openScreen ()
@ 00,00@ say ‘minha nova tela1’
openScreen ()
@ 00,00 say ‘minha nova tela 2’
closeScreen ()
closeScreen ()
closeScreen ()
Anexos
test_openscreen.prg
(1.03 KiB) Baixado 132 vezes
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Dica para poupar muito tempo com savescreen e restscreen

Mensagem por JoséQuintas »

Uso isso, e dá pra simplificar.

Código: Selecionar todos

STATIC wTelas := {}

FUNCTION WSave()

   AAdd( wTelas, SaveScreen() )

   RETURN NIL

FUNCTION WRestore()

   IF ! Empty( wTelas )
      RestScreen( ,,,, Atail( wTelas ) )
      ASize( wTelas, Len( wTelas ) - 1 )
   ENDIF

   RETURN NIL
Fiz digitando no post, sem testes.
O que uso salva coordenadas e até cores, porque também uso pra abrir sub-janelas.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
lwinter
Usuário Nível 3
Usuário Nível 3
Mensagens: 123
Registrado em: 07 Mar 2011 12:08
Localização: Campinas - SP

Dica para poupar muito tempo com savescreen e restscreen

Mensagem por lwinter »

Show! Faz exatamente a mesma coisa e é mais simples...rsrsrsrs....
lwinter
Usuário Nível 3
Usuário Nível 3
Mensagens: 123
Registrado em: 07 Mar 2011 12:08
Localização: Campinas - SP

Dica para poupar muito tempo com savescreen/restscreen MELHO

Mensagem por lwinter »

Refatorei para descapsular as funcoes de pilha (pushStackList e popStackList) e assim se tornarem genericas e poder ser utilizado em outras situacoes em que for necessario utilizar pila.
Alem disso as funcoes openScreen e restScreen, salvam e restauram o estado da tela (tela, estado cursor, cores e posicao col e row). Desta forma sempre que voce abrir uma nova janela por cima nao precisa mais se preocupar em guardas estes estados que consomem tempo de programacao e poluem o codigo.
Para mim esta me ajudando muito.

O modo de usar continua como no exemplo ja colocado neste post. Nao precisa passar parametro nem para a openScreen nem para restScreen. Tudo muito simples.

func pushStackList (list, elemento) // insere um elemento na pilha
aadd (list, elemento)
return list


func popStackList (list) // remove um elemento da pilha e retorna seu valor
local elemento, pos

pos := len (list)

if !empty (list)
elemento = list [pos]
adel (list, pos)
asize (list, pos - 1)
end

return elemento // se retorna nil a pilha esta vazia


func openScreen () // armazena a tela atual para abrir uma nova janela
local list, elemento

list = setStackInfoScreen ()
// o elemento contem o estado da tela/screen
elemento := { saveScreen(), setCursor (), setColor (), row (), col () }

// altd ()
pushStackList (@list, elemento)
setStackInfoScreen (list)

return nil


func closeScreen () // restaura a tela da pinha
local list, elemento

// altd ()

list = setStackInfoScreen ()
elemento := popStackList (@list)
setStackInfoScreen (list)

if !Empty (elemento)
restScreen (,,,,elemento [1])
setCursor (elemento [2])
setColor (elemento [3])
@ elemento [4], elemento [5] say ''
end

return nil
lwinter
Usuário Nível 3
Usuário Nível 3
Mensagens: 123
Registrado em: 07 Mar 2011 12:08
Localização: Campinas - SP

Dica para poupar muito tempo com savescreen e restscreen

Mensagem por lwinter »

Faltou esta funcao que na realidade foi alterada apenas o nome, o resto esta da mesma forma que a sua versao anterior deste post.

func setStackInfoScreen (screens) // get/set lista de screens da pilha
local ret
static _screens

if _screens == nil // initializa a pilha das telas
_screens = {}
end

ret = _screens

if screens <> nil
_screens = screens
end

return ret
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Dica para poupar muito tempo com savescreen e restscreen

Mensagem por JoséQuintas »

Não sei se OpenScreen() é um nome apropriado.

Além das wSave() e wRestore(), tenho wOpen(), wClose(), wAchoice() e outras.

Aqui dá uma idéia aonde uso essas wOpen(), wClose(), e wAchoice()
Pra abrir janela com/sem título, e fechar.
wopen.png
Mas... assim como fazem em GUI, isso poderia ser substituído por wvgCrt() e nunca mais usar save/restore screen.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
lwinter
Usuário Nível 3
Usuário Nível 3
Mensagens: 123
Registrado em: 07 Mar 2011 12:08
Localização: Campinas - SP

Dica para poupar muito tempo com savescreen e restscreen

Mensagem por lwinter »

É que do jeito que fiz fica mais generico nao apenas para abrir box mas para qualquer coisa. O nome eu concordo que nao ficou bom.
Ex: Vamos supor que quero salvar o estado da tela mas nao quero abrir um popup e quero fazer outra coisa. dai fica mais abrangente.
O problema é que saveScreen e restScreen ja existe. Estou aberto a sugestoes de nomes..rsrsrs..
lwinter
Usuário Nível 3
Usuário Nível 3
Mensagens: 123
Registrado em: 07 Mar 2011 12:08
Localização: Campinas - SP

Dica para poupar muito tempo com savescreen e restscreen

Mensagem por lwinter »

Estava vendo video do cleancode, e cada funcao deve fazer apenas uma coisa de vez, mesmo que esta tarefa seja grande nao importa.
Se voce pensar no meu conceito voce pode colocar a openScreen e closeScreen dentro da sua wOpen. Eu vi o fonte da sua wOpen e voce ainda trabalha colocando top, left, bootom e right. Acho isso desnecessario. Acredito que voce guarde o estado da tela em outras funcoes sua, dai esta minha funcao poderia ser utilizado em todo o seu sistema. Ou seja, estas funcoes openScreen e closeScreen sao especializadas apenas nisso.
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Dica para poupar muito tempo com savescreen e restscreen

Mensagem por JoséQuintas »

lwinter escreveu:Eu vi o fonte da sua wOpen e voce ainda trabalha colocando top, left, bootom e right.
Mesmo que nos computadores atuais tenha mais memória.... há possibilidade de usar mais tela.

25 x 80 = 2.000 caracteres
40 x 132 = 5.280 caracteres
100 x 300 = 30.000 caracteres

A diferença pode ser grande entre salvar só um pedaço ou a tela inteira.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Dica para poupar muito tempo com savescreen e restscreen

Mensagem por JoséQuintas »

Sobre as outras funções:
opcoes.png
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Dica para poupar muito tempo com savescreen e restscreen

Mensagem por JoséQuintas »

Pequena correção na rotina que postei:

Ao invés de STATIC wTelas, é THREAD STATIC wTelas

Assim, cada thread tem sua própria pilha de janelas.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Dica para poupar muito tempo com savescreen e restscreen

Mensagem por JoséQuintas »

Um teste simples.
Ao invés de janela normal, uma janela da GTWVG.
Isso elimina a necessidade de save/restore screen.

Código: Selecionar todos

PROCEDURE Main

   SetMode(25,80)
   CLS
   wvt_DrawImage( 0, 0, 24, 79, "foto.jpg" )
   hb_ThreadStart( { || test() } )
   Inkey(0)

   RETURN

FUNCTION Test()

   LOCAL oCrt

   oCrt := wvgCrt():New( ,,{ 5, 5 }, { 10, 20 },,.T. )
   oCrt:Create()
   SetColor( "W/B" )
   CLS
   @ 2, 2 SAY "test"
   Inkey(0)

   RETURN NIL
test.png
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
lwinter
Usuário Nível 3
Usuário Nível 3
Mensagens: 123
Registrado em: 07 Mar 2011 12:08
Localização: Campinas - SP

Dica para poupar muito tempo com savescreen e restscreen

Mensagem por lwinter »

Oi Jose!
Mesmo que as telas atuais sejam maiores (ex: 40 x 132 ou 100 x 300), mesmo assim o consumo de tela é irrisorio. Eu uso no maximo ate 6 telas em cascata (empilhadas) mas vamos supor que voce utilize 20 telas empilhadas. No caso da tela 100 x 300 (30.000 caracteres texto + 30.000 bytes cor clipper/harbour), voce ira consumir 60.000 * 20 = 1,2 Mega bytes de memoria. Considerando um computador pifio de 1 GB ram, voce consumiu 0,11% da memoria da maquina.
Mas convenhamos o mais comum de se usar é uma resolucao 40 x 132, eu uso a resolucao 30 x 132 (3.960 caracteres + 3.960 bytes cor), logo voce ira consumir 7.920 * 10 telas empilhadas (que considero muito ate, pelo menos para minha necessidade), resultara na utilizacao de 79 k. Como eu rodo o meu aplicativo Harbour 64 bits em ambiente com 8 GB, o percentual de consumo passa a ser de 0,0074%, ou seja nada.
Mas se voce considerar o beneficio de nao ter mais que ficar inserindo cordenada em savescreen e restscreen, nem ficar restaurando estado de cursor, cores, row, col, etc... Acho que vale muito a pena.
Outro ponto que voce colocou é que se criar uma janema CRT por cima o harbour salva o estado da tela anterior. Sim, ja verifiquei isso mas mesmo assim existem varios outros locais onde faco uso de telas em cascata e estas funcoes passam a serem importantes.
Com relacao a thread, ainda sou leigo neste assunto mas uma hora vou acabar me inteirando nisso.
Abraco a todos!
Responder