Skip to content

Commit

Permalink
add setup resources
Browse files Browse the repository at this point in the history
  • Loading branch information
mockersf committed Sep 6, 2022
1 parent 1914696 commit b151ec8
Show file tree
Hide file tree
Showing 29 changed files with 100 additions and 52 deletions.
51 changes: 50 additions & 1 deletion crates/bevy_app/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ use bevy_ecs::{
system::Resource,
world::World,
};
use bevy_utils::{tracing::debug, HashMap};
use bevy_utils::{
tracing::{debug, error},
HashMap,
};
use std::fmt::Debug;

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

/// Wrapper struct for setting setup resources aside
#[derive(Resource)]
struct Setup<T>(T);

#[allow(clippy::needless_doctest_main)]
/// A container of app logic and data.
///
Expand Down Expand Up @@ -68,6 +75,7 @@ pub struct App {
/// A container of [`Stage`]s set to be run in a linear order.
pub schedule: Schedule,
sub_apps: HashMap<AppLabelId, SubApp>,
setup_resources: HashMap<std::any::TypeId, &'static str>,
}

/// Each `SubApp` has its own [`Schedule`] and [`World`], enabling a separation of concerns.
Expand Down Expand Up @@ -111,6 +119,7 @@ impl App {
schedule: Default::default(),
runner: Box::new(run_once),
sub_apps: HashMap::default(),
setup_resources: Default::default(),
}
}

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

self.check_all_setup_resources_consumed();

let mut app = std::mem::replace(self, App::empty());
let runner = std::mem::replace(&mut app.runner, Box::new(run_once));
(runner)(app);
Expand Down Expand Up @@ -654,6 +665,44 @@ impl App {
self
}

/// Inserts a setup resource to the current [App] and overwrites any resource
/// previously added of the same type.
///
/// A setup resource is used at startup for plugin initialisation and configuration.
/// All setup resources inserted must be consumed by a plugin and removed before the
/// application is ran.
pub fn insert_setup_resource<T>(&mut self, resource: T) -> &mut Self
where
T: Resource,
{
self.setup_resources
.insert(std::any::TypeId::of::<T>(), std::any::type_name::<T>());
self.insert_resource(Setup(resource));
self
}

/// Consumes a setup resource, and removes it from the current [App] so that a plugin
/// can use it for its setup.
pub fn consume_setup_resource<T>(&mut self) -> Option<T>
where
T: Resource,
{
self.setup_resources.remove(&std::any::TypeId::of::<T>());
self.world
.remove_resource::<Setup<T>>()
.map(|setup| setup.0)
}

/// Check that all setup resources have been consumed, panicking otherwise.
fn check_all_setup_resources_consumed(&self) {
self.setup_resources
.values()
.for_each(|v| error!("Setup resource \"{}\" has not been consumed", v));
if !self.setup_resources.is_empty() {
panic!("Not all setup resources have been consumed. This can happen if you inserted a setup resource after the plugin consuming it.")
}
}

