Skip to content

Commit

Permalink
Allow optional extraction of resources from the main world (bevyengin…
Browse files Browse the repository at this point in the history
…e#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<Res>`, 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
  • Loading branch information
Thomas Wilgenbus committed Oct 14, 2023
1 parent 35073cf commit 4ae6a66
Showing 1 changed file with 16 additions and 14 deletions.
30 changes: 16 additions & 14 deletions crates/bevy_render/src/extract_resource.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,24 +40,26 @@ impl<R: ExtractResource> Plugin for ExtractResourcePlugin<R> {
/// This system extracts the resource of the corresponding [`Resource`] type
pub fn extract_resource<R: ExtractResource>(
mut commands: Commands,
main_resource: Extract<Res<R::Source>>,
main_resource: Extract<Option<Res<R::Source>>>,
target_resource: Option<ResMut<R>>,
#[cfg(debug_assertions)] mut has_warned_on_remove: Local<bool>,
) {
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::<R>()
);
std::any::type_name::<R>()
);
}
commands.insert_resource(R::extract_resource(main_resource));
}
commands.insert_resource(R::extract_resource(&main_resource));
}
}

0 comments on commit 4ae6a66

Please sign in to comment.