Skip to content

Commit d5610ec

Browse files
committed
add setup resources
1 parent 4aa5605 commit d5610ec

23 files changed

+91
-44
lines changed

crates/bevy_app/src/app.rs

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,19 @@ use bevy_ecs::{
1010
system::Resource,
1111
world::World,
1212
};
13-
use bevy_utils::{tracing::debug, HashMap};
13+
use bevy_utils::{
14+
tracing::{debug, error},
15+
HashMap,
16+
};
1417
use std::fmt::Debug;
1518

1619
#[cfg(feature = "trace")]
1720
use bevy_utils::tracing::info_span;
1821
bevy_utils::define_label!(AppLabel);
1922

23+
/// Wrapper struct for setting setup resources aside
24+
struct Setup<T>(T);
25+
2026
#[allow(clippy::needless_doctest_main)]
2127
/// A container of app logic and data.
2228
///
@@ -57,6 +63,7 @@ pub struct App {
5763
/// A container of [`Stage`]s set to be run in a linear order.
5864
pub schedule: Schedule,
5965
sub_apps: HashMap<Box<dyn AppLabel>, SubApp>,
66+
setup_resources: HashMap<std::any::TypeId, &'static str>,
6067
}
6168

6269
/// Each `SubApp` has its own [`Schedule`] and [`World`], enabling a separation of concerns.
@@ -100,6 +107,7 @@ impl App {
100107
schedule: Default::default(),
101108
runner: Box::new(run_once),
102109
sub_apps: HashMap::default(),
110+
setup_resources: Default::default(),
103111
}
104112
}
105113

