Ir para conteúdo
Poccnn

tfs 0.3 Tutorial Coroutine Lua

Posts Recomendados

Fala Xtibianos. 
Nesse tutorial, gostaria de explicar um pouco sobre coroutine e seu uso. 

 

Irei começar com uma lista de funções da coroutine. 

Citar

coroutine.create (f)               cria uma nova coroutine com uma função lua valida. 
coroutine.yield (···)                suspende a execução da coroutine. 
coroutine.resume (co [, val1, ···])    passa os valores para a coroutine. 
coroutine.running ()                pega a coroutine que esteja em execução. 
coroutine.status (co)                return "suspended", "running" ou "dead"
coroutine.wrap (f)                   cria uma nova coroutine no corpo com uma função lua valida. 

 

Irei começa falando sobre a principal função da coroutine. 

Citar

coroutine.create (f) 

 

No corpo dessa função, voce precisa declarar pontos para "suspender" a execução da coroutine. 

 

Ao criar a coroutine, ela se encontra no estado "suspended", ou seja, parada/pausada. 


para iniciar a coroutine, voce precisa ativar ela usando a função: 

Citar

coroutine.resume (co [, val1, ···]) 

 

Além de ativar/reativar a coroutine, você passa valores para a função da coroutine. 
A primeira ativação da coroutine, os argumentos passados não poderão ser modificados, ficam estáticos nos parâmetros da função. 

 

Citar

 

co = coroutine.create(function(a,b) 
-- verificando o estatus da coroutine. 
   print(coroutine.status(coroutine.running())) -- "running" 
   coroutine.yield(a+b) -- primeira chamada 
   coroutine.yield(a-b) -- segunda chamada 
   return a,b,"Fim da coroutine." -- chamada final usando return (facultativo). 
end) 

 

-- verificando o estatus da coroutine. 
print(coroutine.status(co))       -- "suspended" 
print(coroutine.resume(co,5,2))    -- saida >> 7 >> 5+2 
print(coroutine.resume(co,1,8))    -- saida >> 3 >> ??? 1-8 = -7 
print(coroutine.resume(co,9,55))   -- saida >> 5,2, Fim da coroutine. >> veja que são os valores passados na primeira chamada. 
-- verificando o estatus da coroutine. 
print(coroutine.status(co))       -- "dead" 

 

 

Veja que o resultado da segunda chamada não coincidem com os valores passados. Isso se dá devido aos parâmetros da função impregada na coroutine, não modificar seus valores. uma vez declarados os valores, eles não poderão ser modificados. 

 

uma chamada de coroutine a mais da quantidade de yield's existente na coroutine.

Citar

print(coroutine.resume(co,9,55))   -- saida >> cannot resume dead coroutine

 

Como demonstrado acima, ao exceder a quantidade de yield's, ela retorna essa mensagem (sem disparar erro no console). 

 

Agora você deva estar se perguntando: Então como fazer para pegar os valores que são passados em cada ativação? 


Vou explicar agora: 

a função yield pega os valores fornecidos e retorna-os; então você pode pegar esses valores usando variaveis para armazena-los. 

Citar

 

co = coroutine.create(function(a,b) 
   b,c = coroutine.yield(a+b) -- primeira chamada 
   c,d = coroutine.yield(b-c) -- segunda chamada. veja que modifiquei os parametros usados. 
   return c,d,"Fim da coroutine." -- chamada final usando return (facultativo). 
end) 

print(coroutine.resume(co,5,2))    -- saida >> 7 >> 5+2 
print(coroutine.resume(co,1,8))    -- saida >> -7 >> 1-8 << agora o resultado está certo, pois foi usados os valores passados pela segunda chamada. 
print(coroutine.resume(co,9,55))   -- saida >> 9,55, Fim da coroutine. << os dois numerais, são os valores passados na ultima chamada.

 

 

 

Mas, no corpo da função criada para a coroutine, você pode fazer chamadas a funções, pegar valores de variaveis globais, etc; sempre usando a função yield para "suspender" a coroutine. 

 

Citar

 

function add(a,b) 
   return coroutine.yield(a+b,"Valor retornado pela função add()") 
end 

m,n = 2,3 

co = coroutine.create(function(a,b) 
   c,d = add(a,b) 
   e,f = add(m,n) 
   return e,f, "Fim da coroutine." -- retorna os valores da ultima chamada. 
end) 

