-
-
Notifications
You must be signed in to change notification settings - Fork 366
Persist coroutines state #296
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
well, in a very pedantic way on could say that I don't think Rust will support this, even if I can vaguely see a path forward on the implementation side. |
Future + Serialize will work, but it will not work for desired sequences notation: spawn_fx();
wait_seconds(5.0).await;
play_animation(Jump).await;
pos += 5;
wait_seconds(1.).await; Persisting state just before running the coroutine and then re-running it with the same deltas for the same amount of frames will work, but its a lot of extra computations and additional complexity on maintaining code within the coroutine 100% deterministic. But, I read a little bit on future's implementation with generators, and, it looks like this terrible crime may work: https://gist.github.com/not-fl3/ba67e22ba7554f1850e25aaf3f3c07e8#file-past2-rs-L108 |
heh, yea, but this is easy to abuse for unsoundness (even by accident) if anyone holds non-copy types across an await. While I don't see Serialize/Deserialize ever happening, I think we could reasonably allow cloning async blocks. It's not that different from cloning closures. But that takes a while until we have it stable (probably a year?), there may be pre-existing discussions on this. So... if you guarded the "cloning" of the future with needs_drop, we could get this to be comfortable: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=c2d46a3b92fce1d7ff493b338f701b85 |
Well, I actually tried this and it works (kind of) (sort of) (but it should not) https://github.com/not-fl3/macroquad/blob/persist_coroutines/examples/rollback.rs This example is "animation-driven" player movement - on "Arrow" keys the red square is doing some long and non-linear movement pattern. Input is blocked until the "animation" finishes. When paused - it allows going back in time, restoring "player's" state. And after unpause, coroutine finishes the movement, exactly from the state it was persisted. rollback.mp4This gives hope, gives light... The problem: https://github.com/not-fl3/macroquad/blob/persist_coroutines/src/experimental/coroutines.rs#L100 - this assert always triggers, the only coroutine that passes: Trait objects manipulations are, probably, also unsound, but I believe this part is fixable. |
so... in essence: It would be best if we had language support for cloning async blocks/functions. I believe it should be doable, but I haven't read up on previous discussions on this (if there are any). There may be a fundamental problem, but I don't see what it would be. It may be very compiler-cycle prone, but we should be able to make it work for the cases proposed here. |
Yes, basically I am doing exactly a "clone", but in a really unsafe way. I think the only feature missing to make it relatively safe - being able to ask the future if it has any references persisted in the current state. I am really not sure if it is possible, maybe some rust's tracking issues I should follow? It looks like doing a "clone" of a future without references is safe enough. I wonder if I am missing something? I am considering to keep using futures for action chains like this: tweens::approach_linear(player_pos, 10).await;
tweens::approach_lerp(player_pos, 15).await; But make a checklist of things illegal for a coroutine. And eventually, somehow move the checks into runtime/comptime. |
Minimal step towards this: rust-lang/rust#95360 |
Coroutines are a nice way to express sequences of actions. We can gradually, frame by frame control advancement of coroutines.
But what we cant do - serialize the coroutine state and then load it. Say, save the progress of the cutscene in a save file and jump right to the middle of the coroutine after game load.
Use cases:
Minimized use case, do not depend on macroquad at all for simplicity: https://gist.github.com/not-fl3/e6c796fb4701e408c39fc3a03b7b9b72
As far as I understand, official rust's position here: futures are one-time-use by design and this is not possible. But, maybe, with some magic applied there is a way?
The text was updated successfully, but these errors were encountered: