mirror of
https://github.com/bevyengine/bevy
synced 2024-11-26 06:30:19 +00:00
Make WinitWindows
non send (#4027)
# Objective - Fixes #4010, as well as any similar issues in this class. - Winit functions used outside of the main thread can cause the application to unexpectedly hang. ## Solution - Make the `WinitWindows` resource `!Send`. - This ensures that any systems that use `WinitWindows` must either be exclusive (run on the main thread), or the resource is explicitly marked with the `NonSend` parameter in user systems.
This commit is contained in:
parent
81d57e129b
commit
a2d49f4a69
2 changed files with 9 additions and 5 deletions
|
@ -32,7 +32,7 @@ pub struct WinitPlugin;
|
|||
|
||||
impl Plugin for WinitPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.init_resource::<WinitWindows>()
|
||||
app.init_non_send_resource::<WinitWindows>()
|
||||
.set_runner(winit_runner)
|
||||
.add_system_to_stage(CoreStage::PostUpdate, change_window.exclusive_system());
|
||||
let event_loop = EventLoop::new();
|
||||
|
@ -43,7 +43,7 @@ impl Plugin for WinitPlugin {
|
|||
|
||||
fn change_window(world: &mut World) {
|
||||
let world = world.cell();
|
||||
let winit_windows = world.get_resource::<WinitWindows>().unwrap();
|
||||
let winit_windows = world.get_non_send::<WinitWindows>().unwrap();
|
||||
let mut windows = world.get_resource_mut::<Windows>().unwrap();
|
||||
|
||||
for bevy_window in windows.iter_mut() {
|
||||
|
@ -264,7 +264,7 @@ pub fn winit_runner_with(mut app: App) {
|
|||
..
|
||||
} => {
|
||||
let world = app.world.cell();
|
||||
let winit_windows = world.get_resource_mut::<WinitWindows>().unwrap();
|
||||
let winit_windows = world.get_non_send_mut::<WinitWindows>().unwrap();
|
||||
let mut windows = world.get_resource_mut::<Windows>().unwrap();
|
||||
let window_id =
|
||||
if let Some(window_id) = winit_windows.get_window_id(winit_window_id) {
|
||||
|
@ -525,7 +525,7 @@ fn handle_create_window_events(
|
|||
create_window_event_reader: &mut ManualEventReader<CreateWindow>,
|
||||
) {
|
||||
let world = world.cell();
|
||||
let mut winit_windows = world.get_resource_mut::<WinitWindows>().unwrap();
|
||||
let mut winit_windows = world.get_non_send_mut::<WinitWindows>().unwrap();
|
||||
let mut windows = world.get_resource_mut::<Windows>().unwrap();
|
||||
let create_window_events = world.get_resource::<Events<CreateWindow>>().unwrap();
|
||||
let mut window_created_events = world.get_resource_mut::<Events<WindowCreated>>().unwrap();
|
||||
|
@ -544,7 +544,7 @@ fn handle_create_window_events(
|
|||
|
||||
fn handle_initial_window_events(world: &mut World, event_loop: &EventLoop<()>) {
|
||||
let world = world.cell();
|
||||
let mut winit_windows = world.get_resource_mut::<WinitWindows>().unwrap();
|
||||
let mut winit_windows = world.get_non_send_mut::<WinitWindows>().unwrap();
|
||||
let mut windows = world.get_resource_mut::<Windows>().unwrap();
|
||||
let mut create_window_events = world.get_resource_mut::<Events<CreateWindow>>().unwrap();
|
||||
let mut window_created_events = world.get_resource_mut::<Events<WindowCreated>>().unwrap();
|
||||
|
|
|
@ -9,6 +9,10 @@ pub struct WinitWindows {
|
|||
pub windows: HashMap<winit::window::WindowId, winit::window::Window>,
|
||||
pub window_id_to_winit: HashMap<WindowId, winit::window::WindowId>,
|
||||
pub winit_to_window_id: HashMap<winit::window::WindowId, WindowId>,
|
||||
// Some winit functions, such as `set_window_icon` can only be used from the main thread. If
|
||||
// they are used in another thread, the app will hang. This marker ensures `WinitWindows` is
|
||||
// only ever accessed with bevy's non-send functions and in NonSend systems.
|
||||
_not_send_sync: core::marker::PhantomData<*const ()>,
|
||||
}
|
||||
|
||||
impl WinitWindows {
|
||||
|
|
Loading…
Reference in a new issue