print(coroutine.resume(co,5,2))    -- saida >> 7, "Valor retornado pela função add()" >> 5+2 
print(coroutine.resume(co,1,8))    -- saida >> 5 >> "Valor retornado pela função add()" >> valores pegos das variaveis externa 'm' e 'n' >> 2+3 
print(coroutine.resume(co,9,55))   -- saida >> 9,55, Fim da coroutine. << os dois numerais, são os valores passados na ultima chamada.

 

 

Agora só falta comentar sobre a função: 

Citar

coroutine.wrap(f)

 
Assim como coroutine.create, a função auxiliar coroutine.wrap cria uma nova co-rotina, mas ao invés de retornar uma referência para a co-rotina, retorna uma função que, quando chamada, (re)invoca a co- rotina. 


De forma geral, a função coroutine.wrap oferece uma maior conveniência que coroutine.create; ela provê exatamente o que é usualmente necessario: uma função para reativar uma co-rotina. Por outro lado, o uso das funções coroutine.create e coroutine.resume permite o gerenciamento de erros (funções estas que não podem ser usada por wrap). 

 

Citar

 

-- fatorar o valor 
function fatorar(n) 
   if n > 1 then 
      coroutine.yield(n) 
      fatorar(n/2) -- recursividade 
   end 
end 

-- iterador 
iterator = coroutine.wrap(function(value) 
      fatorar(value) 
   end) 

print(iterator(32)) -- 32 
print(iterator())   -- 16 
print(iterator())   -- 8 
print(iterator())   -- 4 
print(iterator())   -- 2 
print(iterator())   -- 1 
print(iterator())   -- Disparado erro com mensagem: "cannot resume dead coroutine". 

 


A função retornada por coroutine.wrap não captura erros; qualquer erro provocado pela execução da co-rotina é propagado a seu chamador. 

 

É isso ai pessoal, espero que tenham gostado. qualquer duvida, sugestão ou critica, deixem nos comentários. 
 

Compartilhar este post


Link para o post
Compartilhar em outros sites
2 horas atrás, Poccnn disse:

@kttallan

Qual sua dificuldade em aprender? 

Bom eu fazia codigos antigamente, participei da primeira escolinha de scripting do xtibia a qual o roksas era o professor aprendi tudo até criar funções, hoje sei da logica só que não sei muito sobre.

 

For, While e Repeat e Strings, Table, Creio que o resto eu saiba como criar funções etcs..

Compartilhar este post


Link para o post
Compartilhar em outros sites
Em 08/12/2016 at 21:33, newFag disse:

O que é uma corrotina em lua? É tipo um thread?

 

Não é uma thread. É um processo executado em modo separado.

 

1 hora atrás, Everson Miranda disse:

amigao vc e genial porem sou um pouco leigo na area de programação.. poderia me explicar oque seria coroutine e em que tipo de situação é aplicado?

 

Coroutine é uma forma de criar um processo que oode parar sua execução a qualquer momento e podendo retornar a execução a pedido do sistema.

É difícil fazer uma implementação dela no mundo do ot server, mas eu fiz essa:

 

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Caro membro,

Seu tópico foi movido de

Please login or register to see this link.

 para

Please login or register to see this link.

