From f51a306b30dfde0a3e315e291686ce70d4ace365 Mon Sep 17 00:00:00 2001 From: Sou1gh0st Date: Tue, 25 Jun 2024 22:04:31 +0800 Subject: [PATCH] feat(bevy_app): expose an API to perform updates for a specific sub-app. (#14009) # Objective - Fixes https://github.com/bevyengine/bevy/issues/14003 ## Solution - Expose an API to perform updates for a specific sub-app, so we can avoid mutable borrow the app twice. ## Testing - I have tested the API by modifying the code in the `many_lights` example with the following changes: ```rust impl Plugin for LogVisibleLights { fn build(&self, app: &mut App) { let Some(render_app) = app.get_sub_app_mut(RenderApp) else { return; }; render_app.add_systems(Render, print_visible_light_count.in_set(RenderSet::Prepare)); } fn finish(&self, app: &mut App) { app.update_sub_app_by_label(RenderApp); } } ``` --- ## Changelog - add the `update_sub_app_by_label` API to `App` and `SubApps`. --------- Co-authored-by: Jan Hohenheim --- crates/bevy_app/src/app.rs | 5 +++++ crates/bevy_app/src/sub_app.rs | 10 +++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/crates/bevy_app/src/app.rs b/crates/bevy_app/src/app.rs index fdd7db483beaa..9825cf4ed3c6f 100644 --- a/crates/bevy_app/src/app.rs +++ b/crates/bevy_app/src/app.rs @@ -663,6 +663,11 @@ impl App { self.sub_apps.sub_apps.remove(&label.intern()) } + /// Extract data from the main world into the [`SubApp`] with the given label and perform an update if it exists. + pub fn update_sub_app_by_label(&mut self, label: impl AppLabel) { + self.sub_apps.update_subapp_by_label(label); + } + /// Inserts a new `schedule` under the provided `label`, overwriting any existing /// schedule with the same label. pub fn add_schedule(&mut self, schedule: Schedule) -> &mut Self { diff --git a/crates/bevy_app/src/sub_app.rs b/crates/bevy_app/src/sub_app.rs index 59ad4eca8b105..832f87357deb2 100644 --- a/crates/bevy_app/src/sub_app.rs +++ b/crates/bevy_app/src/sub_app.rs @@ -1,4 +1,4 @@ -use crate::{App, InternedAppLabel, Plugin, Plugins, PluginsState}; +use crate::{App, AppLabel, InternedAppLabel, Plugin, Plugins, PluginsState}; use bevy_ecs::{ event::EventRegistry, prelude::*, @@ -449,4 +449,12 @@ impl SubApps { pub fn iter_mut(&mut self) -> impl Iterator + '_ { std::iter::once(&mut self.main).chain(self.sub_apps.values_mut()) } + + /// Extract data from the main world into the [`SubApp`] with the given label and perform an update if it exists. + pub fn update_subapp_by_label(&mut self, label: impl AppLabel) { + if let Some(sub_app) = self.sub_apps.get_mut(&label.intern()) { + sub_app.extract(&mut self.main.world); + sub_app.update(); + } + } }