Skip to content
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

Add WinitEvent aggregate event for synchronized window event reading #12100

Merged
merged 9 commits into from
Mar 4, 2024

Conversation

UkoeHB
Copy link
Contributor

@UkoeHB UkoeHB commented Feb 24, 2024

Objective

  • Allow users to read window events in the sequence they appeared. This is important for precise input handling when there are multiple input events in a single frame (e.g. click and release vs release and click).

Solution

  • Add a mega-enum WinitEvent that collects window events, and send those alongside the existing more granular window events.

Changelog

  • Added WinitEvent event that aggregates all window events into a synchronized event stream.

@alice-i-cecile alice-i-cecile added C-Feature A new feature, making something new possible A-Input Player input via keyboard, mouse, gamepad, and more labels Feb 24, 2024
@alice-i-cecile
Copy link
Member

I think that even if we add timestamps to input events, this is still worth having around. It saves users from having to reconstitute this event stream themselves.

@UkoeHB
Copy link
Contributor Author

UkoeHB commented Feb 24, 2024

I am getting libc++abi: terminating with uncaught foreign exception on the alien_cake_addict example (which is failing in CI). No idea why this PR would cause that. Edit: this was caused by not registering the WinitEvent event in the app.

WindowEvent::KeyboardInput { ref event, .. } => {
if event.state.is_pressed() {
if let Some(char) = &event.text {
let char = char.clone();
app.send_event(ReceivedCharacter { window, char });
winit_events.send(ReceivedCharacter { window, char });
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we're no longer using those other event types, can we remove them? or are we to double-send events along both queues?

Copy link
Contributor Author

@UkoeHB UkoeHB Feb 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah events are double-sent now, events are dispatched before each app update.

crates/bevy_winit/src/lib.rs Outdated Show resolved Hide resolved
@alice-i-cecile alice-i-cecile added the M-Needs-Release-Note Work that should be called out in the blog due to impact label Feb 24, 2024
Copy link
Member

@aevyrie aevyrie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a very welcome change, thank you.

My only suggestions would be to send the events directly into the app, instead of allocating an independent Vec and running the newly added flush function. That should allow the app's internal event resource to only pay price of allocation once, instead of every event loop. This adds an entry to the existing event_writer_system_state, and cuts about 70 LOC. I opened a PR against this PR with those changes here: UkoeHB#1

@UkoeHB
Copy link
Contributor Author

UkoeHB commented Mar 3, 2024

That should allow the app's internal event resource to only pay price of allocation once, instead of every event loop.

The Vec allocated here is only allocated once, and then cleared every iteration.

This adds an entry to the existing event_writer_system_state, and cuts about 70 LOC

The PR you opened removes the step where you forward WinitEvents as individual events to Bevy, which will not pass CI.

I agree that your solution feels a bit cleaner, but I'm not sure how you would forward winit events properly using that approach.

@aevyrie
Copy link
Member

aevyrie commented Mar 3, 2024

The Vec allocated here is only allocated once, and then cleared every iteration.

Yup, you're right, I always get a bit confused following the control flow of the runner/event loop. 😄

The PR you opened removes the step where you forward WinitEvents as individual events to Bevy, which will not pass CI.

Maybe I missed something, but in the PR, I'm accessing the EventWriter<WinitEvent> directly using the existing system state, and sending events into it.

https://github.com/UkoeHB/bevy/pull/1/files#diff-b1447f30819280931099e7498b2ced388a98de5cda1b631b493107bb96193cc0R304

@alice-i-cecile alice-i-cecile added the S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it label Mar 3, 2024
@alice-i-cecile alice-i-cecile added this pull request to the merge queue Mar 3, 2024
Merged via the queue into bevyengine:main with commit ef8a617 Mar 4, 2024
27 of 28 checks passed
@UkoeHB
Copy link
Contributor Author

UkoeHB commented Mar 4, 2024

Maybe I missed something, but in the PR, I'm accessing the EventWriter directly using the existing system state, and sending events into it.

Yep and that works great for the aggregate WinitEvent, but WinitEvent also needs to be unwrapped and each internal variant dispatched as independent events. That's what forward_winit_events() was doing, which your PR deleted.

github-merge-queue bot pushed a commit that referenced this pull request Mar 4, 2024
# Objective

- CI is green

## Solution

- Fix typos (#12045)
- Correctly declare features (#12100)
@aevyrie
Copy link
Member

aevyrie commented Mar 4, 2024

That's what forward_winit_events() was doing, which your PR deleted.

Yes, I missed that. Thanks again for getting this change in, looking forward to properly ordered input events!

@UkoeHB UkoeHB deleted the winit_event branch March 8, 2024 00:53
spectria-limina pushed a commit to spectria-limina/bevy that referenced this pull request Mar 9, 2024
…evyengine#12100)

# Objective

- Allow users to read window events in the sequence they appeared. This
is important for precise input handling when there are multiple input
events in a single frame (e.g. click and release vs release and click).

## Solution

- Add a mega-enum `WinitEvent` that collects window events, and send
those alongside the existing more granular window events.

---

## Changelog

- Added `WinitEvent` event that aggregates all window events into a
synchronized event stream.
spectria-limina pushed a commit to spectria-limina/bevy that referenced this pull request Mar 9, 2024
# Objective

- CI is green

## Solution

- Fix typos (bevyengine#12045)
- Correctly declare features (bevyengine#12100)
@extrawurst
Copy link
Contributor

In what release will this land? The milestone is not set

@alice-i-cecile
Copy link
Member

By default merged PRs are shipped in the next major version of Bevy. In this case, 0.14 :)

@extrawurst
Copy link
Contributor

Gotcha!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Input Player input via keyboard, mouse, gamepad, and more C-Feature A new feature, making something new possible M-Needs-Release-Note Work that should be called out in the blog due to impact S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants