Las corutinas son simplemente funciones, "pero", que se puede salir y entrar de ellas en cualquier punto, no sólo al final con un return. Además, tienen control de errores, por lo que si fallan, no da error en lua, simplemente la corutina muere.
Realmente no seria multiproceso, pq no podemos lanzarla y imaginarnos que va sola y en paralelo con otra funcion, si no que tenemos que "re-lanzarla" cada vez.
Es decir, nos proporciona las herramientas para que nosotros nos hagamos nuestro propio planificador.
Para poner un ejemplo medio sencillo, vamos a hacer un modulo de audio para nuestro juego, como los de juegos tipo burnout y demas, donde el reproductor esta activo pero no afecta al juego.
Primero tendriamos que crear el sistema de audio, como si éste fueran funciones normales lua.
function audiomanager ( ... )-- Aqui inicializamos algunas cosas que sólo-- seran necesarias ejecutarlas una vez.local input ={ ... };local output ={};local currentsong =nil;local currentindex =1;local audiofiles ={"snd/bla.mp3",
"snd/ble.mp3",
"snd/bli.mp3"};-- A partir de aqui es lo que se ejecutará a cada ciclo.whiletruedo-- if no song, load and play.if( currentsong ==nil)then
currentsong = sound.load(audiofiles[currentindex]);
currentsong:play(5);-- canal 5.end-- if finished, next song.if( currentsong:percent()>98)then
currentindex = currentindex + 1;
currentsong:stop();
currentsong:free();
currentsong =nil;end-- if player wants next song.if( controls.released("r"))then
currentindex = currentindex + 1;
currentsong:stop();
currentsong:free();
currentsong =nil;end-- controlar rango de currentindex.if( currentindex > #audiofiles )then
currentindex =0;endif( currentindex <1)then
currentindex = #audiofiles;end-- salir de la corutina ( y volver a entrar luego por aqui ).
input ={coroutine.yield(output)};endend
Con esto, tenemos una funcion que simplemente llamandola una vez atascaría el programa, debido a el bucle, pero si lo convertimos en corutina, ese bucle se ejecutará una vez por llamada a la corutina, por que tiene el punto de interrupcion dentro del while.
Ahora, imaginamos que el juego ya lo tenemos hecho y no queremos tocar nada, y queremos que se implemente solito...
Dado que en lua podemos redirigir funciones y machacarlas, borrarlas o lo que sea ( cosa no recomendable xD ), si bien podemos aprovecharnos de este comportamiento con un poco de eficacia:
-- nos guardamos el screen flip.
old_screen_flip = screen.flip;
corutina_audiomanager =nil;-- machacamos un nuevo screen.flip para añadir funciones-- que vayamos a ejecutar a cada ciclo, y no queremos tocar-- el resto del programa...function screen.flip()-- si no hay corutina, crearla.if(corutina_audiomanager ==nil)then
corutina_audiomanager =coroutine.create(audiomanager);end-- vigilar si no esta muerta.if(coroutine.status(corutina_audiomanager)=="dead")then-- hay algun error, y murió, la borraremos para que vuelva-- a nacer en el proximo screen.flip.
corutina_audiomanager =nil;else-- la corutina sigue viva, pero a la espera, o sin primera ejecucioncoroutine.resume(corutina_audiomanager);end-- por ultimo, hacemos el viejo screen flip
old_screen_flip();end
Añadiendo esto al inicio del todo de nuestra app / juego, tendriamos audiomanager sin haber tocado el resto del programa.
Las corutinas no sirven bien bien para esto, pero es tan solo para poneros un ejemplo de como se usa.
Si me preguntais que son los tres puntos ..., son parametros de entrada, que no se cuantos seran, los guardo en inputs (tabla), asi input[0] sera el primer parametro, input[1] el segundo, #input el numero de argumentos. (vararg power). output son los resultados que se devolverian en un coroutine.resume, pero en este caso desde fuera, en el screen.flip no paso argumentos ni recibo, por lo que no me preocupan, pero si requiriese de entrada y salida de datos usaria esas variables.
Espero se entienda un poco, y si no, al manual oficial de lua ;).
Segun tengo entendido, el modulo no esta terminado y no es funcional del todo, pero se puede simular el uso de threads en un solo hilo usando un modulo improvisado que hace la funcion de threader
Thread ={}-- Se crea la tabla del modulo hilo-- Se crea un nuevo hilo que contiene la funcion "func"function Thread.new(id,func)local thr ={-- Creamos un nuevo objeto thread
id = id,
type="Thread",
data ={},
}table.insert(thr.data,func)-- Insertamos la nueva funcion al hiloreturn thr
end-- Añade un hilo a otro hilofunction Thread.add(thr_fat,thr_son)table.insert(thr_fat.data,thr_son)end-- Corre todos los hilos del objeto Thread pasado como argumentofunction Thread.run(thr)for i =1,#thr.data dolocal t = thr.data[i]iftype(t)=="function"then
t()-- Corremos la funcion del threadelseiftype(t)=="Table"and t.type=="Thread"then
Thread.run(t)-- Ejecutamos todos los hilos dentro del hilo principalendendend
No es necesario hacer tanto codigo para hacer qeu tu programa tenga multi proceso, pero si buscas un mayor control de los hilos esto te va a servir, aunqeu le faltan algunas funciones que no me dieron tiempo de llenar como estas:
function Thread.get(id)endfunction Thread.kill(id)endfunction Thread.stop(id)endfunction Thread.clone(id)end
Y yo hice una cosa supercomplicada que va a medias y me tira errores XD. Si no te importa me voy a basar en la tuya, que me gustó mucho la forma de como lo haces en Fishell.
Bien, ya entiendo como funciona la multitarea por procesos, pero sigo sin entender del todo lo de las corrutinas, por ahora, esto es todo lo que visto que las use:
Generador de números primos en Lua:
function gen (n)returncoroutine.wrap(function()for i=2,n docoroutine.yield(i)endend)endfunction filter (p, g)returncoroutine.wrap(function()while1dolocal n = g()if n ==nilthenreturnendifmath.mod(n, p) ~=0thencoroutine.yield(n)endendend)end
N=N or1000
x = gen(N)while1dolocal n = x()if n ==nilthenbreakendprint(n)
x = filter(n, x)end
toma las corrutinas como si fuesen callbacks, te sirve para hacer 2 procesos al mismo tiempo, su uso es algo mas complicado y debido a que esta incompleto no me he dado tiempo de entender bien su uso, pero lo que si se es que puedes hacer practicamente lo mismo con las corrutinas que con el metodo que te presente antes.
para que piensas usar las corrutinas si se puede saber? (para ver si podrias usar metodos mas faciles y practicos)
aaa ok, es muy bueno querer aprender cosas diferentes, pero me referia a para que proyecto la necesitas hacer? (un explorador de archivos, shell, juego?)
puede que haya algun otro metodo que te sirva mas que la corrutina y que podrias preferir usar mas
Bueno, por ahora no creo que las use con mis primeros aportes, en concreto, este ha sido mi primer aporte y ahora mismo estoy programando un reproductor de Mp3 con visualizaciones, listas de reproducción, funciones como ahorro energía y cosas así. Por ahora lo tengo en fase Alpha y aún no funciona muy bien, no creo, sinceramente, que llegue a usar las corrutinas en este projecto, pero quizás en otros sí, ya que no será mi último aporte.
corutinas
Las corutinas son simplemente funciones, "pero", que se puede salir y entrar de ellas en cualquier punto, no sólo al final con un return. Además, tienen control de errores, por lo que si fallan, no da error en lua, simplemente la corutina muere.
Realmente no seria multiproceso, pq no podemos lanzarla y imaginarnos que va sola y en paralelo con otra funcion, si no que tenemos que "re-lanzarla" cada vez.
Es decir, nos proporciona las herramientas para que nosotros nos hagamos nuestro propio planificador.
Para poner un ejemplo medio sencillo, vamos a hacer un modulo de audio para nuestro juego, como los de juegos tipo burnout y demas, donde el reproductor esta activo pero no afecta al juego.
Primero tendriamos que crear el sistema de audio, como si éste fueran funciones normales lua.
Con esto, tenemos una funcion que simplemente llamandola una vez atascaría el programa, debido a el bucle, pero si lo convertimos en corutina, ese bucle se ejecutará una vez por llamada a la corutina, por que tiene el punto de interrupcion dentro del while.
Ahora, imaginamos que el juego ya lo tenemos hecho y no queremos tocar nada, y queremos que se implemente solito...
Dado que en lua podemos redirigir funciones y machacarlas, borrarlas o lo que sea ( cosa no recomendable xD ), si bien podemos aprovecharnos de este comportamiento con un poco de eficacia:
Añadiendo esto al inicio del todo de nuestra app / juego, tendriamos audiomanager sin haber tocado el resto del programa.
Las corutinas no sirven bien bien para esto, pero es tan solo para poneros un ejemplo de como se usa.
Si me preguntais que son los tres puntos ..., son parametros de entrada, que no se cuantos seran, los guardo en inputs (tabla), asi input[0] sera el primer parametro, input[1] el segundo, #input el numero de argumentos. (vararg power).
output son los resultados que se devolverian en un coroutine.resume, pero en este caso desde fuera, en el screen.flip no paso argumentos ni recibo, por lo que no me preocupan, pero si requiriese de entrada y salida de datos usaria esas variables.
Espero se entienda un poco, y si no, al manual oficial de lua ;).
Un saludo.
Actualmente desarrollando nuestra web y UXCode : http://www.gcrew.es
Jefe esto no es C xD"input[0]
Jefe esto no es C xD
"input[0] sera el primer parametro, input[1] el segundo" quieres decir "input[1] sera el primer parametro, input[2] el segundo"
... xD
os estaba poniendo a prueba ;) xDDDDDDDDDD
XD
:o... significa que si es
:o... significa que si es humano y no una maquina de programacion XD
Jajajajajajjaja +1
xDDD No me hagas reir que casi escupo la computadora de gaseosa xDDDDD
Que buen off-topic xD
Saludos!!
Segun tengo entendido, el
Segun tengo entendido, el modulo no esta terminado y no es funcional del todo, pero se puede simular el uso de threads en un solo hilo usando un modulo improvisado que hace la funcion de threader
No es necesario hacer tanto codigo para hacer qeu tu programa tenga multi proceso, pero si buscas un mayor control de los hilos esto te va a servir, aunqeu le faltan algunas funciones que no me dieron tiempo de llenar como estas:
Entre otros, espero qeu te sirva de ayuda :)
Saludos¡¡
LOL
Y yo hice una cosa supercomplicada que va a medias y me tira errores XD. Si no te importa me voy a basar en la tuya, que me gustó mucho la forma de como lo haces en Fishell.
Saludos ^-^.
NekeOS, el nuevo shell para PSP
PS4 500GB OFW, PS3 320GB OFW, PS3 500GB OFW, PSP 6.39 PRO-C Fix4.
Sony Xperia Z1 Compact con Android 5.1.1
Portatil Lenovo z50-70 Intel® Core™ i7-4510U y NVIDIA GeForce 840M con Elementary OS 0.3.2 Freya (64 bits) y Windows 10 (64 bits).
Bien
Bien, ya entiendo como funciona la multitarea por procesos, pero sigo sin entender del todo lo de las corrutinas, por ahora, esto es todo lo que visto que las use:
Generador de números primos en Lua:
Saludos!
toma las corrutinas como si
toma las corrutinas como si fuesen callbacks, te sirve para hacer 2 procesos al mismo tiempo, su uso es algo mas complicado y debido a que esta incompleto no me he dado tiempo de entender bien su uso, pero lo que si se es que puedes hacer practicamente lo mismo con las corrutinas que con el metodo que te presente antes.
para que piensas usar las corrutinas si se puede saber? (para ver si podrias usar metodos mas faciles y practicos)
Pues...
Quería saber usarlas por lo siguiente:
Saludos!
aaa ok, es muy bueno querer
aaa ok, es muy bueno querer aprender cosas diferentes, pero me referia a para que proyecto la necesitas hacer? (un explorador de archivos, shell, juego?)
puede que haya algun otro metodo que te sirva mas que la corrutina y que podrias preferir usar mas
Bueno, por ahora
Bueno, por ahora no creo que las use con mis primeros aportes, en concreto, este ha sido mi primer aporte y ahora mismo estoy programando un reproductor de Mp3 con visualizaciones, listas de reproducción, funciones como ahorro energía y cosas así. Por ahora lo tengo en fase Alpha y aún no funciona muy bien, no creo, sinceramente, que llegue a usar las corrutinas en este projecto, pero quizás en otros sí, ya que no será mi último aporte.
Saludos!
Mmm...
Ahora que me acuerdo, ¿habeis mirado la documentación oficial de Lua? A lo mejor os resuelve vuestras dudas (Y las mias): http://www.lua.org/manual/5.1/es/manual.html#2.11
Ah!, y acordaros de este tutorial: http://psp.scenebeta.com/tutorial/multitarea-en-lua
NekeOS, el nuevo shell para PSP
PS4 500GB OFW, PS3 320GB OFW, PS3 500GB OFW, PSP 6.39 PRO-C Fix4.
Sony Xperia Z1 Compact con Android 5.1.1
Portatil Lenovo z50-70 Intel® Core™ i7-4510U y NVIDIA GeForce 840M con Elementary OS 0.3.2 Freya (64 bits) y Windows 10 (64 bits).
Sinceramente
Sinceramente, me he leido esa documentación por lo menos 10 veces, y una de las pocas cosas que no me ha quedado clara son las corrutinas...
Saludos!
Mmm
Pues entonces mira el tutorial, que creo que si lo explican muy bien.