diff --git a/crates/bevy_ecs/src/world/world_cell.rs b/crates/bevy_ecs/src/world/world_cell.rs index af7858d256b74..d8256df7d215d 100644 --- a/crates/bevy_ecs/src/world/world_cell.rs +++ b/crates/bevy_ecs/src/world/world_cell.rs @@ -180,6 +180,7 @@ impl<'w> WorldCell<'w> { } } + /// Gets a reference to the resource of the given type pub fn get_resource(&self) -> Option> { let component_id = self.world.components.get_resource_id(TypeId::of::())?; let resource_archetype = self.world.archetypes.resource(); @@ -192,6 +193,26 @@ impl<'w> WorldCell<'w> { )) } + /// Gets a reference to the resource of the given type + /// + /// # Panics + /// + /// Panics if the resource does not exist. Use [`get_resource`](WorldCell::get_resource) instead + /// if you want to handle this case. + pub fn resource(&self) -> WorldBorrow<'_, T> { + match self.get_resource() { + Some(x) => x, + None => panic!( + "Requested resource {} does not exist in the `World`. + Did you forget to add it using `app.add_resource` / `app.init_resource`? + Resources are also implicitly added via `app.add_event`, + and can be added by plugins.", + std::any::type_name::() + ), + } + } + + /// Gets a mutable reference to the resource of the given type pub fn get_resource_mut(&self) -> Option> { let component_id = self.world.components.get_resource_id(TypeId::of::())?; let resource_archetype = self.world.archetypes.resource(); @@ -207,7 +228,27 @@ impl<'w> WorldCell<'w> { )) } - pub fn get_non_send(&self) -> Option> { + /// Gets a mutable reference to the resource of the given type + /// + /// # Panics + /// + /// Panics if the resource does not exist. Use [`get_resource_mut`](WorldCell::get_resource_mut) + /// instead if you want to handle this case. + pub fn resource_mut(&self) -> WorldBorrowMut<'_, T> { + match self.get_resource_mut() { + Some(x) => x, + None => panic!( + "Requested resource {} does not exist in the `World`. + Did you forget to add it using `app.add_resource` / `app.init_resource`? + Resources are also implicitly added via `app.add_event`, + and can be added by plugins.", + std::any::type_name::() + ), + } + } + + /// Gets an immutable reference to the non-send resource of the given type, if it exists. + pub fn get_non_send_resource(&self) -> Option> { let component_id = self.world.components.get_resource_id(TypeId::of::())?; let resource_archetype = self.world.archetypes.resource(); let archetype_component_id = resource_archetype.get_archetype_component_id(component_id)?; @@ -219,7 +260,27 @@ impl<'w> WorldCell<'w> { )) } - pub fn get_non_send_mut(&self) -> Option> { + /// Gets an immutable reference to the non-send resource of the given type, if it exists. + /// + /// # Panics + /// + /// Panics if the resource does not exist. Use + /// [`get_non_send_resource`](WorldCell::get_non_send_resource) instead if you want to handle + /// this case. + pub fn non_send_resource(&self) -> WorldBorrow<'_, T> { + match self.get_non_send_resource() { + Some(x) => x, + None => panic!( + "Requested non-send resource {} does not exist in the `World`. + Did you forget to add it using `app.add_non_send_resource` / `app.init_non_send_resource`? + Non-send resources can also be be added by plugins.", + std::any::type_name::() + ), + } + } + + /// Gets a mutable reference to the non-send resource of the given type, if it exists. + pub fn get_non_send_resource_mut(&self) -> Option> { let component_id = self.world.components.get_resource_id(TypeId::of::())?; let resource_archetype = self.world.archetypes.resource(); let archetype_component_id = resource_archetype.get_archetype_component_id(component_id)?; @@ -233,6 +294,25 @@ impl<'w> WorldCell<'w> { self.access.clone(), )) } + + /// Gets a mutable reference to the non-send resource of the given type, if it exists. + /// + /// # Panics + /// + /// Panics if the resource does not exist. Use + /// [`get_non_send_resource_mut`](WorldCell::get_non_send_resource_mut) instead if you want to + /// handle this case. + pub fn non_send_resource_mut(&self) -> WorldBorrowMut<'_, T> { + match self.get_non_send_resource_mut() { + Some(x) => x, + None => panic!( + "Requested non-send resource {} does not exist in the `World`. + Did you forget to add it using `app.add_non_send_resource` / `app.init_non_send_resource`? + Non-send resources can also be be added by plugins.", + std::any::type_name::() + ), + } + } } #[cfg(test)] @@ -248,28 +328,28 @@ mod tests { world.insert_resource(1u64); let cell = world.cell(); { - let mut a = cell.get_resource_mut::().unwrap(); + let mut a = cell.resource_mut::(); assert_eq!(1, *a); *a = 2; } { - let a = cell.get_resource::().unwrap(); + let a = cell.resource::(); assert_eq!(2, *a, "ensure access is dropped"); - let b = cell.get_resource::().unwrap(); + let b = cell.resource::(); assert_eq!( 2, *b, "ensure multiple immutable accesses can occur at the same time" ); } { - let a = cell.get_resource_mut::().unwrap(); + let a = cell.resource_mut::(); assert_eq!( 2, *a, "ensure both immutable accesses are dropped, enabling a new mutable access" ); - let b = cell.get_resource::().unwrap(); + let b = cell.resource::(); assert_eq!( 1, *b, "ensure multiple non-conflicting mutable accesses can occur at the same time" @@ -284,7 +364,7 @@ mod tests { { let cell = world.cell(); { - let mut a = cell.get_resource_mut::().unwrap(); + let mut a = cell.resource_mut::(); assert_eq!(1, *a); *a = 2; } @@ -315,8 +395,8 @@ mod tests { let mut world = World::default(); world.insert_resource(1u32); let cell = world.cell(); - let _value_a = cell.get_resource_mut::().unwrap(); - let _value_b = cell.get_resource_mut::().unwrap(); + let _value_a = cell.resource_mut::(); + let _value_b = cell.resource_mut::(); } #[test] @@ -325,8 +405,8 @@ mod tests { let mut world = World::default(); world.insert_resource(1u32); let cell = world.cell(); - let _value_a = cell.get_resource::().unwrap(); - let _value_b = cell.get_resource_mut::().unwrap(); + let _value_a = cell.resource::(); + let _value_b = cell.resource_mut::(); } #[test] @@ -335,8 +415,8 @@ mod tests { let mut world = World::default(); world.insert_resource(1u32); let cell = world.cell(); - let _value_a = cell.get_resource_mut::().unwrap(); - let _value_b = cell.get_resource::().unwrap(); + let _value_a = cell.resource_mut::(); + let _value_b = cell.resource::(); } #[test] @@ -345,7 +425,7 @@ mod tests { let mut world = World::default(); world.insert_resource(1u32); let cell = world.cell(); - let _value_a = cell.get_resource_mut::().unwrap(); - let _value_b = cell.get_resource::().unwrap(); + let _value_a = cell.resource_mut::(); + let _value_b = cell.resource::(); } } diff --git a/crates/bevy_pbr/src/render/light.rs b/crates/bevy_pbr/src/render/light.rs index a1b527faa5e54..bef9f3e367949 100644 --- a/crates/bevy_pbr/src/render/light.rs +++ b/crates/bevy_pbr/src/render/light.rs @@ -236,7 +236,7 @@ pub struct ShadowPipeline { impl FromWorld for ShadowPipeline { fn from_world(world: &mut World) -> Self { let world = world.cell(); - let render_device = world.get_resource::().unwrap(); + let render_device = world.resource::(); let view_layout = render_device.create_bind_group_layout(&BindGroupLayoutDescriptor { entries: &[ @@ -255,7 +255,7 @@ impl FromWorld for ShadowPipeline { label: Some("shadow_view_layout"), }); - let mesh_pipeline = world.get_resource::().unwrap(); + let mesh_pipeline = world.resource::(); let skinned_mesh_layout = mesh_pipeline.skinned_mesh_layout.clone(); ShadowPipeline { diff --git a/crates/bevy_sprite/src/render/mod.rs b/crates/bevy_sprite/src/render/mod.rs index 95ddce0649af2..865eccd613424 100644 --- a/crates/bevy_sprite/src/render/mod.rs +++ b/crates/bevy_sprite/src/render/mod.rs @@ -39,7 +39,7 @@ pub struct SpritePipeline { impl FromWorld for SpritePipeline { fn from_world(world: &mut World) -> Self { let world = world.cell(); - let render_device = world.get_resource::().unwrap(); + let render_device = world.resource::(); let view_layout = render_device.create_bind_group_layout(&BindGroupLayoutDescriptor { entries: &[BindGroupLayoutEntry { diff --git a/crates/bevy_ui/src/render/pipeline.rs b/crates/bevy_ui/src/render/pipeline.rs index bedc9f9f3b500..d8034632c701b 100644 --- a/crates/bevy_ui/src/render/pipeline.rs +++ b/crates/bevy_ui/src/render/pipeline.rs @@ -14,7 +14,7 @@ pub struct UiPipeline { impl FromWorld for UiPipeline { fn from_world(world: &mut World) -> Self { let world = world.cell(); - let render_device = world.get_resource::().unwrap(); + let render_device = world.resource::(); let view_layout = render_device.create_bind_group_layout(&BindGroupLayoutDescriptor { entries: &[BindGroupLayoutEntry { diff --git a/crates/bevy_winit/src/lib.rs b/crates/bevy_winit/src/lib.rs index fb992f50dc055..438b722cba698 100644 --- a/crates/bevy_winit/src/lib.rs +++ b/crates/bevy_winit/src/lib.rs @@ -300,8 +300,8 @@ pub fn winit_runner_with(mut app: App) { .. } => { let world = app.world.cell(); - let winit_windows = world.get_non_send_mut::().unwrap(); - let mut windows = world.get_resource_mut::().unwrap(); + let winit_windows = world.non_send_resource_mut::(); + let mut windows = world.resource_mut::(); let window_id = if let Some(window_id) = winit_windows.get_window_id(winit_window_id) { window_id @@ -324,8 +324,7 @@ pub fn winit_runner_with(mut app: App) { match event { WindowEvent::Resized(size) => { window.update_actual_size_from_backend(size.width, size.height); - let mut resize_events = - world.get_resource_mut::>().unwrap(); + let mut resize_events = world.resource_mut::>(); resize_events.send(WindowResized { id: window_id, width: window.width(), @@ -333,19 +332,17 @@ pub fn winit_runner_with(mut app: App) { }); } WindowEvent::CloseRequested => { - let mut window_close_requested_events = world - .get_resource_mut::>() - .unwrap(); + let mut window_close_requested_events = + world.resource_mut::>(); window_close_requested_events.send(WindowCloseRequested { id: window_id }); } WindowEvent::KeyboardInput { ref input, .. } => { let mut keyboard_input_events = - world.get_resource_mut::>().unwrap(); + world.resource_mut::>(); keyboard_input_events.send(converters::convert_keyboard_input(input)); } WindowEvent::CursorMoved { position, .. } => { - let mut cursor_moved_events = - world.get_resource_mut::>().unwrap(); + let mut cursor_moved_events = world.resource_mut::>(); let winit_window = winit_windows.get_window(window_id).unwrap(); let inner_size = winit_window.inner_size(); @@ -363,19 +360,17 @@ pub fn winit_runner_with(mut app: App) { } WindowEvent::CursorEntered { .. } => { let mut cursor_entered_events = - world.get_resource_mut::>().unwrap(); + world.resource_mut::>(); cursor_entered_events.send(CursorEntered { id: window_id }); } WindowEvent::CursorLeft { .. } => { - let mut cursor_left_events = - world.get_resource_mut::>().unwrap(); + let mut cursor_left_events = world.resource_mut::>(); window.update_cursor_physical_position_from_backend(None); cursor_left_events.send(CursorLeft { id: window_id }); } WindowEvent::MouseInput { state, button, .. } => { - let mut mouse_button_input_events = world - .get_resource_mut::>() - .unwrap(); + let mut mouse_button_input_events = + world.resource_mut::>(); mouse_button_input_events.send(MouseButtonInput { button: converters::convert_mouse_button(button), state: converters::convert_element_state(state), @@ -384,7 +379,7 @@ pub fn winit_runner_with(mut app: App) { WindowEvent::MouseWheel { delta, .. } => match delta { event::MouseScrollDelta::LineDelta(x, y) => { let mut mouse_wheel_input_events = - world.get_resource_mut::>().unwrap(); + world.resource_mut::>(); mouse_wheel_input_events.send(MouseWheel { unit: MouseScrollUnit::Line, x, @@ -393,7 +388,7 @@ pub fn winit_runner_with(mut app: App) { } event::MouseScrollDelta::PixelDelta(p) => { let mut mouse_wheel_input_events = - world.get_resource_mut::>().unwrap(); + world.resource_mut::>(); mouse_wheel_input_events.send(MouseWheel { unit: MouseScrollUnit::Pixel, x: p.x as f32, @@ -402,8 +397,7 @@ pub fn winit_runner_with(mut app: App) { } }, WindowEvent::Touch(touch) => { - let mut touch_input_events = - world.get_resource_mut::>().unwrap(); + let mut touch_input_events = world.resource_mut::>(); let mut location = touch.location.to_logical(window.scale_factor()); @@ -416,9 +410,8 @@ pub fn winit_runner_with(mut app: App) { touch_input_events.send(converters::convert_touch_input(touch, location)); } WindowEvent::ReceivedCharacter(c) => { - let mut char_input_events = world - .get_resource_mut::>() - .unwrap(); + let mut char_input_events = + world.resource_mut::>(); char_input_events.send(ReceivedCharacter { id: window_id, @@ -429,9 +422,8 @@ pub fn winit_runner_with(mut app: App) { scale_factor, new_inner_size, } => { - let mut backend_scale_factor_change_events = world - .get_resource_mut::>() - .unwrap(); + let mut backend_scale_factor_change_events = + world.resource_mut::>(); backend_scale_factor_change_events.send(WindowBackendScaleFactorChanged { id: window_id, scale_factor, @@ -450,9 +442,8 @@ pub fn winit_runner_with(mut app: App) { ) .to_physical::(forced_factor); } else if approx::relative_ne!(new_factor, prior_factor) { - let mut scale_factor_change_events = world - .get_resource_mut::>() - .unwrap(); + let mut scale_factor_change_events = + world.resource_mut::>(); scale_factor_change_events.send(WindowScaleFactorChanged { id: window_id, @@ -465,8 +456,7 @@ pub fn winit_runner_with(mut app: App) { if approx::relative_ne!(window.width() as f64, new_logical_width) || approx::relative_ne!(window.height() as f64, new_logical_height) { - let mut resize_events = - world.get_resource_mut::>().unwrap(); + let mut resize_events = world.resource_mut::>(); resize_events.send(WindowResized { id: window_id, width: new_logical_width as f32, @@ -480,38 +470,34 @@ pub fn winit_runner_with(mut app: App) { } WindowEvent::Focused(focused) => { window.update_focused_status_from_backend(focused); - let mut focused_events = - world.get_resource_mut::>().unwrap(); + let mut focused_events = world.resource_mut::>(); focused_events.send(WindowFocused { id: window_id, focused, }); } WindowEvent::DroppedFile(path_buf) => { - let mut events = - world.get_resource_mut::>().unwrap(); + let mut events = world.resource_mut::>(); events.send(FileDragAndDrop::DroppedFile { id: window_id, path_buf, }); } WindowEvent::HoveredFile(path_buf) => { - let mut events = - world.get_resource_mut::>().unwrap(); + let mut events = world.resource_mut::>(); events.send(FileDragAndDrop::HoveredFile { id: window_id, path_buf, }); } WindowEvent::HoveredFileCancelled => { - let mut events = - world.get_resource_mut::>().unwrap(); + let mut events = world.resource_mut::>(); events.send(FileDragAndDrop::HoveredFileCancelled { id: window_id }); } WindowEvent::Moved(position) => { let position = ivec2(position.x, position.y); window.update_actual_position_from_backend(position); - let mut events = world.get_resource_mut::>().unwrap(); + let mut events = world.resource_mut::>(); events.send(WindowMoved { id: window_id, position, @@ -609,10 +595,10 @@ fn handle_create_window_events( create_window_event_reader: &mut ManualEventReader, ) { let world = world.cell(); - let mut winit_windows = world.get_non_send_mut::().unwrap(); - let mut windows = world.get_resource_mut::().unwrap(); - let create_window_events = world.get_resource::>().unwrap(); - let mut window_created_events = world.get_resource_mut::>().unwrap(); + let mut winit_windows = world.non_send_resource_mut::(); + let mut windows = world.resource_mut::(); + let create_window_events = world.resource::>(); + let mut window_created_events = world.resource_mut::>(); for create_window_event in create_window_event_reader.iter(&create_window_events) { let window = winit_windows.create_window( event_loop, @@ -628,10 +614,10 @@ 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_non_send_mut::().unwrap(); - let mut windows = world.get_resource_mut::().unwrap(); - let mut create_window_events = world.get_resource_mut::>().unwrap(); - let mut window_created_events = world.get_resource_mut::>().unwrap(); + let mut winit_windows = world.non_send_resource_mut::(); + let mut windows = world.resource_mut::(); + let mut create_window_events = world.resource_mut::>(); + let mut window_created_events = world.resource_mut::>(); for create_window_event in create_window_events.drain() { let window = winit_windows.create_window( event_loop, diff --git a/examples/shader/animate_shader.rs b/examples/shader/animate_shader.rs index abdf5fafe69b9..2af1d34b85bf8 100644 --- a/examples/shader/animate_shader.rs +++ b/examples/shader/animate_shader.rs @@ -186,10 +186,10 @@ pub struct CustomPipeline { impl FromWorld for CustomPipeline { fn from_world(world: &mut World) -> Self { let world = world.cell(); - let asset_server = world.get_resource::().unwrap(); + let asset_server = world.resource::(); let shader = asset_server.load("shaders/animate_shader.wgsl"); - let render_device = world.get_resource_mut::().unwrap(); + let render_device = world.resource_mut::(); let time_bind_group_layout = render_device.create_bind_group_layout(&BindGroupLayoutDescriptor { label: Some("time bind group"), @@ -205,7 +205,7 @@ impl FromWorld for CustomPipeline { }], }); - let mesh_pipeline = world.get_resource::().unwrap(); + let mesh_pipeline = world.resource::(); CustomPipeline { shader, diff --git a/examples/shader/shader_instancing.rs b/examples/shader/shader_instancing.rs index a036a612f117f..5698c3325b829 100644 --- a/examples/shader/shader_instancing.rs +++ b/examples/shader/shader_instancing.rs @@ -169,11 +169,11 @@ pub struct CustomPipeline { impl FromWorld for CustomPipeline { fn from_world(world: &mut World) -> Self { let world = world.cell(); - let asset_server = world.get_resource::().unwrap(); + let asset_server = world.resource::(); asset_server.watch_for_changes().unwrap(); let shader = asset_server.load("shaders/instancing.wgsl"); - let mesh_pipeline = world.get_resource::().unwrap(); + let mesh_pipeline = world.resource::(); CustomPipeline { shader,