State machines (automata) - [BEP]AcerPilot - 23.07.2011
State machines (automata)
O que й, para que serve e como usar
Introduзгo
Se vocк nunca leu a
pawn lang, й quase 100% de certeza que nгo conhece state machines, ou automata. Atй hoje, nunca vi NENHUM script lanзado que utilize automata, o que й uma vergonha, jб que esse mйtodo й muito ъtil. Mas tambйm existem algumas pessoas que leram, e sabem o que sгo. Umas delas sou eu, e por isso estou fazendo este guia. PAWN
nativamente suporta um sistema chamado state machines, ou automata, que basicamente permitem que vocк use mъltiplas cуpias da mesma funзгo para diferentes circunstвncias.
Antes de comerзamos, quero deixar uma coisa clara:
State machines, ou automata, nгo foram feitos para serem usados como arrays, pois nгo podem possuir indexes, ou seja, vocк nгo poderб usar automata com fins de gerenciar as aзхes cada player, por exemplo.
Exemplo
Vamos usar o seguinte cуdigo como exemplo:
pawn Код:
new print;
forward PrintShit();
main()
{
print = 0;
SetTimer("PrintShit", 1000, 1);
}
public PrintShit()
{
if(print == 1)
{
print("Estamos mostrando uma frase no console.");
}
else
{
return 1;
}
}
public OnPlayerCommandText(playerid, cmdtext[])
{
if(strcmp(cmdtext, "/print", true) == 0)
{
if(print == 0)
{
print = 1;
}
else
{
print = 0;
}
}
return 0;
}
Esse й o cуdigo mais simples em que consegui pensar. Como podem ver, a funзгo 'PrintShit' mostra uma frase no console se a variбvel 'print' for igual a 1, de 1 em 1 segundo. Se print for igual a 0 nada acontece. Com o comando /print podemos ligar/desligar essas mensagens. Mas podemos melhorar muito este cуdigo:
pawn Код:
#include <a_samp>
forward PrintShit();
main()
{
state print:no;
SetTimer("PrintShit", 1000, 1);
}
public PrintShit() <print:yes>
{
print("Estamos mostrando uma frase no console.");
}
public PrintShit() <print:no>
{
return 1;
}
public OnPlayerCommandText(playerid, cmdtext[]) <print:no>
{
state (strcmp(cmdtext, "/print", true) == 0) print:yes;
return 0;
}
public OnPlayerCommandText(playerid, cmdtext[]) <print:yes>
{
state (strcmp(cmdtext, "/print", true) == 0) print:no;
return 0;
}
Usando automata, o cуdigo fica mais limpo e tambйm mais rбpido por ser nativamente suportado pela linguagem.
Uma coisa importante a ressaltar й que a diretiva 'state' pode ter condicionais dentro da mesma. Essa linha:
pawn Код:
state (strcmp(cmdtext, "/print", true) == 0) print:yes;
Corresponde a:
pawn Код:
if(strcmp(cmdtext, "/print", true) == 0)
{
state print:yes;
}
Vantagens
Usando automata, nгo precisamos usar variбveis globais, ou seja, nгo usamos espaзo a mais na memуria, e o cуdigo fica mais limpo e mais rбpido, como disse anteriormente, alйm de nгo precisar de enormes 'if's e 'else's ou grandes estruturas como 'switch', com automata vocк pode criar vбrios 'PrintShit's, 'OnGameCommandText's etc. Nгo hб problema nenhum em usar a mesma automata em vбrias funзхes ao mesmo tempo.
Explicaзгo
Agora que jб vemos alguns exemplos e sabemos como funciona vamos olhar mais detalhadamente no cуdigo:
- state
Isso coloca a automata 'a' dentro do estado 's' (tambйm existem estados indeclarados, para mais informaзхes leia a pбgina 37 da pawn lang). Diferentemente de variбveis, automatas nгo precisam ser declaradas globalmente, pois o prуprio compilador lhe poupa desse trabalho, do contrбrio nгo seria possнvel usar automatas em qualquer funзгo do teu script, mas й preciso declarar a automata em alguma funзгo, no caso a fiz em main().
Como falei anteriormente, vocк pode usar condicionais dentro da diretiva 'state':
Isso equivale a:
Naturalmente vocк pode escolher qual mйtodo usar.
- Funзхes
Uma funзгo pode ter vбrias cуpias delas mesma para serem usadas em vбrias circunstвncias, afinal esse й o principal 'recurso' da automata. Vocк pode orientar uma funзгo para nгo ter estados, ter apenas um, vбrios, ou ser chamada se todos os outros estados nгo forem vбlidos.
- Nenhum estado
pawn Код:
stock Math()
{
new x = 2;
new y = 4;
printf("%i", y-x);
}
Essa funзгo й sempre chamada independentemente do estado de qualquer automata.
- Um estado
pawn Код:
stock Math() <calcs:on>
{
new x = 2;
new y = 4;
printf("%i", y-x);
}
Essa funзгo й chamada se a automata 'calcs' estiver no estado 'on'.
- Estados mъltiplos
pawn Код:
stock Math() <calcs:on, calcs:always>
{
new x = 2;
new y = 4;
printf("%i", y-x);
}
Essa funзгo й chamada se a automata 'calcs' estiver no estado 'on' ou 'always'.
Quando se usa nъmeros como estados, precisa-se adicionar um underline ('_') antes do nъmero, pois sнmbolos nгo podem comeзar com nъmeros, como no exemplo:
pawn Код:
stock Math() <calcs:_1, calcs:_2>
{
new x = 2;
new y = 4;
printf("%i", y-x);
}
- Outros estados
pawn Код:
stock Math() <>
{
new x = 2;
new y = 4;
printf("%i", y-x);
}
Essa funзгo й chamada quando o estado da automata 'calcs' nгo corresponde a nenhum outro estado explнcito no script.
- entry
Й uma funзгo especial que funciona como uma callback. A callback OnPlayerCommandText nгo й chamada quando o jogador envia um comando? A 'entry' й chamada quando se muda o estado de uma automata.
O cуdigo:
pawn Код:
main()
{
print("Hello");
state printstring:sure;
print("World");
}
entry() <printstring:sure>
{
print("Fuckin'");
}
Iria fazer mostrar no console:
Pois quando se alterou o estado da automata 'printstring', a funзгo 'entry' correspondente foi chamada e executou a funзгo que estava contida dentro da mesma.
Conclusгo
Espero que todos tenham entendido. Qualquer dъvida, nгo hesite em perguntar. Para mais informaзхes, leia a
pawn lang a partir da pбgina 37.
Re: State machines (automata) -
Macintosh - 23.07.2011
Gostei do tuto

