-
Notifications
You must be signed in to change notification settings - Fork 903
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
EventLoop 3.0 Changes #2900
Comments
CC: @kchibisov, @msiglreith, @madsmtm, @daxpedda |
+1 to this. Maybe it could also be implemented for all of the non-Android platforms, which use
Maybe we build this into the type system? I.e. The only other thing is that Looks good to me, otherwise! Can't wait. |
This API only required on ios.
It'll be named |
Wrt While throttling adds a bit to that, I think it'll still be nice to have such entry point to potentially schedule the redraw on this loop iteration, so for example when after processing input events, you decided to request a redraw, so if on e.g. Wayland you already had frame callback, you could simply draw on this loop iteration reducing the overall latency. |
Wrt to window creation, we know that it's generally async, maybe we should expose it? Though, I'm thinking that it'll too much. But that, however will make it work with It could be like But I fill like that could be a bit a change in convenience, but generally speaking it'll improve situation wrt correctness, given that you really want to create EGLSurface for Wayland with the Besides, macOS has issues in general when it comes to creating windows out side of the loop, so some windowing features stop working (alacritty thus moved to |
I think it could be good to expose that window creation is async and fix the awkward issue with Wayland right now with the sync roundtrip in I don't know about really buffering requests to create a window right from before an event loop is started. It's always seemed a bit odd to me with Winit that you could create windows before starting to run an EventLoop. The idea of initially just getting a In terms of sizes to use with EGL there's another big mess imho with the It wouldn't necessarily always bad for apps to optimistically use a size that was used to request a new window for an egl surface if it e.g. means they don't have to wait for a round trip - if it's 99% likely they get what they asked for and the other 1% will correct itself via resize events etc. |
There would no longer be any notion of having multiple redraw events within a single iteration of the loop - you just get (throttled) RedrawRequested events in response to calling request_redraw() - so now you would just submit work to the GPU as part of your RedrawRequested event handler (i.e. after you've finished actually drawing). If we kept a RedrawEventsCleared then conceptually it would just be called back-to-back, immediately after the |
I don't think we want a |
I also don't quite understand why we have an api which The whole point was to move away of The only issue is that I think |
Yes, that unfortunately can't be fixed in Web. |
I think we've discussed in the past and we could have a way to block via the exception handler, basically the way |
Whats the "exception handler"? Right now |
oh, sorry, I didn't mean 'exception handler' I meant the trick with throwing - just wasn't thinking when typing ;-p |
it's not a panic that's thrown though is it? I thought it was done by punching through to javascript to throw an exception which Rust wouldn't see |
which was an old hack from emscripten that used to be done to give the illusion of a function in C/C++ that doesn't exit |
yeah I don't really feel like it's necessary for web. for web you're going to have a bit of bespoke wasm_bindgen glue anyway so it's just not really an issue to use a different run function |
it's pretty much just iOS that wants run_noreturn so I really don't see that it would be that nice to expose it across all platforms just for the sake of making the iOS behaviour into a lowest common denominator. Having every other platform hit technically though we could implement it for all platforms except Android I think, but that would kind of endorse it more than I feel like it should be. |
So right now we are just using the JS throw mechanism, which is kinda what you are describing. There isn't a big difference in practice between throwing directly and calling
I will remove it from OP then. |
I'd guess iOS is probably also like Android and Web where you're very likely going to have a bespoke entrypoint that isn't just a plain |
The trick relies on Rust basically not being aware of the Javascript layer throwing the exception - it's transparent to the Rust compiler, so I think it's maybe quite an important distinction - a panic is something that Rust would definitely know about. |
This idea would potentially work better if there was an event that corresponded to It would be tricky to do with Resumed events that can be emitted multiple times during the life of mobile apps. It could be interesting to consider since it can be good when the API forces you into a portable pattern - if it doesn't break other important use cases. |
Panics on Wasm are implemented very crudely right now. Basically any sort of panic in Wasm just uses the The important thing is that we don't trigger the panic handler, which a call to That is all until Rust gains Wasm unwinding support. |
The problem in my eyes with Though I didn't know about |
That is a good point ... I didn't consider that. I think @kchibisov mentioned in the PR that we should consider removing I am strongly in favor of not making the change to |
:( we've been around in circles so many times on this now. We can't support
Overall there's no perfect Another option could be to rely on extensions for all platforms since there's no perfect solution but as it is The ability to return a status is something that is really desirable and also possible on the majority of platforms except for iOS and Web. It's notable that It doesn't break Web or iOS for the compiler to not inform apps that the function doesn't return - that's an ergonomic hint and we can provide an extension API like |
Apologies, I wasn't here for that. I'm still new here!
Yeah, that's a problem, I agree.
I think this is the most reasonable option here. I would be in favor of just making this platform specific, or alternatively, just expose |
doesn't change anything from user side of view, I don't know who call exit but anyway that what winit do by calling whatever that call exit. I know a bit of wayland and wayland-rs and I don't think they call exit either. Calling exit break so many thing from user, imagine a game where you would like try to save before a crash, you couldn't cause something call exit. |
I'm saying that no-one calls |
That said, the docs for One reasonable interpretation of that sentence is that |
fwiw Winit did use to call Now that Winit's In general the previous use of |
It could be just forgotten to update, since we don't and we always forward errors now, even from other functions. It's best to remove such references all together if you still see them in the docs. You can open a separate issue and I fix the docs once I have time. It's just the claim was that we straight terminate, said on that issue, given that this issue was solely about removing any sort of such termination, which I treat as complete dismissal of what was said before on the issue and they just decided to attack without understanding and reading into the issue and following anything. |
I didn't attack on anything, I say I also prefer winit without exit and ask if it was still the case cause the doc on beta still say there is exit for x11 and wayland. I asked you to read twice my comment and you proved you didn't. I literally quote the doc of beta where it's return Result, ask if it was still up to date, link to the beta doc (oops I didn't lol). What more do you want from me ? You make no effort to answer me. |
See this #3111 . |
I'd just say that the first sentence was made me decide to discard and not read much into the other part of message for the following reasons:
I'm sorry for being offensive, it's just, hard to understand what folks really want when they start their comments with a sentence making me not want to read the rest, and that the thing you said was only half the truth, given that winit always offered alternatives which never terminated with Just simply linking to the exact place in docs where you have question is always better and you could save a lot of time removing all the misunderstanding. I fixed it after @wleslie provided relevant link to the docs. |
Apologies for what may seem like bikeshedding, but |
Yeah, would probably make sense. The name really just came from terms that were being used in the original github issues being addressed (#2431). It became the term we used for consistency to refer to that use case. I guess I won't get a chance to make a PR to change it myself but it does sound like it would be reasonable to rename. |
fine with renaming, do you want to send a patch doing so? |
# Objective - Update winit dependency to 0.29 ## Changelog ### KeyCode changes - Removed `ScanCode`, as it was [replaced by KeyCode](https://github.com/rust-windowing/winit/blob/master/CHANGELOG.md#0292). - `ReceivedCharacter.char` is now a `SmolStr`, [relevant doc](https://docs.rs/winit/latest/winit/event/struct.KeyEvent.html#structfield.text). - Changed most `KeyCode` values, and added more. KeyCode has changed meaning. With this PR, it refers to physical position on keyboard rather than the printed letter on keyboard keys. In practice this means: - On QWERTY keyboard layouts, nothing changes - On any other keyboard layout, `KeyCode` no longer reflects the label on key. - This is "good". In bevy 0.12, when you used WASD for movement, users with non-QWERTY keyboards couldn't play your game! This was especially bad for non-latin keyboards. Now, WASD represents the physical keys. A French player will press the ZQSD keys, which are near each other, Kyrgyz players will use "Цфыв". - This is "bad" as well. You can't know in advance what the label of the key for input is. Your UI says "press WASD to move", even if in reality, they should be pressing "ZQSD" or "Цфыв". You also no longer can use `KeyCode` for text inputs. In any case, it was a pretty bad API for text input. You should use `ReceivedCharacter` now instead. ### Other changes - Use `web-time` rather than `instant` crate. (rust-windowing/winit#2836) - winit did split `run_return` in `run_onDemand` and `pump_events`, I did the same change in bevy_winit and used `pump_events`. - Removed `return_from_run` from `WinitSettings` as `winit::run` now returns on supported platforms. - I left the example "return_after_run" as I think it's still useful. - This winit change is done partly to allow to create a new window after quitting all windows: emilk/egui#1918 ; this PR doesn't address. - added `width` and `height` properties in the `canvas` from wasm example (#10702 (comment)) ## Known regressions (important follow ups?) - Provide an API for reacting when a specific key from current layout was released. - possible solutions: use winit::Key from winit::KeyEvent ; mapping between KeyCode and Key ; or . - We don't receive characters through alt+numpad (e.g. alt + 151 = "ù") anymore ; reproduced on winit example "ime". maybe related to rust-windowing/winit#2945 - (windows) Window content doesn't refresh at all when resizing. By reading rust-windowing/winit#2900 ; I suspect we should just fire a `window.request_redraw();` from `AboutToWait`, and handle actual redrawing within `RedrawRequested`. I'm not sure how to move all that code so I'd appreciate it to be a follow up. - (windows) unreleased winit fix for using set_control_flow in AboutToWait rust-windowing/winit#3215 ;⚠️ I'm not sure what the implications are, but that feels bad 🤔 ## Follow up I'd like to avoid bloating this PR, here are a few follow up tasks worthy of a separate PR, or new issue to track them once this PR is closed, as they would either complicate reviews, or at risk of being controversial: - remove CanvasParentResizePlugin (#10702 (comment)) - avoid mentionning explicitly winit in docs from bevy_window ? - NamedKey integration on bevy_input: rust-windowing/winit#3143 introduced a new NamedKey variant. I implemented it only on the converters but we'd benefit making the same changes to bevy_input. - Add more info in KeyboardInput #10702 (review) - #9905 added a workaround on a bug allegedly fixed by winit 0.29. We should check if it's still necessary. - update to raw_window_handle 0.6 - blocked by wgpu - Rename `KeyCode` to `PhysicalKeyCode` #10702 (comment) - remove `instant` dependency, [replaced by](rust-windowing/winit#2836) `web_time`), we'd need to update to : - fastrand >= 2.0 - [`async-executor`](https://github.com/smol-rs/async-executor) >= 1.7 - [`futures-lite`](https://github.com/smol-rs/futures-lite) >= 2.0 - Verify license, see [discussion](#8745 (comment)) - we might be missing a short notice or description of changes made - Consider using https://github.com/rust-windowing/cursor-icon directly rather than vendoring it in bevy. - investigate [this unwrap](#8745 (comment)) (`winit_window.canvas().unwrap();`) - Use more good things about winit's update - #10689 (comment) ## Migration Guide This PR should have one.
(Not sure if this is the right place to ask, so feel free to hide/delete this comment.) First off, thanks for all the hard work! I'm migrating my codebase (a game) to use winit 0.29, and I'm really confused by some of the guidance in the docs, but I'm also unsure how much of it is intentional or lacking design details. Here are some questions that popped up:
Really sorry if I'm missing something obvious. I'm not really sure what is actionable about all this - the changes seem really good overall, and I like that there is less magic going on around the quirks of the Windows event loop. Might just be a documentation issue. :-) |
that's a bug that should be fixed given that it's a windows specific issue.
This is only on macOS since it really wants you to draw right from this event otherwise you may get a bit undesired artifacts, but it's not tearing, not.
Calling redraw_requested from RedrawRequested itself is supported and guaranteed to work on all the platforms. It'll properly send it on the next frame.
To spin the loop as fast as you can? Like not sure why it shouldn't exist given that it's pretty common for event loop to have wait, wait with time out, and instant return when no events. |
Thank you for clarifying this!
It's still unclear to me what the guidance actually is here. Is it the case for all use cases that any drawing on the window's surface, including presentation to a GPU surface, should happen within Really sorry if this is hijacking the issue, please let me know if there is a better place to put these questions! |
it's recommended and how apply expects you.
you should ask such questions on matrix or discussions. |
Hi all! Came here after attempting to upgrade to 29. I am wondering, how should one structure a loop for videogames these days. In 28, we had I notice there's
Thanks! |
If you want to draw or update in VSync, you can do that inside If you want to draw or update in a specific interval, you can use If you want to draw or update as fast possible, which is not recommended as it will just consume 100% CPU, you can use |
This contradicts the guidance of https://docs.rs/winit/latest/winit/event_loop/enum.ControlFlow.html , and I guess in WGPU at least waiting for the swapchain image can block which is how vsync throttling typically is done for that API. Is your note here about the case where you don't have a 3D API, or are the docs wrong here? |
The documentation is poor and wrong in some places. Unfortunately there are some inconsistencies here, unfortunately Wgpu doesn't always block for VSync, e.g. Web doesn't, so if you use The fact is that there is no ideal solution here until either Wgpu improves (gfx-rs/wgpu#2869, gfx-rs/wgpu#3283) or Winit finishes #2412. But if you have a reliable method blocking until VSync and you don't want to handle any events while doing that, |
# Objective - Update winit dependency to 0.29 ## Changelog ### KeyCode changes - Removed `ScanCode`, as it was [replaced by KeyCode](https://github.com/rust-windowing/winit/blob/master/CHANGELOG.md#0292). - `ReceivedCharacter.char` is now a `SmolStr`, [relevant doc](https://docs.rs/winit/latest/winit/event/struct.KeyEvent.html#structfield.text). - Changed most `KeyCode` values, and added more. KeyCode has changed meaning. With this PR, it refers to physical position on keyboard rather than the printed letter on keyboard keys. In practice this means: - On QWERTY keyboard layouts, nothing changes - On any other keyboard layout, `KeyCode` no longer reflects the label on key. - This is "good". In bevy 0.12, when you used WASD for movement, users with non-QWERTY keyboards couldn't play your game! This was especially bad for non-latin keyboards. Now, WASD represents the physical keys. A French player will press the ZQSD keys, which are near each other, Kyrgyz players will use "Цфыв". - This is "bad" as well. You can't know in advance what the label of the key for input is. Your UI says "press WASD to move", even if in reality, they should be pressing "ZQSD" or "Цфыв". You also no longer can use `KeyCode` for text inputs. In any case, it was a pretty bad API for text input. You should use `ReceivedCharacter` now instead. ### Other changes - Use `web-time` rather than `instant` crate. (rust-windowing/winit#2836) - winit did split `run_return` in `run_onDemand` and `pump_events`, I did the same change in bevy_winit and used `pump_events`. - Removed `return_from_run` from `WinitSettings` as `winit::run` now returns on supported platforms. - I left the example "return_after_run" as I think it's still useful. - This winit change is done partly to allow to create a new window after quitting all windows: emilk/egui#1918 ; this PR doesn't address. - added `width` and `height` properties in the `canvas` from wasm example (bevyengine/bevy#10702 (comment)) ## Known regressions (important follow ups?) - Provide an API for reacting when a specific key from current layout was released. - possible solutions: use winit::Key from winit::KeyEvent ; mapping between KeyCode and Key ; or . - We don't receive characters through alt+numpad (e.g. alt + 151 = "ù") anymore ; reproduced on winit example "ime". maybe related to rust-windowing/winit#2945 - (windows) Window content doesn't refresh at all when resizing. By reading rust-windowing/winit#2900 ; I suspect we should just fire a `window.request_redraw();` from `AboutToWait`, and handle actual redrawing within `RedrawRequested`. I'm not sure how to move all that code so I'd appreciate it to be a follow up. - (windows) unreleased winit fix for using set_control_flow in AboutToWait rust-windowing/winit#3215 ;⚠️ I'm not sure what the implications are, but that feels bad 🤔 ## Follow up I'd like to avoid bloating this PR, here are a few follow up tasks worthy of a separate PR, or new issue to track them once this PR is closed, as they would either complicate reviews, or at risk of being controversial: - remove CanvasParentResizePlugin (bevyengine/bevy#10702 (comment)) - avoid mentionning explicitly winit in docs from bevy_window ? - NamedKey integration on bevy_input: rust-windowing/winit#3143 introduced a new NamedKey variant. I implemented it only on the converters but we'd benefit making the same changes to bevy_input. - Add more info in KeyboardInput bevyengine/bevy#10702 (review) - bevyengine/bevy#9905 added a workaround on a bug allegedly fixed by winit 0.29. We should check if it's still necessary. - update to raw_window_handle 0.6 - blocked by wgpu - Rename `KeyCode` to `PhysicalKeyCode` bevyengine/bevy#10702 (comment) - remove `instant` dependency, [replaced by](rust-windowing/winit#2836) `web_time`), we'd need to update to : - fastrand >= 2.0 - [`async-executor`](https://github.com/smol-rs/async-executor) >= 1.7 - [`futures-lite`](https://github.com/smol-rs/futures-lite) >= 2.0 - Verify license, see [discussion](bevyengine/bevy#8745 (comment)) - we might be missing a short notice or description of changes made - Consider using https://github.com/rust-windowing/cursor-icon directly rather than vendoring it in bevy. - investigate [this unwrap](bevyengine/bevy#8745 (comment)) (`winit_window.canvas().unwrap();`) - Use more good things about winit's update - bevyengine/bevy#10689 (comment) ## Migration Guide This PR should have one.
Considering the changes being made for
run()-> Result<>
,pump_events
,run_ondemand
, and addressing inconsistent ordering guarantees for events likeMainEventsCleared
andRedrawRequested
, as well as removing and renaming several core events, then it feels like a similar level of change as happened for EventLoop 2.0.The details are a bit scattered though, and although some things have been agreed as part of lengthy issue discussions we still need to track those ideas at least as a reminder as to what is left to do.
I'm going to be lite on details here, but a lot of the background discussion probably happened here #2706 and maybe a few other issues we can link back here too.
run() ->!
withrun() -> Result
as our portable run API available on all platforms (Re-work event loop run APIs: addsrun -> Result<>
,run_ondemand
andpump_events
#2767)run_return()
withpump_events()
andrun_ondemand()
(for Windows, macOS, Linux + Android) (Re-work event loop run APIs: addsrun -> Result<>
,run_ondemand
andpump_events
#2767)run_noreturn() ->!
extension API for iOSLoopDestroyed
LoopExiting
(RenameLoopDestroyed
toLoopExiting
#2975)RedrawEventsCleared
(Remove RedrawEventsCleared + MainEventsCleared, and add AboutToWait #2976)MainEventsCleared
->AboutToPoll
AboutToWait
(ConceptuallyNewEvents
andAboutToWait
can be seen as a way to observe the underlying blocking/polling of the event loop - similar to registering an observer with a macOSRunLoop
) (Remove RedrawEventsCleared + MainEventsCleared, and add AboutToWait #2976)RedrawRequested
is no longer guaranteed to be delivered in order with respect to any other event - it is platform specificRedrawRequested
callback (and they shouldn't defer the redraw outside of the winit callback).Resumed
events are delivered on all platforms (not just mobile) andResumed
events are a good place to initialize an application because it's the first point where it's possible to start creating Windows across all platforms.Event
RedrawRequested
throttling by default where there's a suitable mechanism provided by the window systemWM_PAINT
on WindowsdrawRect
or display link on macOS (same for iOS?)I don't mind if we want to collate this information somewhere else, or in a different, better way etc but wanted to a least get a basic task list laid out somewhere
Maybe a milestone would be a nicer way to organize this?
The text was updated successfully, but these errors were encountered: