Gotos Globais -
ipsBruno - 29.09.2013
Nгo й um lanзamento, nem um pedido de ajuda. Apenas criei este tуpico para discutir, e mostrar uma coisa que estou tentando fazer hб algum tempo. Nгo funcionou durante muitas tentativas, apуs algum tempo consegui fixar a arrumar meio por completo.
Basicamente, consegui mudar o modo de execucaзгo de Pawn, simulando um GOTO — consegui interromper um cуdigo e pular para outra бrea de memуria, totalmente distinta, sem qualquer vinculo com as callbacks.
Veja o exemplo abaixo:
pawn Код:
#include <a_samp>
#pragma dynamic 65335
// definiзхes para uso
#define goto<%0> \
global_step(#%0)
#define glabel<%0> \
globalLabel(#%0)
forward bruno2(brusno, bruno);
public bruno2(brusno, bruno) {
new b;
new string[] = "teste";
goto<l>;
#pragma unused b
#pragma unused string
return 1;
}
forward bruno1();
public bruno1() {
new b;
new string[] = "teste";
print("1");
print("2");
print("3");
glabel<l>;
print("4");
#pragma unused b
#pragma unused string
print("5");
}
main() {
SetTimerEx("bruno1", 1000, false, "i", 0); // chamar a public 1 e imprimir 1,2,3,4,5
SetTimerEx("bruno2", 2000, false, "ii", 0,0); // chamar public 2 para dar goto na public 1
}
stock globalLabel (name []) {
static beh;
// carregar valor da variбvel puxada na callback anterior
#emit load.s.pri 4
// salvar o endereзo dela em beh
#emit stor.pri beh
// salvar goto em propriedade, para poder puxar pelo nome strng
setproperty(.id = 0, .name = name, .value = beh);
setproperty(.id = 1, .name = name, .value = _: true);
return true;
}
stock global_step(label[])
{
// puxar o endereзo de execuзгo do meu goto por strng
static beh;
if( !getproperty(1,label) ) return printf("ERROR ON LABEL: %s (not executed)", label);
beh = getproperty(0,label);
// carregar endereзo de execuзгo antigo
#emit load.pri beh
// adicionar 28 sobreo valor atual de pri, para que pule o cуdigo GOTO
//#emit add.c 28
// fechar registro, e passar PRI para o CIP.
#emit sctrl 6
return 0xffffffff;
}
No exemplo abaixo, eu executo a callback
bruno1 imprimindo 1,2,3,4,5. Tudo bem, entгo em outro temporizador, executo
bruno2, mas aн que estб o detalhe. No bruno2 tem uma interrupзгo de memуria, que envia diretamente para callback bruno1.
Atй aн tudo bem, certo? Nгo.
Ao invйs de ele fazer uma chamada comum, como CallRemoteFunction, CallLocalFunction ou atй mesmo bruno1(); por si prуprio, ele faz algo diferente. Ele chama a funзгo, mas comeзa a executar ela pela metade imprimindo 4,5 (e nгo 1,2,3). Executando um GOTO, sу que intercalando callbacks.
Dissertem!
Re: Gotos Globais -
PT - 29.09.2013
isso e porque as funcoes 4,5 sao mais rapidas e sao chamadas primeiro que as outras? ou e erro de codigo?
Re: Gotos Globais -
ipsBruno - 29.09.2013
Й uma coisa meio avanзada, й similar o mйtodo como o y_inline de ****** trabalha. Sу que aн, ele interrompe o cуdigo e manda para o label definida atravйs de goto<>. Й como se chamasse a callback pela metade.
Tipo:
pawn Код:
main() {
label:
print("bruno");
goto label;
}
Assim, vocк faz um loop. Usando o cуdigo que eu tenho, vocк pode dar goto para outras callbacks. O que nгo era possнvel sem #emit.
pawn Код:
main() {
glabel<conexao>;
print("callback1");
func();
}
func () {
print ("callback2");
goto<conexao>;
}
Код:
[09:20:22] callback1
[09:20:22] callback2
[09:20:22] callback1
[09:20:22] callback2
[09:20:22] callback1
[09:20:22] callback2
[09:20:22] callback1
[09:20:22] callback2
[09:20:22] callback1
[09:20:22] callback2
[09:20:22] callback1
[09:20:22] callback2
[09:20:22] callback1
[09:20:22] callback2
[09:20:22] callback1
[09:20:22] callback2
[09:20:22] callback1
[09:20:22] callback2
[09:20:22] callback1
[09:20:22] callback2
[09:20:22] callback1
[09:20:22] callback2
[09:20:22] callback1
[09:20:22] callback2
[09:20:22] callback1
[09:20:22] callback2
[09:20:22] callback1
[09:20:22] callback2
[09:20:22] callback1
[09:20:22] callback2
[09:20:22] callback1
Se fazer com GOTO:
pawn Код:
main() {
conexao:
print("callback1");
func();
}
func () {
print ("callback2");
goto conexao;
}
darб erros, veja:
Quote:
grandlarc.pwn(31) : error 019: not a label: "conexao"
|
Re: Gotos Globais -
PT - 29.09.2013
e se fizer como fez la em cima
pawn Код:
func ()
{
conexao:
print ("callback2");
goto conexao;
}
?
Re: Gotos Globais -
Juniiro3 - 29.09.2013
Quote:
Originally Posted by ipsBruno
O que nгo era possнvel sem #emit.
|
O intuito desse tуpico й provar que #emit й ъtil ? Se for, isso jб foi provado nos seus tutorias
Re: Gotos Globais -
WLSF - 29.09.2013
O cуdigo ficou interessante, porque vocк estб criando pontos de continuaзгo em callbacks diferentes. Mas eu nгo vejo muito progresso nisso... O goto em si jб й uma coisa feia, assim como break, vocк estб quebrando uma linha de raciocнnio, que poderia ter sido feita com lуgica simples.
Vocк me deu algumas ideias em relaзгo a esses posts sobre #emit...
Re: Gotos Globais -
Magnus' - 29.09.2013
Quote:
Originally Posted by Willian_Luigi
O cуdigo ficou interessante, porque vocк estб criando pontos de continuaзгo em callbacks diferentes. Mas eu nгo vejo muito progresso nisso... O goto em si jб й uma coisa feia, assim como break, vocк estб quebrando uma linha de raciocнnio, que poderia ter sido feita com lуgica simples.
|
Eu estava tentando pensar em uma maneira de expressar isso, mas nгo consegui. Sу excluo a parte do break, pois break nгo quebra o raciocнnio, ele apenas encerra um loop :3
pawn Код:
new array[50],i;
array[30] = true;
for(i=0; i<50;i++) if(array[i]) break;
print("O valor onde i й verdadeiro й %d", i);
Considero que o
break й como um return que sу encerra o loop.
Re: Gotos Globais -
PT - 29.09.2013
Quote:
Originally Posted by Magnus'
Eu estava tentando pensar em uma maneira de expressar isso, mas nгo consegui. Sу excluo a parte do break, pois break nгo quebra o raciocнnio, ele apenas encerra um loop :3
pawn Код:
new array[50],i; array[30] = true; for(i=0; i<50;i++) if(array[i]) break; print("O valor onde i й verdadeiro й %d", i);
Considero que o break й como um return que sу encerra o loop.
|
uso o break em 1 comando quando usa loop e quero que o playerid id seja por exemplo o unico a ser kickado... isso encerra o loop e nao deixa os outros ser kickados...
Re: Gotos Globais -
WLSF - 29.09.2013
Quote:
Originally Posted by Magnus'
Eu estava tentando pensar em uma maneira de expressar isso, mas nгo consegui. Sу excluo a parte do break pois break nгo quebra o raciocнnio, ele apenas encerra um loop :3
pawn Код:
new array[50],i; array[30] = true; for(i=0; i<50;i++) if(array[i]) break; print("O valor onde i й verdadeiro й %d", i);
break й como um return que sу encerra o loop.
|
O break muitas vezes й uma utilidade para pessoas que nгo encontraram a condiзгo certa para utilizar no seu loop.
Й por isso que eu prefiro dizer que ele quebra a linha de raciocнnio.
Se vocк tem certeza que um dos valores inseridos tem de ser verdadeiro, por que vocк vai mandar rodar x vezes e ficar verificando, se pode fazer isso logo na condiзгo de parada do loop ?
pawn Код:
new i, array[] = {0,0,0,0,3,0};
for (i = 0; !array[i]; ++i) {}
printf("%d й verdadeiro", i);
Re: Gotos Globais -
Magnus' - 29.09.2013
Quote:
Originally Posted by Willian_Luigi
O break muitas vezes й uma utilidade para pessoas que nгo encontraram a condiзгo certa para utilizar no seu loop.
Й por isso que eu prefiro dizer que ele quebra a linha de raciocнnio.
pawn Код:
new i, array[] = {0,0,0,0,3,0}; for (i = 0; !array[i]; ++i) {}
printf("%d й verdadeiro", i);
|
Concordo com vocк que nesse caso o break poderia ser poupado, mas nгo й sempre que nos deparamos com uma condiзгo tгo simples, por isso ainda prefiro usar o break. Essa lуgica usada tambйm daria facilmente um stack overflow e encerraria o bloco inteiro.