Skip to content

Commit b151ec8

Browse files
committed
add setup resources
1 parent 1914696 commit b151ec8

29 files changed

+100
-52
lines changed

crates/bevy_app/src/app.rs

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@ use bevy_ecs::{
1111
system::Resource,
1212
world::World,
1313
};
14-
use bevy_utils::{tracing::debug, HashMap};
14+
use bevy_utils::{
15+
tracing::{debug, error},
16+
HashMap,
17+
};
1518
use std::fmt::Debug;
1619

1720
#[cfg(feature = "trace")]
@@ -28,6 +31,10 @@ bevy_utils::define_label!(
2831
#[derive(Resource, Clone, Deref, DerefMut, Default)]
2932
pub struct AppTypeRegistry(pub bevy_reflect::TypeRegistryArc);
3033

34+
/// Wrapper struct for setting setup resources aside
35+
#[derive(Resource)]
36+
struct Setup<T>(T);
37+
3138
#[allow(clippy::needless_doctest_main)]
3239
/// A container of app logic and data.
3340
///
@@ -68,6 +75,7 @@ pub struct App {
6875
/// A container of [`Stage`]s set to be run in a linear order.
6976
pub schedule: Schedule,
7077
sub_apps: HashMap<AppLabelId, SubApp>,
78+
setup_resources: HashMap<std::any::TypeId, &'static str>,
7179
}
7280

7381
/// Each `SubApp` has its own [`Schedule`] and [`World`], enabling a separation of concerns.
@@ -111,6 +119,7 @@ impl App {
111119
schedule: Default::default(),
112120
runner: Box::new(run_once),
113121
sub_apps: HashMap::default(),
122+
setup_resources: Default::default(),
114123
}
115124
}
116125

