×

Langue

Fermer
Atelier 801
  • Forums
  • Dev Tracker
  • Connexion
    • English Français
      Português do Brasil Español
      Türkçe Polski
      Magyar Română
      العربية Skandinavisk
      Nederlands Deutsch
      Bahasa Indonesia Русский
      中文 Filipino
      Lietuvių kalba 日本語
      Suomi עברית
      Italiano Česky
      Hrvatski Slovensky
      Български Latviešu
      Estonian
  • Langue
  • Forums
  • /
  • Transformice
  • /
  • Modules
  • /
  • [Tutorial] O básico de coroutines
[Tutorial] O básico de coroutines
Esh
« Censeur »
1460812860000
    • Esh#0095
    • Profil
    • Derniers messages
    • Tribu
#1
  0
I. Introdução

    Coroutines é um ótima forma de evitar runtime em seu script, e é bastante utilizada para executar ações mais complexas/pesadas. É bastante simples de inicializar uma: coroutine.create utiliza apenas um argumento, que é a função que o thread - coroutine - irá inicializar.

II. Inicializando uma coroutine

    Para inicializar uma coroutine, utilizamos coroutine.create com o código que queremos executar dentro de uma função:

      thread = coroutine.create(function()
        for player, data in pairs(tfm.get.room.playerList) do
          tfm.exec.movePlayer(player, 0, 0, false, 0, -50, false)
        end
      end)

    Como podemos ver, a função dentro de coroutine.create está segurando um código que irá fazer todos os jogadores na sala saltarem. Ao utilizar coroutine.status, poderemos checar o status da coroutine criada:

      thread = coroutine.create(function()
        for player, data in pairs(tfm.get.room.playerList) do
          tfm.exec.movePlayer(player, 0, 0, false, 0, -50, false)
        end
      end)
      print(coroutine.status(thread))

    Ao executar este código, percebemos que o valor retornado é "suspended", pois uma coroutine não é inicializada ao ser criada, para isto devemos utilizar coroutine.resume, que permite a inicialização do código dentro da coroutine:

      thread = coroutine.create(function()
        for player, data in pairs(tfm.get.room.playerList) do
          tfm.exec.movePlayer(player, 0, 0, false, 0, -50, false)
        end
      end)
      coroutine.resume(thread)
      print(coroutine.status(thread))

    Agora vemos que a coroutine foi executada, e que o status retornado é "dead".

III. Suspendendo coroutines temporariamente

    Graças a função coroutine.yield(), é possível pausar uma execução de código dentro da coroutine, e retomar o processo depois:

      thread = coroutine.create(function()
        for i = 0, 10 do
          print(i)
          coroutine.yield()
        end
      end)
      coroutine.resume(thread)
      print(coroutine.status(thread))

    Neste exemplo, a coroutine será suspensa após retornar um número do for, e ao utilizar coroutine.resume(thread) novamente, ela retornará o número seguinte, parando no yield e podendo ser reinicializada até a mesma terminar a sua função. Além disto, é possível utilizar o yield para passar argumentos para uma coroutine:

      thread = coroutine.create(function(x, y)
        coroutine.yield(x+y)
      end)
      success, result = coroutine.resume(thread, 1, 2)
      print(result)


IV. Considerações finais

    Utilizamos coroutine.create para declarar threads, e coroutine.resume para inicia-los ou para resumi-los, quando coroutine.yield() está disponível. Podemos também utilizar coroutine.status para retornar o status de uma coroutine: suspended, running e dead.


Dernière modification le 1460861160000
Malucarr
« Citoyen »
1460815140000
    • Malucarr#0000
    • Profil
    • Derniers messages
#2
  0
ótimo tópico.

nem ly nem lerey

Dernière modification le 1460815200000
Laagaadoo
« Citoyen »
1460818080000
    • Laagaadoo#0000
    • Profil
    • Derniers messages
    • Tribu
#3
  0
Muito bom esh, com coroutines tbm é possível fazer contadores (3,2,1) bem facilmente, são mt uteis

