diff --git a/crates/bevy_app/src/app.rs b/crates/bevy_app/src/app.rs index 2e5ba17a0edbc..56859989631e7 100644 --- a/crates/bevy_app/src/app.rs +++ b/crates/bevy_app/src/app.rs @@ -424,9 +424,12 @@ impl App { self } - /// Inserts the [`!Send`](Send) resource into the app, initialized with its default value, - /// if there is no existing instance of `R`. - pub fn init_non_send_resource(&mut self) -> &mut Self { + /// Inserts the [`!Send`](Send) resource into the app if there is no existing instance of `R`. + /// + /// `R` must implement [`FromWorld`]. + /// If `R` implements [`Default`], [`FromWorld`] will be automatically implemented and + /// initialize the [`Resource`] with [`Default::default`]. + pub fn init_non_send_resource(&mut self) -> &mut Self { self.world_mut().init_non_send_resource::(); self } @@ -916,8 +919,11 @@ impl Termination for AppExit { #[cfg(test)] mod tests { + use std::sync::Mutex; use std::{marker::PhantomData, mem}; + use bevy_ecs::prelude::{Resource, World}; + use bevy_ecs::world::FromWorld; use bevy_ecs::{event::EventWriter, schedule::ScheduleLabel, system::Commands}; use crate::{App, AppExit, Plugin, Update}; @@ -1178,4 +1184,31 @@ mod tests { // it's nice they're so small let's keep it that way. assert_eq!(mem::size_of::(), mem::size_of::()); } + + #[test] + fn initializing_resources_from_world() { + #[derive(Resource)] + struct TestResource; + impl FromWorld for TestResource { + fn from_world(_world: &mut World) -> Self { + TestResource + } + } + + #[derive(Resource)] + struct NonSendTestResource { + _marker: PhantomData>, + } + impl FromWorld for NonSendTestResource { + fn from_world(_world: &mut World) -> Self { + NonSendTestResource { + _marker: PhantomData, + } + } + } + + App::new() + .init_non_send_resource::() + .init_resource::(); + } }