El caso más destacado de corutinas es probally old graph point & haga clic en juegos de aventuras, donde se utilizaron para secuencias de secuencias de comandos y otras secuencias animadas en el juego. Un ejemplo simple código se vería así:
# script_file.scr
bob.walkto(jane)
bob.lookat(jane)
bob.say("How are you?")
wait(2)
jane.say("Fine")
...
Toda esta secuencia no puede ser escrito como código normal, como usted quiere ver a Bob hacer su animación paseo después de que hizo bob.walkto(jane)
en lugar de saltar a la derecha a la línea siguiente . Sin embargo, para que la animación de la caminata juegue, debes devolver el control al motor del juego y ahí es donde entran en juego las corutinas.
Toda esta secuencia se ejecuta como una corutina, lo que significa que tiene la capacidad de suspenderla y reanudarla como desee.Un comando como bob.walkto(jane)
le dice al objeto bob del lado del motor su objetivo y luego suspende la corrutina, esperando una llamada de activación cuando bob ha alcanzado su objetivo.
En las cosas laterales del motor podría tener este aspecto (pseudo código):
class Script:
def __init__(self, filename):
self.coroutine = Coroutine(filename)
self.is_wokenup = True
def wakeup(self):
self.is_wokenup = False;
def update():
if self.is_wokenup:
coroutine.run()
class Character:
def walkto(self, target, script):
self.script = script
self.target = target
def update(self):
if target:
move_one_step_closer_to(self.target)
if close_enough_to(self.target):
self.script.wakeup()
self.target = None
self.script = None
objects = [Character("bob"), Character("jane")]
scripts = [Script("script_file.scr")]
while True:
for obj in objects:
obj.update()
for scr in scripts:
scr.update()
Palabras litte de advertencia sin embargo, mientras corrutinas hacen codificación de estas secuencias muy simple, no todas las implementaciones se encuentra de ellos Se debe tener en cuenta la serialización, por lo que guardar el juego se convertirá en un problema bastante problemático si haces un uso intensivo de corrutinas.
Este ejemplo es también el caso más básico de una corutina en un juego, las corutinas en sí mismas se pueden utilizar para muchas otras tareas y algoritmos también.
Las corrutinas tienen algunos problemas de sincronización, pero solo si su estado no puede ser coherente entre las llamadas a yield(). Tener un bloqueo implícito alrededor de todo el código entre llamadas a yield() puede simplificar enormemente las cosas. El mayor problema es que cada vez que se crea una rutina, se debe decidir en ese momento si la rutina siempre podrá completarse antes de tener que ceder(). Si la persona que llama a una rutina no espera que se rinda una rutina, es posible que no tenga elementos en un estado constante cuando se llame a la rutina. Agregar un rendimiento() sería un cambio radical. – supercat
El problema es que, por lo general, desea poder ceder en cualquier lugar para que tales rutinas tengan algún uso (como en UnrealScript donde las funciones latentes rinden implícitamente), pero esto lleva a combinaciones de corutinas que interactúan de maneras impredecibles. p.ej. Si se trata de una patrulla corrutina que dice "vete al norte, mira, vete al sur, mira, repite"; y la otra es una rutina de reacción que dice "si (el sonido se escucha hacia el oeste) {ir al oeste; mirar; ir hacia el este;}" luego intercalando los dos podría resultar en que el actor se mueva de manera impredecible. Es por eso que UnrealScript solo permite tales funciones en precisamente una 'corutina'. – Kylotan
E incluso si solo tiene 1 corrutina por actor, eso aún no es suficiente para garantizar que la lógica siempre funcione en el nivel de idioma: si su corotine dice: "dibuje espada, espere 1 segundo; ataque al oponente con espada", entonces qué sucede si la espada desaparece debido a que eres desarmado por otro jugador? En particular, ¿qué pasa si tu lenguaje implementa esa corotine usando una variable local para una espada que ahora se refiere a un objeto nulo? Es muy complicado considerar todos estos casos si usa un lenguaje de propósito general de la forma habitual. – Kylotan