From 1777aa22d00f962a80d4690ebc0c2acfc535ef53 Mon Sep 17 00:00:00 2001 From: Joshua Holmes Date: Tue, 10 Jun 2025 18:06:36 -0700 Subject: [PATCH 1/4] Make `GILRS` and `WINIT_WINDOWS` public --- crates/bevy_gilrs/src/lib.rs | 2 +- crates/bevy_winit/src/lib.rs | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/crates/bevy_gilrs/src/lib.rs b/crates/bevy_gilrs/src/lib.rs index db1b404abcab8..9b86edf03a01a 100644 --- a/crates/bevy_gilrs/src/lib.rs +++ b/crates/bevy_gilrs/src/lib.rs @@ -39,7 +39,7 @@ thread_local! { /// `NonSendMut` parameter, which told Bevy that the system was `!Send`, but now with the removal of `!Send` /// resource/system parameter usage, there is no internal guarantee that the system will run in only one thread, so /// we need to rely on the platform to make such a guarantee. - static GILRS: RefCell> = const { RefCell::new(None) }; + pub static GILRS: RefCell> = const { RefCell::new(None) }; } #[derive(Resource)] diff --git a/crates/bevy_winit/src/lib.rs b/crates/bevy_winit/src/lib.rs index 968386bc02d06..4373c4dcfd128 100644 --- a/crates/bevy_winit/src/lib.rs +++ b/crates/bevy_winit/src/lib.rs @@ -55,7 +55,9 @@ mod winit_monitors; mod winit_windows; thread_local! { - static WINIT_WINDOWS: RefCell = const { RefCell::new(WinitWindows::new()) }; + /// Temporary storage of WinitWindows data to replace usage of `!Send` resources. This will be replaced with proper + /// storage of `!Send` data after issue #17667 is complete. + pub static WINIT_WINDOWS: RefCell = const { RefCell::new(WinitWindows::new()) }; } /// A [`Plugin`] that uses `winit` to create and manage windows, and receive window and input From 586f8b98e9d07e6e48878da28d2ccf413892780a Mon Sep 17 00:00:00 2001 From: Joshua Holmes Date: Tue, 10 Jun 2025 18:48:45 -0700 Subject: [PATCH 2/4] Add migration guide --- .../replace_non_send_resources.md | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 release-content/migration-guides/replace_non_send_resources.md diff --git a/release-content/migration-guides/replace_non_send_resources.md b/release-content/migration-guides/replace_non_send_resources.md new file mode 100644 index 0000000000000..4aa7484017b5c --- /dev/null +++ b/release-content/migration-guides/replace_non_send_resources.md @@ -0,0 +1,37 @@ +--- +title: Replace `Gilrs`, `AccessKitAdapters`, and `WinitWindows` resources +pull_requests: [18386, 17730, 19575] +--- + +As an effort to remove `!Send` resources in Bevy, we replaced the following resources: +* `Gilrs` - _For wasm32 only, other platforms are unchanged -_ Replaced with `bevy_gilrs::GILRS` +* `WinitWindows` - Replaced with `bevy_winit::WINIT_WINDOWS` +* `AccessKitAdapters` - Replaced with `bevy_winit::ACCESS_KIT_ADAPTERS` + +Each of these are now using `thread_local`s to store the data and are temporary solutions to storing `!Send` data. Even though `thread_local`s are thread safe, they should not be accessed from other threads. If they are accessed from other threads, the data will be uninitialized in each non-main thread, which isn't very useful. + +Here is an example of how the data can now be accessed. This example will use `WINIT_WINDOWS` as an example, but the same technique can be applied to the others: + +__Immutable Access__ +```rust +use bevy_winit::WINIT_WINDOWS; + +... + +WINIT_WINDOWS.with_borrow(|winit_windows| { + // do things with `winit_windows` +}); +``` + +__Mutable Access__ +```rust +use bevy_winit::WINIT_WINDOWS; + +... + +WINIT_WINDOWS.with_borrow_mut(|winit_windows| { + // do things with `winit_windows` +}); +``` + +If a borrow is attempted while the data is borrowed elsewhere, the method will panic. From 373b8ba2fc9e9b2217608e3ddf778878e2720be3 Mon Sep 17 00:00:00 2001 From: Joshua Holmes Date: Wed, 11 Jun 2025 17:32:58 -0700 Subject: [PATCH 3/4] Add instructions for use of `NonSendMarker` --- .../replace_non_send_resources.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/release-content/migration-guides/replace_non_send_resources.md b/release-content/migration-guides/replace_non_send_resources.md index 4aa7484017b5c..0f118a3d5ab93 100644 --- a/release-content/migration-guides/replace_non_send_resources.md +++ b/release-content/migration-guides/replace_non_send_resources.md @@ -35,3 +35,19 @@ WINIT_WINDOWS.with_borrow_mut(|winit_windows| { ``` If a borrow is attempted while the data is borrowed elsewhere, the method will panic. + +Previously, the use of a `!Send` resource in a system would force the system to execute on the main thread. Since `!Send` resources are removed in Bevy, we needed to create a new way to prevent systems from running on non-main threads. To do this, you can now use `bevy_ecs::system::NonSendMarker` as a system parameter: + +```rust +use bevy_ecs::system::NonSendMarker; + +fn my_system( + _non_send_marker: NonSendMarker, +) { + ACCESS_KIT_ADAPTERS.with_borrow_mut(|adapters| { + // do things with adapters + }); +} +``` + +To prevent a panic, if any of the `!Send` resource replacements mentioned in this document are used in a system, the system should _always_ be marked as `!Send` with `bevy_ecs::system::NonSendMarker`. From 5937256d3ec07b3356aabbeab9e94462b03d051e Mon Sep 17 00:00:00 2001 From: Joshua Holmes Date: Thu, 12 Jun 2025 11:19:29 -0700 Subject: [PATCH 4/4] Fix linting errors and add headers to migration guide --- .../migration-guides/replace_non_send_resources.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/release-content/migration-guides/replace_non_send_resources.md b/release-content/migration-guides/replace_non_send_resources.md index 0f118a3d5ab93..e26a24b19ac45 100644 --- a/release-content/migration-guides/replace_non_send_resources.md +++ b/release-content/migration-guides/replace_non_send_resources.md @@ -3,7 +3,10 @@ title: Replace `Gilrs`, `AccessKitAdapters`, and `WinitWindows` resources pull_requests: [18386, 17730, 19575] --- +## NonSend Resources Replaced + As an effort to remove `!Send` resources in Bevy, we replaced the following resources: + * `Gilrs` - _For wasm32 only, other platforms are unchanged -_ Replaced with `bevy_gilrs::GILRS` * `WinitWindows` - Replaced with `bevy_winit::WINIT_WINDOWS` * `AccessKitAdapters` - Replaced with `bevy_winit::ACCESS_KIT_ADAPTERS` @@ -12,7 +15,8 @@ Each of these are now using `thread_local`s to store the data and are temporary Here is an example of how the data can now be accessed. This example will use `WINIT_WINDOWS` as an example, but the same technique can be applied to the others: -__Immutable Access__ +### Immutable Access + ```rust use bevy_winit::WINIT_WINDOWS; @@ -23,7 +27,8 @@ WINIT_WINDOWS.with_borrow(|winit_windows| { }); ``` -__Mutable Access__ +### Mutable Access + ```rust use bevy_winit::WINIT_WINDOWS; @@ -36,6 +41,8 @@ WINIT_WINDOWS.with_borrow_mut(|winit_windows| { If a borrow is attempted while the data is borrowed elsewhere, the method will panic. +## NonSend Systems + Previously, the use of a `!Send` resource in a system would force the system to execute on the main thread. Since `!Send` resources are removed in Bevy, we needed to create a new way to prevent systems from running on non-main threads. To do this, you can now use `bevy_ecs::system::NonSendMarker` as a system parameter: ```rust