Coroutines are awesome

General discussion about LÖVE, Lua, game development, puns, and unicorns.
User avatar
pgimeno
Party member
Posts: 3541
Joined: Sun Oct 18, 2015 2:58 pm

Re: Coroutines are awesome

Post by pgimeno »

Well, even 10 yeas later, coroutines keep being awesome.
User avatar
ReFreezed
Party member
Posts: 612
Joined: Sun Oct 25, 2015 11:32 pm
Location: Sweden
Contact:

Re: Coroutines are awesome

Post by ReFreezed »

Meh. Coroutines have their uses, but really, they just wish they were Real Threads™.
Tools: Hot Particles, LuaPreprocess, InputField, (more) Games: Momento Temporis
"If each mistake being made is a new one, then progress is being made."
User avatar
pgimeno
Party member
Posts: 3541
Joined: Sun Oct 18, 2015 2:58 pm

Re: Coroutines are awesome

Post by pgimeno »

Well, so far I have written several projects with coroutines and only one with threads, and I have more ideas that would require coroutines if I ever get to implement them, so for me they are more useful.

The GIF library would have been messier without them; the coroutine deals with decoding and the caller gives it the data and takes the output. With threads, you have to deal with synchronization and messaging, both of which are trivial with coroutines.

You also can't draw from a thread, so if you need to draw, you have to implement something like a command system so that the main thread draws on behalf of the others, complicating the code a lot. Coroutines in the main thread can happily draw to the screen (of course if you create another thread and use a coroutine there, you can't draw from it).

In Löve it's not relevant, but in environments that require a global interpreter lock, like Python or Minetest, real threads are most probably slower than coroutines in many cases. Long ago I read an article about Python that implemented coroutines using generators, and it explained that the performance gain was noticeable; the project was a TCP server IIRC.
User avatar
ReFreezed
Party member
Posts: 612
Joined: Sun Oct 25, 2015 11:32 pm
Location: Sweden
Contact:

Re: Coroutines are awesome

Post by ReFreezed »

The comparison to threads was mostly a joke - of course they have significant differences. I've also used coroutines more than threads, but I've seldom needed to use either. Using coroutines does make sense when decoding streaming data one chunk at a time, like can be done with gifload (though when I've used it I've just fed it whole files in one go, so any benefit of using coroutines is purely internal to the library).

I'm wondering how coroutines could be used in a good way during rendering, especially since rendering depends on the current state (current color, shader, transformation etc.), and the fact that you likely need to have rendered all the things by the end of the frame - not just some of the things.

The biggest strength of threads is the parallelism, i.e. letting a thread do something time consuming while the main thread goes on uninterrupted.
Tools: Hot Particles, LuaPreprocess, InputField, (more) Games: Momento Temporis
"If each mistake being made is a new one, then progress is being made."
User avatar
pgimeno
Party member
Posts: 3541
Joined: Sun Oct 18, 2015 2:58 pm

Re: Coroutines are awesome

Post by pgimeno »

ReFreezed wrote: Sun Sep 18, 2022 8:46 pm I'm wondering how coroutines could be used in a good way during rendering, especially since rendering depends on the current state (current color, shader, transformation etc.), and the fact that you likely need to have rendered all the things by the end of the frame - not just some of the things.
Here's an example:

viewtopic.php?f=5&t=87262

This utility renders to a canvas, and then love.draw displays it. Here's an example program made with, which implements a very basic keyboard input function (edit control) the "classic" way:
https://notabug.org/pgimeno/alg-visuali ... ens.lua#46

Another use I can think of is user-programmable entities. The user code would transparently run within a coroutine. The user can then decide how to render their entity. The coroutines can be scheduled to give all entities a chance to run, similarly to threads. But writing a good scheduler is no longer a trivial task, admittedly, and it starts to be on par with inter-thread communication, command queues and locking, so part of the advantage of using coroutines in the first place is lost. But a simple scheduler is easy to write.
User avatar
ReFreezed
Party member
Posts: 612
Joined: Sun Oct 25, 2015 11:32 pm
Location: Sweden
Contact:

Re: Coroutines are awesome

Post by ReFreezed »

Interesting example about visualizing algorithms. I was mainly thinking about games, but I see how coroutines could work in other simpler programs. Not sure specifically the rendering fits well there though as you could just render stuff and call love.graphics.present() whenever you want in the middle of the algorithm. Same with sleeping. (Btw, I'd say present() is also a bit like a yield, but control is returned to the OS instead of the program.) It would be different in a program that wants to do multiple things and have multiple coroutines running/yielding, but now it sounds more like threads again, and if you can't use threads because you need to render stuff then that doesn't make coroutines more awesome - they just happen to be the only option (and there's still the issue of the graphical state potentially changing during yields).

I'm probably misunderstanding what you mean, but the entities thing sounds like callbacks on the entity would be way simpler.

Code: Select all

for i, entity in ipairs(entities) do
	if entity.customDraw then  entity:customDraw()  end
end
When would the render code for an entity want to yield?
Tools: Hot Particles, LuaPreprocess, InputField, (more) Games: Momento Temporis
"If each mistake being made is a new one, then progress is being made."
User avatar
pgimeno
Party member
Posts: 3541
Joined: Sun Oct 18, 2015 2:58 pm

Re: Coroutines are awesome

Post by pgimeno »

ReFreezed wrote: Mon Sep 19, 2022 3:15 pm When would the render code for an entity want to yield?
You're right, that was a bad example. I was generalizing from the idea of user-programmable entities, where yielding is a must, to user-programmable entities that included rendering routines, but as you have noticed, it doesn't make much sense to yield during rendering, so coroutines are actually not very useful in that field.
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot] and 23 guests