Add SubApp::take_extract() (#16862)

# Objective

Fixes #16850

## Solution

Add a new function `SubApp::take_extract()`, similar to
`Option::take()`, which allows stealing the currently installed extract
function of a sub-app, with the intent to replace it with a custom one
calling the original one via `set_extract()`.

This pattern enables registering a custom "world sync" function similar
to the existing one `entity_sync_system()`, to run custom world sync
logic with mutable access to both the main and render worlds.

## Testing

`cargo r -p ci` currently doesn't build locally, event after upgrading
rustc to latest and doing a `cargo update`.
This commit is contained in:
Jerome Humbert 2024-12-24 18:26:32 +00:00 committed by François Mockers
parent 38dec272fe
commit 1f72e078ae

View File

@ -164,6 +164,35 @@ impl SubApp {
self
}
/// Take the function that will be called by [`extract`](Self::extract) out of the app, if any was set,
/// and replace it with `None`.
///
/// If you use Bevy, `bevy_render` will set a default extract function used to extract data from
/// the main world into the render world as part of the Extract phase. In that case, you cannot replace
/// it with your own function. Instead, take the Bevy default function with this, and install your own
/// instead which calls the Bevy default.
///
/// ```
/// # use bevy_app::SubApp;
/// # let mut app = SubApp::new();
/// let default_fn = app.take_extract();
/// app.set_extract(move |main, render| {
/// // Do pre-extract custom logic
/// // [...]
///
/// // Call Bevy's default, which executes the Extract phase
/// if let Some(f) = default_fn.as_ref() {
/// f(main, render);
/// }
///
/// // Do post-extract custom logic
/// // [...]
/// });
/// ```
pub fn take_extract(&mut self) -> Option<ExtractFn> {
self.extract.take()
}
/// See [`App::insert_resource`].
pub fn insert_resource<R: Resource>(&mut self, resource: R) -> &mut Self {
self.world.insert_resource(resource);