From 4ae6a66481b1b1eab8039f8406bb73210ed4c689 Mon Sep 17 00:00:00 2001 From: Thomas Wilgenbus Date: Sat, 14 Oct 2023 18:07:49 +0200 Subject: [PATCH] Allow optional extraction of resources from the main world (#10109) # Objective From my understanding, although resources are not meant to be created and removed at every frame, they are still meant to be created dynamically during the lifetime of the App. But because the extract_resource API does not allow optional resources from the main world, it's impossible to use resources in the render phase that were not created before the render sub-app itself. ## Solution Because the ECS engine already allows for system parameters to be `Option`, it just had to be added. --- ## Changelog - Changed - `extract_resource` now takes an optional main world resource - Fixed - `ExtractResourcePlugin` doesn't cause panics anymore if the resource is not already inserted --- crates/bevy_render/src/extract_resource.rs | 30 ++++++++++++---------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/crates/bevy_render/src/extract_resource.rs b/crates/bevy_render/src/extract_resource.rs index 4233ef61b5d61..37a21f45bf84c 100644 --- a/crates/bevy_render/src/extract_resource.rs +++ b/crates/bevy_render/src/extract_resource.rs @@ -40,24 +40,26 @@ impl Plugin for ExtractResourcePlugin { /// This system extracts the resource of the corresponding [`Resource`] type pub fn extract_resource( mut commands: Commands, - main_resource: Extract>, + main_resource: Extract>>, target_resource: Option>, #[cfg(debug_assertions)] mut has_warned_on_remove: Local, ) { - if let Some(mut target_resource) = target_resource { - if main_resource.is_changed() { - *target_resource = R::extract_resource(&main_resource); - } - } else { - #[cfg(debug_assertions)] - if !main_resource.is_added() && !*has_warned_on_remove { - *has_warned_on_remove = true; - bevy_log::warn!( - "Removing resource {} from render world not expected, adding using `Commands`. + if let Some(main_resource) = main_resource.as_ref() { + if let Some(mut target_resource) = target_resource { + if main_resource.is_changed() { + *target_resource = R::extract_resource(main_resource); + } + } else { + #[cfg(debug_assertions)] + if !main_resource.is_added() && !*has_warned_on_remove { + *has_warned_on_remove = true; + bevy_log::warn!( + "Removing resource {} from render world not expected, adding using `Commands`. This may decrease performance", - std::any::type_name::() - ); + std::any::type_name::() + ); + } + commands.insert_resource(R::extract_resource(main_resource)); } - commands.insert_resource(R::extract_resource(&main_resource)); } }