Parabйns hehe
Re: State machines (automata) -
ViniBorn - 23.07.2011
Bom tutorial. ; )
Acho que poucos sabem da existкncias dessas estruturas
Re: State machines (automata) -
GPenner - 23.07.2011
Estб ai uma coisa que eu nгo sabia, vou passar a utilizar esse meio, que alйm de facilitar, deixa o script pequeno e й rбpido.
a бrea portuguesa precisa de tutoriais assim, e nгo tutoriais que ensinam a editar GF!
Muito bom.
Re: State machines (automata) -
steki. - 23.07.2011
aff. Eu nгo sabia disso D:
Re: State machines (automata) -
Shadoww5 - 23.07.2011
Se eu nгo me engano, jб vi um tutorial sobre este mesmo assunto feito pelo ******.
De qualquer forma, parabйns pelo belo tutorial =D
Re: State machines (automata) -
wallon - 23.07.2011
awesome

#nensabiasquessasporraexistia D:
Re: State machines (automata) -
RockFire - 23.07.2011
Quote:
Originally Posted by Luнs Miki
aff. Eu nгo sabia disso D:
|
Muito menos eu ._.
Re: State machines (automata) -
Ricop522 - 23.07.2011
Jб sabia, porйm acho inъtil elas.
bom tutor
Re: State machines (automata) - [BEP]AcerPilot - 23.07.2011
Obrigado a quem gostou, й meu primeiro tutorial.
@Ricop: Nгo ache isso! Sу sгo inъteis pra quem nгo sabe utilizб-las. Leia a seзгo 'Vantagens' e verб que sгo muito boas. Obrigado por achar bom meu tutorial.
@GPenner: Tambйm penso assim, cada dia que venho aqui nгo vejo um tutorial sobre coisas realmente importantes, sу tutoriais de como criar 'org's, como criar npc, como criar infoorg, como criar isso e aquilo. Nгo que eu tenha algo contra quem cria tutoriais sobre isso, sу acho que deveriam postar mais coisas que realmente importam quando o assunto й PAWN.
@Shadow: Sim, ****** tambйm fez um tutorial assim. Como й meu primeiro tutorial, eu fiz o nome das seзхes baseado no dele, apesar de ter conhecimento sobre o que eu estava escrevendo e os cуdigos serem completamente diferentes. Nгo й e nem deve ser considerado uma traduзгo nem uma cуpia.
Ah, pra quem quiser saber, sim, jб li a pawn lang e tenho ela impressa como livro.