Dernière modification le 1460818140000
Squalleze
« Citoyen »
1460854860000
    • Squalleze#0000
    • Profil
    • Derniers messages
    • Tribu
#4
  0
"Esta função está desabilitada na api lua do jogo." como se eu ja usei '-',

Ps.: você esta usando ela errado.

Exemplo:

cor = {}

eventPopupAnswer = function(popupId, playerName, answer)
if popupId == 1 then
coroutine.resume(cor[playerName], answer)
end
end

for playerName in next, tfm.get.room.playerList do
cor[playerName] = coroutine.create(function(playerName)
ui.addPopup(1, 2, "Nome", playerName, 100, 100)
local name = coroutine.yield()
ui.addPopup(1, 2, "Idade", playerName, 100, 100)
local idade = coroutine.yield()
ui.addPopup(1, 1, "Oe?", playerName, 100, 100)
local oe = coroutine.yield()
ui.addPopup(1, 0, string.format("Oe %s, idade %s, oe? %s", name, idade, oe), playerName, 100, 100)
end)

coroutine.resume(cor[playerName], playerName)
end


Como da para ver o "coroutine.yield()" vai pausar e retornar o valor que foi passado para o resume assim que ele for chamado dnv

Dernière modification le 1460855820000
Esh
« Censeur »
1460860680000
    • Esh#0095
    • Profil
    • Derniers messages
    • Tribu
#5
  0
Squalleze a dit :
"Esta função está desabilitada na api lua do jogo." como se eu ja usei '-',

Ps.: você esta usando ela errado.

Exemplo:

cor = {}

eventPopupAnswer = function(popupId, playerName, answer)
if popupId == 1 then
coroutine.resume(cor[playerName], answer)
end
end

for playerName in next, tfm.get.room.playerList do
cor[playerName] = coroutine.create(function(playerName)
ui.addPopup(1, 2, "Nome", playerName, 100, 100)
local name = coroutine.yield()
ui.addPopup(1, 2, "Idade", playerName, 100, 100)
local idade = coroutine.yield()
ui.addPopup(1, 1, "Oe?", playerName, 100, 100)
local oe = coroutine.yield()
ui.addPopup(1, 0, string.format("Oe %s, idade %s, oe? %s", name, idade, oe), playerName, 100, 100)
end)

coroutine.resume(cor[playerName], playerName)
end


Como da para ver o "coroutine.yield()" vai pausar e retornar o valor que foi passado para o resume assim que ele for chamado dnv

Na verdade não, seu código não tem nada a ver com o explicado, houve só uma confusão minha ao utilizar o print para testar a função, já que agora o print do transformice não está mais retornando todos os argumentos, já foi corrigido :)
Tocutoeltuco
« Censeur »
1482690660000
    • Tocutoeltuco#0000
    • Profil
    • Derniers messages
#6
  0
O Bolodefchoco fez algo útil quanto as dead coroutines. Ele cria um loop mesmo quando ela já está morta
Code Lua

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
infcoroutine = setmetatable({},{
__newindex = function(list,index,value)
if type(value) == "function" then
rawset(list,index,setmetatable({value},{
__call = coroutine.wrap(function(t,...)
t[1] = coroutine.create(value)
while true do
if coroutine.status(t[1]) == "dead" then
t[1] = coroutine.create(value)
coroutine.resume(t[1],...)
end
coroutine.resume(t[1],...)
coroutine.yield()
end
end)
}))
else
rawset(list,index,value)
end
end
})
Jellymichey
« Censeur »
1499009100000
    • Jellymichey#0000
    • Profil
    • Derniers messages
    • Tribu
#7
  0
o que eu posso fazer com as coroutines?
Gamedroit
« Citoyen »
1499029140000
    • Gamedroit#3347
    • Profil
    • Derniers messages
    • Tribu
#8
  0
gostei do tópico eu não sabia que dava para fazer coroutines no mice :v
  • Forums
  • /
  • Transformice
  • /
  • Modules
  • /
  • [Tutorial] O básico de coroutines
© Atelier801 2018

Equipe Conditions Générales d'Utilisation Politique de Confidentialité Contact

Version 1.27