.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisar ser um membro para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar Agora

  • Conteúdo Similar

    • Por Marshmello
      Fala pessoal Então tava sem nada pra fazer decidir ajudar um pouco quem ta começando
       
      Trazendo Exemplo de quest (tanto item e pokemon)
       
      Então vamos lá
       
      Exempo de quest Que ganha Item
      --[[ Script: Exemplo Quest Item AUTOR: Brendo Hiesttfer EMAIL: [email protected] ]] function onUse(cid,item,fropos,topos) storage = 587954 -- Storage da quest (troque quando for fezer outra quest) item = 9999 -- id do Item valor = 1 -- quantidade de item que o player vai ganhar na quest itemname = "NomeItem" -- nome do Item que vai ser ganho na quest level = 1 -- Level minimo para completar a quest if getPlayerStorageValue(cid,storage) == -1 then if getPlayerLevel(cid) >= level then doPlayerAddItem(cid,item,Valor) doPlayerSendTextMessage(cid,25, "Parabéns você ganhou um "..itemname.." como premio") -- Msg ao completar a quest setPlayerStorageValue(cid,storage,1) else doPlayerSendTextMessage(cid, 26, "Desculpe, mais você precisa ter no minimo level "..level.." para completar a quest") --- Msg quando não tiver o level end else doPlayerSendTextMessage(cid,26, "Você já pegou oque estava dentro") -- Msg quando tentar fazer novamente end return true end  
      EXEMPLO QUEST QUE GANHA POKEMON:
      --[[ Script: Exemplo Quest Pokemon AUTOR: Brendo Hiesttfer EMAIL: [email protected] ]] function onUse(cid,item,fropos,topos) storage = 587954 -- Storage da quest (troque quando for fezer outra quest) pokemon = "Pikachu" -- Pokemon Que o player vai ganhar TypeBall = "Normal" -- type da ball level = 1 -- Level que precisa para completar a quest if getPlayerStorageValue(cid,storage) == -1 then if getPlayerLevel(cid) >= level then addPokeToPlayer(cid,pokemon,0 ,nil ,TypeBall) doPlayerSendTextMessage(cid,25, "Parabéns você ganhou um "..pokemon.." como premio! ") -- Msg ao completar a quest setPlayerStorageValue(cid,storage,1) else doPlayerSendTextMessage(cid, 26, "Desculpe, mais você precisa ter no minimo level "..level.." para completar a quest") --- Msg quando não tiver o level end else doPlayerSendTextMessage(cid, 26, "Você já fez essa quest") -- Msg quando tentar fazer novamente end return true end E isso coisa simples para quem está começando agora com poketibias , abraços ♥
    • Por moskitinho
      Olá camaradas,
       
      Voltei ao fórum depois de anos e queria encontrar alguém para me ajudar num projeto de OT 8.6 o mapa esta pronto, o que falta é configurar as quests e eventos. Eu procurei em fóruns e tutoriais de todas as maneiras, mas não consegui aprender. As distros de hoje em dia vem com muitos scripts bagunçados e fica difícil pra aprender apenas copiando. Porque na maioria dos casos o que funciona em um server não funciona no outro.
       
      Então deixo registrado aqui meu pedido.
       
      Procura-se um Action/Script Maker
       
      Moskitinho o que é esse projeto?
      - É um OT Server 8.6 com mapa próprio.
      - A cidade principal é Carlin que foi renomeada para Draenor. E modificada para se ajustar a parte do RPG.
      - As hunts serão por portal (mas nada de caves sem graça e cheia de retas) usei respawns famosos do global para melhorar o aspecto visual das hunts.
      - Não teremos itens VIP ou mesmo o VIP System. Todos os jogadores tem acesso à 100% do conteúdo. (Sujeito a modificação)
      - Vocações balancedas. (fast attack moderado e os regens de mana e life configurados corretamente para não ser tão fácil)
      - Sou um RPG Maker e talvez muitos pensem que OTs com rates altas não consigam juntas ambas as coisas, mas é essa barreira que quero derrubar.
      - As rates começam em 600x e param em 3x a partir do nível 800. (Tudo sujeito a modificação depois de testes)
       
      O que precisa saber?
      - Configurar quests como Annihilator, Demon Helmet, Pits of Inferno, Inquisition e Wrath of the Emperor. 
       
      Obs.: A maior parte destas quest no server foi diminuída ou modificada para facilitar.
       
      Horários?
      - Sem pressa amigo, trabalhe em tempo livre. Eu não quero ocupar tempo, apenas concluir este projeto. Se não puder fazer, mas puder me ensinar eu aceito.
       
      Porque você deve aceitar?
      - Tenho alguns anos na área e qualquer membro antigo do Éks pode afirmar minha credibilidade. Quero muito lançar esse server que é particularmente um sonho pessoal. Como disse acima eu não quero tudo na mão, estou disposto a ajudar no que puder e aprender também.
       
      Bom pessoal é isto. Os interessados por favor preencham a ficha abaixo e respondam aqui no fórum ou podem me adicionar no facebook @felipelotz ou skype f_lotz

       
       
       
      E galera volto a repetir se você não quiser configurar, mas souber e puder me ensinar eu vou ficar muito grato.
       
      Agradeço desde já,
      Felipe.
       
       
       
    • Por LLossavaro
      Olá pessoal, estou procurando um scripter LUA avançado para meu servidor de pokemon, preços a combinar, estamos com meta para abrir no meio do ano.
       
    • Por meubk
      Venda proibida!
    • Por login12
      Estou procurando alguem para realizar uma modificação em minha Source.

      Posso pagar pelo serviço!



      Preço: ( à combinar )

      Preciso o mais rápido possível, então se você é scripter, e se considera profissional, ou seja que entende

      do assunto, por favor poste neste topico.







      Deixe seu skype, ou facebook se possivel

      __

      Obrigado

×