Skip to content

Commit

Permalink
bevy_winit(emit raw winit events)
Browse files Browse the repository at this point in the history
  • Loading branch information
HugoPeters1024 committed Oct 14, 2024
1 parent d96a9d1 commit 0606734
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 10 deletions.
18 changes: 17 additions & 1 deletion crates/bevy_winit/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ extern crate alloc;
use bevy_derive::Deref;
use bevy_window::{RawHandleWrapperHolder, WindowEvent};
use core::marker::PhantomData;
use winit::event_loop::EventLoop;
use winit::{event_loop::EventLoop, window::WindowId};

use bevy_a11y::AccessibilityRequested;
use bevy_app::{App, Last, Plugin};
Expand Down Expand Up @@ -117,6 +117,7 @@ impl<T: Event> Plugin for WinitPlugin<T> {
app.init_non_send_resource::<WinitWindows>()
.init_resource::<WinitMonitors>()
.init_resource::<WinitSettings>()
.add_event::<RawWinitWindowEvent>()
.set_runner(winit_runner::<T>)
.add_systems(
Last,
Expand Down Expand Up @@ -149,6 +150,21 @@ impl<T: Event> Plugin for WinitPlugin<T> {
#[derive(Debug, Default, Clone, Copy, Event)]
pub struct WakeUp;

/// The original window event as produced by winit. This is meant as an escape
/// hatch for power users that wish add custom winit integrations.
/// If you want to process events for your app or game, you should instead use
/// `bevy::window::WindowEvent`, or one of its sub-events.
///
/// When you receive this event it has already been handled by Bevy's main loop.
/// Sending these events will NOT cause them to be processed by Bevy.
#[derive(Debug, Clone, Event)]
pub struct RawWinitWindowEvent {
/// The window for which the event was fired.
pub window_id: WindowId,
/// The raw winit window event.
pub event: winit::event::WindowEvent,
}

/// A wrapper type around [`winit::event_loop::EventLoopProxy`] with the specific
/// [`winit::event::Event::UserEvent`] used in the [`WinitPlugin`].
///
Expand Down
31 changes: 22 additions & 9 deletions crates/bevy_winit/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ use crate::{
accessibility::AccessKitAdapters,
converters, create_windows,
system::{create_monitors, CachedWindow},
AppSendEvent, CreateMonitorParams, CreateWindowParams, EventLoopProxyWrapper, UpdateMode,
WinitSettings, WinitWindows,
AppSendEvent, CreateMonitorParams, CreateWindowParams, EventLoopProxyWrapper,
RawWinitWindowEvent, UpdateMode, WinitSettings, WinitWindows,
};

/// Persistent state that is used to run the [`App`] according to the current
Expand Down Expand Up @@ -80,6 +80,8 @@ struct WinitAppRunnerState<T: Event> {
previous_lifecycle: AppLifecycle,
/// Bevy window events to send
bevy_window_events: Vec<bevy_window::WindowEvent>,
/// Raw Winit window events to send
raw_winit_events: Vec<RawWinitWindowEvent>,
_marker: PhantomData<T>,

event_writer_system_state: SystemState<(
Expand Down Expand Up @@ -121,6 +123,7 @@ impl<T: Event> WinitAppRunnerState<T> {
// 3 seems to be enough, 5 is a safe margin
startup_forced_updates: 5,
bevy_window_events: Vec::new(),
raw_winit_events: Vec::new(),
_marker: PhantomData,
event_writer_system_state,
}
Expand Down Expand Up @@ -250,6 +253,12 @@ impl<T: Event> ApplicationHandler<T> for WinitAppRunnerState<T> {
return;
};

// Store a copy of the event to send to an EventWriter later.
self.raw_winit_events.push(RawWinitWindowEvent {
window_id,
event: event.clone(),
});

// Allow AccessKit to respond to `WindowEvent`s before they reach
// the engine.
if let Some(adapter) = access_kit_adapters.get_mut(&window) {
Expand Down Expand Up @@ -687,14 +696,16 @@ impl<T: Event> WinitAppRunnerState<T> {
}

fn forward_bevy_events(&mut self) {
let raw_winit_events = self.raw_winit_events.drain(..).collect::<Vec<_>>();
let buffered_events = self.bevy_window_events.drain(..).collect::<Vec<_>>();
let world = self.world_mut();

if buffered_events.is_empty() {
return;
if !raw_winit_events.is_empty() {
world
.resource_mut::<Events<RawWinitWindowEvent>>()
.send_batch(raw_winit_events);
}

let world = self.world_mut();

for winit_event in buffered_events.iter() {
match winit_event.clone() {
BevyWindowEvent::AppLifecycle(e) => {
Expand Down Expand Up @@ -781,9 +792,11 @@ impl<T: Event> WinitAppRunnerState<T> {
}
}

world
.resource_mut::<Events<BevyWindowEvent>>()
.send_batch(buffered_events);
if !buffered_events.is_empty() {
world
.resource_mut::<Events<BevyWindowEvent>>()
.send_batch(buffered_events);
}
}

#[cfg(feature = "custom_cursor")]
Expand Down

0 comments on commit 0606734

Please sign in to comment.