@@ -125,6 +133,8 @@ impl App {
125133
#[cfg(feature = "trace")]
126134
let _bevy_app_run_span = info_span!("bevy_app").entered();
127135

136+
self.check_all_setup_resources_consumed();
137+
128138
let mut app = std::mem::replace(self, App::empty());
129139
let runner = std::mem::replace(&mut app.runner, Box::new(run_once));
130140
(runner)(app);
@@ -631,6 +641,44 @@ impl App {
631641
self
632642
}
633643

644+
/// Inserts a setup resource to the current [App] and overwrites any resource
645+
/// previously added of the same type.
646+
///
647+
/// A setup resource is used at startup for plugin initialisation and configuration.
648+
/// All setup resources inserted must be consumed by a plugin and removed before the
649+
/// application is ran.
650+
pub fn insert_setup_resource<T>(&mut self, resource: T) -> &mut Self
651+
where
652+
T: Resource,
653+
{
654+
self.setup_resources
655+
.insert(std::any::TypeId::of::<T>(), std::any::type_name::<T>());
656+
self.insert_resource(Setup(resource));
657+
self
658+
}
659+
660+
/// Consumes a setup resource, and removes it from the current [App] so that a plugin
661+
/// can use it for its setup.
662+
pub fn consume_setup_resource<T>(&mut self) -> Option<T>
663+
where
664+
T: Resource,
665+
{
666+
self.setup_resources.remove(&std::any::TypeId::of::<T>());
667+
self.world
668+
.remove_resource::<Setup<T>>()
669+
.map(|setup| setup.0)
670+
}
671+
672+
/// Check that all setup resources have been consumed, panicking otherwise.
673+
fn check_all_setup_resources_consumed(&self) {
674+
self.setup_resources
675+
.values()
676+
.for_each(|v| error!("Setup resource \"{}\" has not been consumed", v));
677+
if !self.setup_resources.is_empty() {
678+
panic!("Not all setup resources have been consumed. This can happen if you inserted a setup resource after the plugin consuming it.")
679+
}
680+
}
681+
634682
/// Inserts a [`Resource`] to the current [`App`] and overwrites any [`Resource`] previously added of the same type.
635683
///
636684
/// 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
@@ -66,7 +66,7 @@ impl Plugin for DebugAssetServerPlugin {
6666
.thread_name("Debug Asset Server IO Task Pool".to_string())
6767
.build(),
6868
))
69-
.insert_resource(AssetServerSettings {
69+
.insert_setup_resource(AssetServerSettings {
7070
asset_folder: "crates".to_string(),
7171
watch_for_changes: true,
7272
})

crates/bevy_asset/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,8 @@ impl Default for AssetServerSettings {
6666
/// delegate to the default `AssetIo` for the platform.
6767
pub fn create_platform_default_asset_io(app: &mut App) -> Box<dyn AssetIo> {
6868
let settings = app
69-
.world
70-
.get_resource_or_insert_with(AssetServerSettings::default);
69+
.consume_setup_resource::<AssetServerSettings>()
70+
.unwrap_or_default();
7171

7272
#[cfg(all(not(target_arch = "wasm32"), not(target_os = "android")))]
7373
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
@@ -42,9 +42,7 @@ pub enum CoreSystem {
4242
impl Plugin for CorePlugin {
4343
fn build(&self, app: &mut App) {
4444
// Setup the default bevy task pools
45-
app.world
46-
.get_resource::<DefaultTaskPoolOptions>()
47-
.cloned()
45+
app.consume_setup_resource::<DefaultTaskPoolOptions>()
4846
.unwrap_or_default()
4947
.create_default_pools(&mut app.world);
5048

crates/bevy_log/src/lib.rs

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

123123
let default_filter = {
124-
let settings = app.world.get_resource_or_insert_with(LogSettings::default);
124+
let settings = app
125+
.consume_setup_resource::<LogSettings>()
126+
.unwrap_or_default();
125127
format!("{},{}", settings.level, settings.filter)
126128
};
127129
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 windows 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
@@ -16,7 +16,7 @@ pub mod prelude {
1616
#[doc(hidden)]
1717
pub use crate::{
1818
CursorEntered, CursorIcon, CursorLeft, CursorMoved, FileDragAndDrop, ReceivedCharacter,
19-
Window, WindowDescriptor, WindowMoved, Windows,
19+
Window, WindowMoved, WindowSetupDescriptor, Windows,
2020
};
2121
}
2222

@@ -58,9 +58,7 @@ impl Plugin for WindowPlugin {
5858

5959
if self.add_primary_window {
6060
let window_descriptor = app
61-
.world
62-
.get_resource::<WindowDescriptor>()
63-
.map(|descriptor| (*descriptor).clone())
61+
.consume_setup_resource::<WindowSetupDescriptor>()
6462
.unwrap_or_default();
6563
let mut create_window_event = app.world.resource_mut::<Events<CreateWindow>>();
6664
create_window_event.send(CreateWindow {

crates/bevy_window/src/window.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,9 @@ pub struct WindowId(Uuid);
1616
///
1717
/// `Immediate` or `Mailbox` will gracefully fallback to `Fifo` when unavailable.
1818
///
19-
/// The presentation mode may be declared in the [`WindowDescriptor`](WindowDescriptor::present_mode)
20-
/// or updated on a [`Window`](Window::set_present_mode).
19+
/// The presentation mode may be declared in the
20+
/// [`WindowSetupDescriptor`](WindowSetupDescriptor::present_mode) or updated on a
21+
/// [`Window`](Window::set_present_mode).
2122
#[repr(C)]
2223
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
2324
#[doc(alias = "vsync")]
@@ -238,7 +239,7 @@ pub enum WindowMode {
238239
impl Window {
239240
pub fn new(
240241
id: WindowId,
241-
window_descriptor: &WindowDescriptor,
242+
window_descriptor: &WindowSetupDescriptor,
242243
physical_width: u32,
243244
physical_height: u32,
244245
scale_factor: f64,
@@ -587,7 +588,7 @@ impl Window {
587588
}
588589

589590
#[derive(Debug, Clone)]
590-
pub struct WindowDescriptor {
591+
pub struct WindowSetupDescriptor {
591592
pub width: f32,
592593
pub height: f32,
593594
pub position: Option<Vec2>,
@@ -613,9 +614,9 @@ pub struct WindowDescriptor {
613614
pub canvas: Option<String>,
614615
}
615616

616-
impl Default for WindowDescriptor {
617+
impl Default for WindowSetupDescriptor {
617618
fn default() -> Self {
618-
WindowDescriptor {
619+
WindowSetupDescriptor {
619620
title: "app".to_string(),
620621
width: 1280.,
621622
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::IVec2;
22
use bevy_utils::HashMap;
3-
use bevy_window::{Window, WindowDescriptor, WindowId, WindowMode};
3+
use bevy_window::{Window, WindowId, WindowMode, WindowSetupDescriptor};
44
use raw_window_handle::HasRawWindowHandle;
55
use winit::dpi::LogicalSize;
66

@@ -20,7 +20,7 @@ impl WinitWindows {
2020
&mut self,
2121
event_loop: &winit::event_loop::EventLoopWindowTarget<()>,
2222
window_id: WindowId,
23-
window_descriptor: &WindowDescriptor,
23+
window_descriptor: &WindowSetupDescriptor,
2424
) -> Window {
2525
let mut winit_window_builder = winit::window::WindowBuilder::new();
2626

@@ -41,7 +41,7 @@ impl WinitWindows {
4141
)),
4242
)),
4343
_ => {
44-
let WindowDescriptor {
44+
let WindowSetupDescriptor {
4545
width,
4646
height,
4747
position,

examples/app/logs.rs

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

2525
// by default, trace and debug logs are ignored because they are "noisy"
26-
// you can control what level is logged by adding the LogSettings resource
26+
// you can control what level is logged by adding the LogSettings setup resource
2727
// alternatively you can set the log level via the RUST_LOG=LEVEL environment variable
2828
// ex: RUST_LOG=trace, RUST_LOG=info,bevy_ecs=warn
2929
// 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
@@ -4,7 +4,7 @@ use bevy::prelude::*;
44
/// certain number of threads).
55
fn main() {
66
App::new()
7-
.insert_resource(DefaultTaskPoolOptions::with_num_threads(4))
7+
.insert_setup_resource(DefaultTaskPoolOptions::with_num_threads(4))
88
.add_plugins(DefaultPlugins)
99
.run();
1010
}

examples/asset/hot_asset_reloading.rs

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

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
@@ -8,7 +8,7 @@ use bevy::{
88
renderer::{RenderContext, RenderDevice},
99
RenderApp, RenderStage,
1010
},
11-
window::WindowDescriptor,
11+
window::WindowSetupDescriptor,
1212
};
1313
use std::borrow::Cow;
1414

@@ -18,7 +18,7 @@ const WORKGROUP_SIZE: u32 = 8;
1818
fn main() {
1919
App::new()
2020
.insert_resource(ClearColor(Color::BLACK))
21-
.insert_resource(WindowDescriptor {
21+
.insert_setup_resource(WindowSetupDescriptor {
2222
// uncomment for unthrottled FPS
2323
// vsync: false,
2424
..default()

examples/stress_tests/bevymark.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ struct Bird {
2727
/// Usage: spawn more entities by clicking on the screen.
2828
fn main() {
2929
App::new()
30-
.insert_resource(WindowDescriptor {
30+
.insert_setup_resource(WindowSetupDescriptor {
3131
title: "BevyMark".to_string(),
3232
width: 800.,
3333
height: 600.,

examples/stress_tests/many_lights.rs

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

1010
fn main() {
1111
App::new()
12-
.insert_resource(WindowDescriptor {
12+
.insert_setup_resource(WindowSetupDescriptor {
1313
width: 1024.0,
1414
height: 768.0,
1515
title: "many_lights".to_string(),

examples/tools/scene_viewer.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,11 @@ Controls:
4040
color: Color::WHITE,
4141
brightness: 1.0 / 5.0f32,
4242
})
43-
.insert_resource(AssetServerSettings {
43+
.insert_setup_resource(AssetServerSettings {
4444
asset_folder: std::env::var("CARGO_MANIFEST_DIR").unwrap_or_else(|_| ".".to_string()),
4545
watch_for_changes: true,
4646
})
47-
.insert_resource(WindowDescriptor {
47+
.insert_setup_resource(WindowSetupDescriptor {
4848
title: "bevy scene viewer".to_string(),
4949
..default()
5050
})

examples/ui/text_debug.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use bevy::{
77
/// This example is for debugging text layout
88
fn main() {
99
App::new()
10-
.insert_resource(WindowDescriptor {
10+
.insert_setup_resource(WindowSetupDescriptor {
1111
present_mode: PresentMode::Immediate,
1212
..default()
1313
})

examples/window/low_power.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ fn main() {
2424
..default()
2525
})
2626
// Turn off vsync to maximize CPU/GPU usage
27-
.insert_resource(WindowDescriptor {
27+
.insert_setup_resource(WindowSetupDescriptor {
2828
present_mode: PresentMode::Immediate,
2929
..default()
3030
})

examples/window/multiple_windows.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ fn create_new_window(mut create_window_events: EventWriter<CreateWindow>, mut co
8888
// sends out a "CreateWindow" event, which will be received by the windowing backend
8989
create_window_events.send(CreateWindow {
9090
id: window_id,
91-
descriptor: WindowDescriptor {
91+
descriptor: WindowSetupDescriptor {
9292
width: 800.,
9393
height: 600.,
9494
present_mode: PresentMode::Immediate,

examples/window/scale_factor_override.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use bevy::prelude::*;
33
/// This example illustrates how to customize the default window settings
44
fn main() {
55
App::new()
6-
.insert_resource(WindowDescriptor {
6+
.insert_setup_resource(WindowSetupDescriptor {
77
width: 500.,
88
height: 300.,
99
..default()

0 commit comments

Comments
 (0)