"Just" is doing a lot of work there. I've use callback-based async frameworks in C++ in the past, and it turns into pure hell very fast. Async programming is, basically, state machines all the way down, and doing it explicitly is not nice. And trying to debug the damn thing is a miserable experience
The author just chose to write it as a state machine, but you don't have to. Write it in whatever style helps you reach correctness.
Lol, no thanks. People are using coroutines exactly to avoid callback hell. I have rewritten my own C++ ASIO networking code from callback to coroutines (asio::awaitable) and the difference is night and day!
waitFrames(5); // wait 5 frames
fireProjectile();
waitFrames(15);
turnLeft(-30/*deg*/, 120); // turn left over 120 frames
waitFrames(10);
fireProjectile();
// spin and shoot
for (i of range(0, 360, 60)) {
turnRight(60, 90); // turn 60 degrees over 90 frames
fireProjectile();
}
10 lines and I get behavior over time. What would your non-coroutine solution look like?``` int f() { a; co_yield r; b; co_return r2; } ```
this transforms into
``` auto f(auto then) { a; return then(r, [&]() { b; return then(r2); }); }; ```
You can easily extend this to arbitrarily complex statements. The main thing is that obviously, you have to worry about the capture lifetime yourself (coroutines allocate a frame separate from the stack), and the syntax causes nesting for every statement (but you can avoid that using operator overloading, like C++26/29 does for executors)
> The main thing is that obviously, you have to worry about the capture lifetime yourself
This is a big deal! The fact that the coroutine frame is kept alive and your state can just stay in local variables is one of the main selling points. I experienced this first-hand when I rewrote callback-style C++ ASIO code to the new coroutine style. No more [self=shared_from_this()] and other shenanigans!
For simple callback hell, not so much.
Just put your state in visible instance variables of your objects, and then you will actually be able to see and even edit what state your program is in. Stop doing things that make debugging difficult and frustratingly opaque.