@@ -136,6 +145,8 @@ impl App {
136145
#[cfg(feature = "trace")]
137146
let _bevy_app_run_span = info_span!("bevy_app").entered();
138147

148+
self.check_all_setup_resources_consumed();
149+
139150
let mut app = std::mem::replace(self, App::empty());
140151
let runner = std::mem::replace(&mut app.runner, Box::new(run_once));
141152
(runner)(app);
@@ -654,6 +665,44 @@ impl App {
654665
self
655666
}
656667

668+
/// Inserts a setup resource to the current [App] and overwrites any resource
669+
/// previously added of the same type.
670+
///
671+
/// A setup resource is used at startup for plugin initialisation and configuration.
672+
/// All setup resources inserted must be consumed by a plugin and removed before the
673+
/// application is ran.
674+
pub fn insert_setup_resource<T>(&mut self, resource: T) -> &mut Self
675+
where
676+
T: Resource,
677+
{
678+
self.setup_resources
679+
.insert(std::any::TypeId::of::<T>(), std::any::type_name::<T>());
680+
self.insert_resource(Setup(resource));
681+
self
682+
}
683+
684+
/// Consumes a setup resource, and removes it from the current [App] so that a plugin
685+
/// can use it for its setup.
686+
pub fn consume_setup_resource<T>(&mut self) -> Option<T>
687+
where
688+
T: Resource,
689+
{
690+
self.setup_resources.remove(&std::any::TypeId::of::<T>());
691+
self.world
692+
.remove_resource::<Setup<T>>()
693+
.map(|setup| setup.0)
694+
}
695+
696+
/// Check that all setup resources have been consumed, panicking otherwise.
697+
fn check_all_setup_resources_consumed(&self) {
698+
self.setup_resources
699+
.values()
700+
.for_each(|v| error!("Setup resource \"{}\" has not been consumed", v));
701+
if !self.setup_resources.is_empty() {
702+
panic!("Not all setup resources have been consumed. This can happen if you inserted a setup resource after the plugin consuming it.")
703+
}
704+
}
705+
657706
/// Inserts a [`Resource`] to the current [`App`] and overwrites any [`Resource`] previously added of the same type.
658707
///
659708
/// A [`Resource`] in Bevy represents globally unique data. [`Resource`]s must be added to Bevy apps

crates/bevy_asset/src/debug_asset_server.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ impl Plugin for DebugAssetServerPlugin {
7676
});
7777
let mut debug_asset_app = App::new();
7878
debug_asset_app
79-
.insert_resource(AssetServerSettings {
79+
.insert_setup_resource(AssetServerSettings {
8080
asset_folder: "crates".to_string(),
8181
watch_for_changes: true,
8282
})

crates/bevy_asset/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,8 @@ impl Default for AssetServerSettings {
9191
/// delegate to the default `AssetIo` for the platform.
9292
pub fn create_platform_default_asset_io(app: &mut App) -> Box<dyn AssetIo> {
9393
let settings = app
94-
.world
95-
.get_resource_or_insert_with(AssetServerSettings::default);
94+
.consume_setup_resource::<AssetServerSettings>()
95+
.unwrap_or_default();
9696

9797
#[cfg(all(not(target_arch = "wasm32"), not(target_os = "android")))]
9898
let source = FileAssetIo::new(&settings.asset_folder, settings.watch_for_changes);

crates/bevy_core/src/lib.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,7 @@ pub struct CorePlugin;
2727
impl Plugin for CorePlugin {
2828
fn build(&self, app: &mut App) {
2929
// Setup the default bevy task pools
30-
app.world
31-
.get_resource::<DefaultTaskPoolOptions>()
32-
.cloned()
30+
app.consume_setup_resource::<DefaultTaskPoolOptions>()
3331
.unwrap_or_default()
3432
.create_default_pools();
3533

crates/bevy_log/src/lib.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,14 @@ use tracing_subscriber::{prelude::*, registry::Registry, EnvFilter};
4747
/// * Using [`tracing-wasm`](https://crates.io/crates/tracing-wasm) in WASM, logging
4848
/// to the browser console.
4949
///
50-
/// You can configure this plugin using the resource [`LogSettings`].
50+
/// You can configure this plugin using the setup resource [`LogSettings`].
5151
/// ```no_run
5252
/// # use bevy_app::{App, NoopPluginGroup as DefaultPlugins};
5353
/// # use bevy_log::LogSettings;
5454
/// # use bevy_utils::tracing::Level;
5555
/// fn main() {
5656
/// App::new()
57-
/// .insert_resource(LogSettings {
57+
/// .insert_setup_resource(LogSettings {
5858
/// level: Level::DEBUG,
5959
/// filter: "wgpu=error,bevy_render=info,bevy_ecs=trace".to_string(),
6060
/// })
@@ -122,7 +122,9 @@ impl Plugin for LogPlugin {
122122
}
123123

124124
let default_filter = {
125-
let settings = app.world.get_resource_or_insert_with(LogSettings::default);
125+
let settings = app
126+
.consume_setup_resource::<LogSettings>()
127+
.unwrap_or_default();
126128
format!("{},{}", settings.level, settings.filter)
127129
};
128130
LogTracer::init().unwrap();

crates/bevy_window/src/event.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::path::PathBuf;
22

3-
use super::{WindowDescriptor, WindowId};
3+
use super::{WindowId, WindowSetupDescriptor};
44
use bevy_math::{IVec2, Vec2};
55

66
/// A window event that is sent whenever a window's logical size has changed.
@@ -17,7 +17,7 @@ pub struct WindowResized {
1717
#[derive(Debug, Clone)]
1818
pub struct CreateWindow {
1919
pub id: WindowId,
20-
pub descriptor: WindowDescriptor,
20+
pub descriptor: WindowSetupDescriptor,
2121
}
2222

2323
/// An event that indicates the window should redraw, even if its control flow is set to `Wait` and

crates/bevy_window/src/lib.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ pub mod prelude {
1717
#[doc(hidden)]
1818
pub use crate::{
1919
CursorEntered, CursorIcon, CursorLeft, CursorMoved, FileDragAndDrop, MonitorSelection,
20-
ReceivedCharacter, Window, WindowDescriptor, WindowMode, WindowMoved, WindowPosition,
20+
ReceivedCharacter, Window, WindowMode, WindowMoved, WindowPosition, WindowSetupDescriptor,
2121
Windows,
2222
};
2323
}
@@ -99,9 +99,7 @@ impl Plugin for WindowPlugin {
9999

100100
if settings.add_primary_window {
101101
let window_descriptor = app
102-
.world
103-
.get_resource::<WindowDescriptor>()
104-
.cloned()
102+
.consume_setup_resource::<WindowSetupDescriptor>()
105103
.unwrap_or_default();
106104
let mut create_window_event = app.world.resource_mut::<Events<CreateWindow>>();
107105
create_window_event.send(CreateWindow {

crates/bevy_window/src/window.rs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,9 @@ pub struct WindowId(Uuid);
2020
///
2121
/// `Immediate` or `Mailbox` will gracefully fallback to `Fifo` when unavailable.
2222
///
23-
/// The presentation mode may be declared in the [`WindowDescriptor`](WindowDescriptor::present_mode)
24-
/// or updated on a [`Window`](Window::set_present_mode).
23+
/// The presentation mode may be declared in the
24+
/// [`WindowSetupDescriptor`](WindowSetupDescriptor::present_mode) or updated on a
25+
/// [`Window`](Window::set_present_mode).
2526
#[repr(C)]
2627
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
2728
#[doc(alias = "vsync")]
@@ -305,7 +306,7 @@ impl Window {
305306
/// Creates a new [`Window`].
306307
pub fn new(
307308
id: WindowId,
308-
window_descriptor: &WindowDescriptor,
309+
window_descriptor: &WindowSetupDescriptor,
309310
physical_width: u32,
310311
physical_height: u32,
311312
scale_factor: f64,
@@ -751,13 +752,13 @@ pub enum WindowPosition {
751752
Automatic,
752753
/// Center the window on the monitor.
753754
///
754-
/// The monitor to center the window on can be selected with the `monitor` field in `WindowDescriptor`.
755+
/// The monitor to center the window on can be selected with the `monitor` field in `WindowSetupDescriptor`.
755756
Centered,
756757
/// The window's top-left corner will be placed at the specified position in pixels.
757758
///
758759
/// (0,0) represents top-left corner of the monitor.
759760
///
760-
/// The monitor to position the window on can be selected with the `monitor` field in `WindowDescriptor`.
761+
/// The monitor to position the window on can be selected with the `monitor` field in `WindowSetupDescriptor`.
761762
At(Vec2),
762763
}
763764

@@ -783,7 +784,7 @@ pub enum MonitorSelection {
783784
///
784785
/// [`examples/window/window_settings.rs`]: https://github.com/bevyengine/bevy/blob/latest/examples/window/window_settings.rs
785786
#[derive(Resource, Debug, Clone)]
786-
pub struct WindowDescriptor {
787+
pub struct WindowSetupDescriptor {
787788
/// The requested logical width of the window's client area.
788789
///
789790
/// May vary from the physical width due to different pixel density on different monitors.
@@ -861,9 +862,9 @@ pub struct WindowDescriptor {
861862
pub fit_canvas_to_parent: bool,
862863
}
863864

864-
impl Default for WindowDescriptor {
865+
impl Default for WindowSetupDescriptor {
865866
fn default() -> Self {
866-
WindowDescriptor {
867+
WindowSetupDescriptor {
867868
title: "app".to_string(),
868869
width: 1280.,
869870
height: 720.,

crates/bevy_winit/src/winit_windows.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use bevy_math::{DVec2, IVec2};
22
use bevy_utils::HashMap;
3-
use bevy_window::{MonitorSelection, Window, WindowDescriptor, WindowId, WindowMode};
3+
use bevy_window::{MonitorSelection, Window, WindowId, WindowMode, WindowSetupDescriptor};
44
use raw_window_handle::HasRawWindowHandle;
55
use winit::{
66
dpi::{LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize},
@@ -23,11 +23,11 @@ impl WinitWindows {
2323
&mut self,
2424
event_loop: &winit::event_loop::EventLoopWindowTarget<()>,
2525
window_id: WindowId,
26-
window_descriptor: &WindowDescriptor,
26+
window_descriptor: &WindowSetupDescriptor,
2727
) -> Window {
2828
let mut winit_window_builder = winit::window::WindowBuilder::new();
2929

30-
let &WindowDescriptor {
30+
let &WindowSetupDescriptor {
3131
width,
3232
height,
3333
position,

examples/app/logs.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use bevy::prelude::*;
55
fn main() {
66
App::new()
77
// Uncomment this to override the default log settings:
8-
// .insert_resource(bevy::log::LogSettings {
8+
// .insert_setup_resource(bevy::log::LogSettings {
99
// level: bevy::log::Level::TRACE,
1010
// filter: "wgpu=warn,bevy_ecs=info".to_string(),
1111
// })
@@ -24,7 +24,7 @@ fn log_system() {
2424
error!("something failed");
2525

2626
// by default, trace and debug logs are ignored because they are "noisy"
27-
// you can control what level is logged by adding the LogSettings resource
27+
// you can control what level is logged by adding the LogSettings setup resource
2828
// alternatively you can set the log level via the RUST_LOG=LEVEL environment variable
2929
// ex: RUST_LOG=trace, RUST_LOG=info,bevy_ecs=warn
3030
// the format used here is super flexible. check out this documentation for more info:

examples/app/thread_pool_resources.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use bevy::prelude::*;
55

66
fn main() {
77
App::new()
8-
.insert_resource(DefaultTaskPoolOptions::with_num_threads(4))
8+
.insert_setup_resource(DefaultTaskPoolOptions::with_num_threads(4))
99
.add_plugins(DefaultPlugins)
1010
.run();
1111
}

examples/asset/hot_asset_reloading.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use bevy::{asset::AssetServerSettings, prelude::*};
77
fn main() {
88
App::new()
99
// Tell the asset server to watch for asset changes on disk:
10-
.insert_resource(AssetServerSettings {
10+
.insert_setup_resource(AssetServerSettings {
1111
watch_for_changes: true,
1212
..default()
1313
})

examples/ios/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use bevy::{input::touch::TouchPhase, prelude::*, window::WindowMode};
44
#[bevy_main]
55
fn main() {
66
App::new()
7-
.insert_resource(WindowDescriptor {
7+
.insert_setup_resource(WindowSetupDescriptor {
88
resizable: false,
99
mode: WindowMode::BorderlessFullscreen,
1010
..default()

examples/shader/compute_shader_game_of_life.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use bevy::{
1313
renderer::{RenderContext, RenderDevice},
1414
RenderApp, RenderStage,
1515
},
16-
window::WindowDescriptor,
16+
window::WindowSetupDescriptor,
1717
};
1818
use std::borrow::Cow;
1919

@@ -23,7 +23,7 @@ const WORKGROUP_SIZE: u32 = 8;
2323
fn main() {
2424
App::new()
2525
.insert_resource(ClearColor(Color::BLACK))
26-
.insert_resource(WindowDescriptor {
26+
.insert_setup_resource(WindowSetupDescriptor {
2727
// uncomment for unthrottled FPS
2828
// present_mode: bevy::window::PresentMode::AutoNoVsync,
2929
..default()

examples/stress_tests/bevymark.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ struct Bird {
2929

3030
fn main() {
3131
App::new()
32-
.insert_resource(WindowDescriptor {
32+
.insert_setup_resource(WindowSetupDescriptor {
3333
title: "BevyMark".to_string(),
3434
width: 800.,
3535
height: 600.,

examples/stress_tests/many_buttons.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ const FONT_SIZE: f32 = 7.0;
1111
/// This example shows what happens when there is a lot of buttons on screen.
1212
fn main() {
1313
App::new()
14-
.insert_resource(WindowDescriptor {
14+
.insert_setup_resource(WindowSetupDescriptor {
1515
present_mode: PresentMode::Immediate,
1616
..default()
1717
})

examples/stress_tests/many_cubes.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use bevy::{
2121

2222
fn main() {
2323
App::new()
24-
.insert_resource(WindowDescriptor {
24+
.insert_setup_resource(WindowSetupDescriptor {
2525
present_mode: PresentMode::AutoNoVsync,
2626
..default()
2727
})

examples/stress_tests/many_foxes.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ struct Foxes {
1818

1919
fn main() {
2020
App::new()
21-
.insert_resource(WindowDescriptor {
21+
.insert_setup_resource(WindowSetupDescriptor {
2222
title: "🦊🦊🦊 Many Foxes! 🦊🦊🦊".to_string(),
2323
present_mode: PresentMode::AutoNoVsync,
2424
..default()

examples/stress_tests/many_lights.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use rand::{thread_rng, Rng};
1515

1616
fn main() {
1717
App::new()
18-
.insert_resource(WindowDescriptor {
18+
.insert_setup_resource(WindowSetupDescriptor {
1919
width: 1024.0,
2020
height: 768.0,
2121
title: "many_lights".to_string(),

examples/stress_tests/many_sprites.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ struct ColorTint(bool);
2424

2525
fn main() {
2626
App::new()
27-
.insert_resource(WindowDescriptor {
27+
.insert_setup_resource(WindowSetupDescriptor {
2828
present_mode: PresentMode::AutoNoVsync,
2929
..default()
3030
})

examples/tools/scene_viewer.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,11 @@ Controls:
4545
color: Color::WHITE,
4646
brightness: 1.0 / 5.0f32,
4747
})
48-
.insert_resource(AssetServerSettings {
48+
.insert_setup_resource(AssetServerSettings {
4949
asset_folder: std::env::var("CARGO_MANIFEST_DIR").unwrap_or_else(|_| ".".to_string()),
5050
watch_for_changes: true,
5151
})
52-
.insert_resource(WindowDescriptor {
52+
.insert_setup_resource(WindowSetupDescriptor {
5353
title: "bevy scene viewer".to_string(),
5454
..default()
5555
})

0 commit comments

Comments
 (0)