Dica para poupar muito tempo com savescreen e restscreen
Moderador: Moderadores
Dica para poupar muito tempo com savescreen e restscreen
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 ()
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 131 vezes
- JoséQuintas
- 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
Uso isso, e dá pra simplificar.
Fiz digitando no post, sem testes.
O que uso salva coordenadas e até cores, porque também uso pra abrir sub-janelas.
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
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/
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/
Dica para poupar muito tempo com savescreen e restscreen
Show! Faz exatamente a mesma coisa e é mais simples...rsrsrsrs....
Dica para poupar muito tempo com savescreen/restscreen MELHO
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
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
Dica para poupar muito tempo com savescreen e restscreen
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
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
- JoséQuintas
- 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
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.
Mas... assim como fazem em GUI, isso poderia ser substituído por wvgCrt() e nunca mais usar save/restore screen.
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.
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/
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/
Dica para poupar muito tempo com savescreen e restscreen
É 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..
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..
Dica para poupar muito tempo com savescreen e restscreen
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.
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.
- JoséQuintas
- 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
Mesmo que nos computadores atuais tenha mais memória.... há possibilidade de usar mais tela.lwinter escreveu:Eu vi o fonte da sua wOpen e voce ainda trabalha colocando top, left, bootom e right.
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/
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/
- JoséQuintas
- 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
Sobre as outras funções:
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/
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/
- JoséQuintas
- 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
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.
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/
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/
- JoséQuintas
- 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
Um teste simples.
Ao invés de janela normal, uma janela da GTWVG.
Isso elimina a necessidade de save/restore screen.
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
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/
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/
Dica para poupar muito tempo com savescreen e restscreen
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!
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!
