Skip to content

Commit

Permalink
Fix Plugin::build detection (#8103)
Browse files Browse the repository at this point in the history
  • Loading branch information
geieredgar authored Mar 17, 2023
1 parent f3d6c2d commit 67afd21
Showing 1 changed file with 20 additions and 10 deletions.
30 changes: 20 additions & 10 deletions crates/bevy_app/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ use bevy_ecs::{
},
};
use bevy_utils::{tracing::debug, HashMap, HashSet};
use std::fmt::Debug;
use std::{
fmt::Debug,
panic::{catch_unwind, resume_unwind, AssertUnwindSafe},
};

#[cfg(feature = "trace")]
use bevy_utils::tracing::info_span;
Expand Down Expand Up @@ -80,8 +83,8 @@ pub struct App {
sub_apps: HashMap<AppLabelId, SubApp>,
plugin_registry: Vec<Box<dyn Plugin>>,
plugin_name_added: HashSet<String>,
/// A private marker to prevent incorrect calls to `App::run()` from `Plugin::build()`
is_building_plugin: bool,
/// A private counter to prevent incorrect calls to `App::run()` from `Plugin::build()`
building_plugin_depth: usize,
}

impl Debug for App {
Expand Down Expand Up @@ -228,7 +231,7 @@ impl App {
plugin_name_added: Default::default(),
default_schedule_label: Box::new(CoreSchedule::Main),
outer_schedule_label: Box::new(CoreSchedule::Outer),
is_building_plugin: false,
building_plugin_depth: 0,
}
}

Expand Down Expand Up @@ -291,8 +294,8 @@ impl App {
let _bevy_app_run_span = info_span!("bevy_app").entered();

let mut app = std::mem::replace(self, App::empty());
if app.is_building_plugin {
panic!("App::run() was called from within Plugin::Build(), which is not allowed.");
if app.building_plugin_depth > 0 {
panic!("App::run() was called from within Plugin::build(), which is not allowed.");
}

Self::setup(&mut app);
Expand Down Expand Up @@ -765,9 +768,12 @@ impl App {
plugin_name: plugin.name().to_string(),
})?;
}
self.is_building_plugin = true;
plugin.build(self);
self.is_building_plugin = false;
self.building_plugin_depth += 1;
let result = catch_unwind(AssertUnwindSafe(|| plugin.build(self)));
self.building_plugin_depth -= 1;
if let Err(payload) = result {
resume_unwind(payload);
}
self.plugin_registry.push(plugin);
Ok(self)
}
Expand Down Expand Up @@ -1071,9 +1077,13 @@ mod tests {
#[should_panic]
fn cant_call_app_run_from_plugin_build() {
struct PluginRun;
struct InnerPlugin;
impl Plugin for InnerPlugin {
fn build(&self, _: &mut crate::App) {}
}
impl Plugin for PluginRun {
fn build(&self, app: &mut crate::App) {
app.run();
app.add_plugin(InnerPlugin).run();
}
}
App::new().add_plugin(PluginRun);
Expand Down

0 comments on commit 67afd21

Please sign in to comment.