/// Inserts a [`Resource`] to the current [`App`] and overwrites any [`Resource`] previously added of the same type.
///
/// A [`Resource`] in Bevy represents globally unique data. [`Resource`]s must be added to Bevy apps
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_asset/src/debug_asset_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ impl Plugin for DebugAssetServerPlugin {
});
let mut debug_asset_app = App::new();
debug_asset_app
.insert_resource(AssetServerSettings {
.insert_setup_resource(AssetServerSettings {
asset_folder: "crates".to_string(),
watch_for_changes: true,
})
Expand Down
4 changes: 2 additions & 2 deletions crates/bevy_asset/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,8 @@ impl Default for AssetServerSettings {
/// delegate to the default `AssetIo` for the platform.
pub fn create_platform_default_asset_io(app: &mut App) -> Box<dyn AssetIo> {
let settings = app
.world
.get_resource_or_insert_with(AssetServerSettings::default);
.consume_setup_resource::<AssetServerSettings>()
.unwrap_or_default();

#[cfg(all(not(target_arch = "wasm32"), not(target_os = "android")))]
let source = FileAssetIo::new(&settings.asset_folder, settings.watch_for_changes);
Expand Down
4 changes: 1 addition & 3 deletions crates/bevy_core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,7 @@ pub struct CorePlugin;
impl Plugin for CorePlugin {
fn build(&self, app: &mut App) {
// Setup the default bevy task pools
app.world
.get_resource::<DefaultTaskPoolOptions>()
.cloned()
app.consume_setup_resource::<DefaultTaskPoolOptions>()
.unwrap_or_default()
.create_default_pools();

Expand Down
8 changes: 5 additions & 3 deletions crates/bevy_log/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,14 @@ use tracing_subscriber::{prelude::*, registry::Registry, EnvFilter};
/// * Using [`tracing-wasm`](https://crates.io/crates/tracing-wasm) in WASM, logging
/// to the browser console.
///
/// You can configure this plugin using the resource [`LogSettings`].
/// You can configure this plugin using the setup resource [`LogSettings`].
/// ```no_run
/// # use bevy_app::{App, NoopPluginGroup as DefaultPlugins};
/// # use bevy_log::LogSettings;
/// # use bevy_utils::tracing::Level;
/// fn main() {
/// App::new()
/// .insert_resource(LogSettings {
/// .insert_setup_resource(LogSettings {
/// level: Level::DEBUG,
/// filter: "wgpu=error,bevy_render=info,bevy_ecs=trace".to_string(),
/// })
Expand Down Expand Up @@ -122,7 +122,9 @@ impl Plugin for LogPlugin {
}

let default_filter = {
let settings = app.world.get_resource_or_insert_with(LogSettings::default);
let settings = app
.consume_setup_resource::<LogSettings>()
.unwrap_or_default();
format!("{},{}", settings.level, settings.filter)
};
LogTracer::init().unwrap();
Expand Down
4 changes: 2 additions & 2 deletions crates/bevy_window/src/event.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::path::PathBuf;

use super::{WindowDescriptor, WindowId};
use super::{WindowId, WindowSetupDescriptor};
use bevy_math::{IVec2, Vec2};

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

/// An event that indicates the window should redraw, even if its control flow is set to `Wait` and
Expand Down
6 changes: 2 additions & 4 deletions crates/bevy_window/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ pub mod prelude {
#[doc(hidden)]
pub use crate::{
CursorEntered, CursorIcon, CursorLeft, CursorMoved, FileDragAndDrop, MonitorSelection,
ReceivedCharacter, Window, WindowDescriptor, WindowMode, WindowMoved, WindowPosition,
ReceivedCharacter, Window, WindowMode, WindowMoved, WindowPosition, WindowSetupDescriptor,
Windows,
};
}
Expand Down Expand Up @@ -99,9 +99,7 @@ impl Plugin for WindowPlugin {

if settings.add_primary_window {
let window_descriptor = app
.world
.get_resource::<WindowDescriptor>()
.cloned()
.consume_setup_resource::<WindowSetupDescriptor>()
.unwrap_or_default();
let mut create_window_event = app.world.resource_mut::<Events<CreateWindow>>();
create_window_event.send(CreateWindow {
Expand Down
17 changes: 9 additions & 8 deletions crates/bevy_window/src/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ pub struct WindowId(Uuid);
///
/// `Immediate` or `Mailbox` will gracefully fallback to `Fifo` when unavailable.
///
/// The presentation mode may be declared in the [`WindowDescriptor`](WindowDescriptor::present_mode)
/// or updated on a [`Window`](Window::set_present_mode).
/// The presentation mode may be declared in the
/// [`WindowSetupDescriptor`](WindowSetupDescriptor::present_mode) or updated on a
/// [`Window`](Window::set_present_mode).
#[repr(C)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[doc(alias = "vsync")]
Expand Down Expand Up @@ -305,7 +306,7 @@ impl Window {
/// Creates a new [`Window`].
pub fn new(
id: WindowId,
window_descriptor: &WindowDescriptor,
window_descriptor: &WindowSetupDescriptor,
physical_width: u32,
physical_height: u32,
scale_factor: f64,
Expand Down Expand Up @@ -751,13 +752,13 @@ pub enum WindowPosition {
Automatic,
/// Center the window on the monitor.
///
/// The monitor to center the window on can be selected with the `monitor` field in `WindowDescriptor`.
/// The monitor to center the window on can be selected with the `monitor` field in `WindowSetupDescriptor`.
Centered,
/// The window's top-left corner will be placed at the specified position in pixels.
///
/// (0,0) represents top-left corner of the monitor.
///
/// The monitor to position the window on can be selected with the `monitor` field in `WindowDescriptor`.
/// The monitor to position the window on can be selected with the `monitor` field in `WindowSetupDescriptor`.
At(Vec2),
}

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

impl Default for WindowDescriptor {
impl Default for WindowSetupDescriptor {
fn default() -> Self {
WindowDescriptor {
WindowSetupDescriptor {
title: "app".to_string(),
width: 1280.,
height: 720.,
Expand Down
6 changes: 3 additions & 3 deletions crates/bevy_winit/src/winit_windows.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use bevy_math::{DVec2, IVec2};
use bevy_utils::HashMap;
use bevy_window::{MonitorSelection, Window, WindowDescriptor, WindowId, WindowMode};
use bevy_window::{MonitorSelection, Window, WindowId, WindowMode, WindowSetupDescriptor};
use raw_window_handle::HasRawWindowHandle;
use winit::{
dpi::{LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize},
Expand All @@ -23,11 +23,11 @@ impl WinitWindows {
&mut self,
event_loop: &winit::event_loop::EventLoopWindowTarget<()>,
window_id: WindowId,
window_descriptor: &WindowDescriptor,
window_descriptor: &WindowSetupDescriptor,
) -> Window {
let mut winit_window_builder = winit::window::WindowBuilder::new();

let &WindowDescriptor {
let &WindowSetupDescriptor {
width,
height,
position,
Expand Down
4 changes: 2 additions & 2 deletions examples/app/logs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use bevy::prelude::*;
fn main() {
App::new()
// Uncomment this to override the default log settings:
// .insert_resource(bevy::log::LogSettings {
// .insert_setup_resource(bevy::log::LogSettings {
// level: bevy::log::Level::TRACE,
// filter: "wgpu=warn,bevy_ecs=info".to_string(),
// })
Expand All @@ -24,7 +24,7 @@ fn log_system() {
error!("something failed");

// by default, trace and debug logs are ignored because they are "noisy"
// you can control what level is logged by adding the LogSettings resource
// you can control what level is logged by adding the LogSettings setup resource
// alternatively you can set the log level via the RUST_LOG=LEVEL environment variable
// ex: RUST_LOG=trace, RUST_LOG=info,bevy_ecs=warn
// the format used here is super flexible. check out this documentation for more info:
Expand Down
2 changes: 1 addition & 1 deletion examples/app/thread_pool_resources.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use bevy::prelude::*;

fn main() {
App::new()
.insert_resource(DefaultTaskPoolOptions::with_num_threads(4))
.insert_setup_resource(DefaultTaskPoolOptions::with_num_threads(4))
.add_plugins(DefaultPlugins)
.run();
}
2 changes: 1 addition & 1 deletion examples/asset/hot_asset_reloading.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use bevy::{asset::AssetServerSettings, prelude::*};
fn main() {
App::new()
// Tell the asset server to watch for asset changes on disk:
.insert_resource(AssetServerSettings {
.insert_setup_resource(AssetServerSettings {
watch_for_changes: true,
..default()
})
Expand Down
2 changes: 1 addition & 1 deletion examples/ios/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use bevy::{input::touch::TouchPhase, prelude::*, window::WindowMode};
#[bevy_main]
fn main() {
App::new()
.insert_resource(WindowDescriptor {
.insert_setup_resource(WindowSetupDescriptor {
resizable: false,
mode: WindowMode::BorderlessFullscreen,
..default()
Expand Down
4 changes: 2 additions & 2 deletions examples/shader/compute_shader_game_of_life.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use bevy::{
renderer::{RenderContext, RenderDevice},
RenderApp, RenderStage,
},
window::WindowDescriptor,
window::WindowSetupDescriptor,
};
use std::borrow::Cow;

Expand All @@ -23,7 +23,7 @@ const WORKGROUP_SIZE: u32 = 8;
fn main() {
App::new()
.insert_resource(ClearColor(Color::BLACK))
.insert_resource(WindowDescriptor {
.insert_setup_resource(WindowSetupDescriptor {
// uncomment for unthrottled FPS
// present_mode: bevy::window::PresentMode::AutoNoVsync,
..default()
Expand Down
2 changes: 1 addition & 1 deletion examples/stress_tests/bevymark.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ struct Bird {

fn main() {
App::new()
.insert_resource(WindowDescriptor {
.insert_setup_resource(WindowSetupDescriptor {
title: "BevyMark".to_string(),
width: 800.,
height: 600.,
Expand Down
2 changes: 1 addition & 1 deletion examples/stress_tests/many_buttons.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const FONT_SIZE: f32 = 7.0;
/// This example shows what happens when there is a lot of buttons on screen.
fn main() {
App::new()
.insert_resource(WindowDescriptor {
.insert_setup_resource(WindowSetupDescriptor {
present_mode: PresentMode::Immediate,
..default()
})
Expand Down
2 changes: 1 addition & 1 deletion examples/stress_tests/many_cubes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use bevy::{

fn main() {
App::new()
.insert_resource(WindowDescriptor {
.insert_setup_resource(WindowSetupDescriptor {
present_mode: PresentMode::AutoNoVsync,
..default()
})
Expand Down
2 changes: 1 addition & 1 deletion examples/stress_tests/many_foxes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ struct Foxes {

fn main() {
App::new()
.insert_resource(WindowDescriptor {
.insert_setup_resource(WindowSetupDescriptor {
title: "🦊🦊🦊 Many Foxes! 🦊🦊🦊".to_string(),
present_mode: PresentMode::AutoNoVsync,
..default()
Expand Down
2 changes: 1 addition & 1 deletion examples/stress_tests/many_lights.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use rand::{thread_rng, Rng};

fn main() {
App::new()
.insert_resource(WindowDescriptor {
.insert_setup_resource(WindowSetupDescriptor {
width: 1024.0,
height: 768.0,
title: "many_lights".to_string(),
Expand Down
2 changes: 1 addition & 1 deletion examples/stress_tests/many_sprites.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ struct ColorTint(bool);

fn main() {
App::new()
.insert_resource(WindowDescriptor {
.insert_setup_resource(WindowSetupDescriptor {
present_mode: PresentMode::AutoNoVsync,
..default()
})
Expand Down
4 changes: 2 additions & 2 deletions examples/tools/scene_viewer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,11 @@ Controls:
color: Color::WHITE,
brightness: 1.0 / 5.0f32,
})
.insert_resource(AssetServerSettings {
.insert_setup_resource(AssetServerSettings {
asset_folder: std::env::var("CARGO_MANIFEST_DIR").unwrap_or_else(|_| ".".to_string()),
watch_for_changes: true,
})
.insert_resource(WindowDescriptor {
.insert_setup_resource(WindowSetupDescriptor {
title: "bevy scene viewer".to_string(),
..default()
})
Expand Down
Loading

0 comments on commit b151ec8

Please sign in to comment.