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 4aa5605 commit d5610ec
Show file tree
Hide file tree
Showing 23 changed files with 91 additions and 44 deletions.
50 changes: 49 additions & 1 deletion crates/bevy_app/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,19 @@ 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")]
use bevy_utils::tracing::info_span;
bevy_utils::define_label!(AppLabel);

/// Wrapper struct for setting setup resources aside
struct Setup<T>(T);

#[allow(clippy::needless_doctest_main)]
/// A container of app logic and data.
///
Expand Down Expand Up @@ -57,6 +63,7 @@ pub struct App {
/// A container of [`Stage`]s set to be run in a linear order.
pub schedule: Schedule,
sub_apps: HashMap<Box<dyn AppLabel>, 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 @@ -100,6 +107,7 @@ impl App {
schedule: Default::default(),
runner: Box::new(run_once),
sub_apps: HashMap::default(),
setup_resources: Default::default(),
}
}

Expand All @@ -125,6 +133,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 @@ -631,6 +641,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 @@ -66,7 +66,7 @@ impl Plugin for DebugAssetServerPlugin {
.thread_name("Debug Asset Server IO Task Pool".to_string())
.build(),
))
.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 @@ -66,8 +66,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 @@ -42,9 +42,7 @@ pub enum CoreSystem {
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(&mut app.world);

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 @@ -45,15 +45,15 @@ 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_internal::DefaultPlugins;
/// # use bevy_app::App;
/// # 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 @@ -121,7 +121,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 windows 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 @@ -16,7 +16,7 @@ pub mod prelude {
#[doc(hidden)]
pub use crate::{
CursorEntered, CursorIcon, CursorLeft, CursorMoved, FileDragAndDrop, ReceivedCharacter,
Window, WindowDescriptor, WindowMoved, Windows,
Window, WindowMoved, WindowSetupDescriptor, Windows,
};
}

Expand Down Expand Up @@ -58,9 +58,7 @@ impl Plugin for WindowPlugin {

if self.add_primary_window {
let window_descriptor = app
.world
.get_resource::<WindowDescriptor>()
.map(|descriptor| (*descriptor).clone())
.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
13 changes: 7 additions & 6 deletions crates/bevy_window/src/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,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 @@ -238,7 +239,7 @@ pub enum WindowMode {
impl 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 @@ -587,7 +588,7 @@ impl Window {
}

#[derive(Debug, Clone)]
pub struct WindowDescriptor {
pub struct WindowSetupDescriptor {
pub width: f32,
pub height: f32,
pub position: Option<Vec2>,
Expand All @@ -613,9 +614,9 @@ pub struct WindowDescriptor {
pub canvas: Option<String>,
}

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::IVec2;
use bevy_utils::HashMap;
use bevy_window::{Window, WindowDescriptor, WindowId, WindowMode};
use bevy_window::{Window, WindowId, WindowMode, WindowSetupDescriptor};
use raw_window_handle::HasRawWindowHandle;
use winit::dpi::LogicalSize;

Expand All @@ -20,7 +20,7 @@ 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();

Expand All @@ -41,7 +41,7 @@ impl WinitWindows {
)),
)),
_ => {
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 @@ -4,7 +4,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 @@ -23,7 +23,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 @@ -4,7 +4,7 @@ use bevy::prelude::*;
/// certain number of threads).
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 @@ -6,7 +6,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 @@ -8,7 +8,7 @@ use bevy::{
renderer::{RenderContext, RenderDevice},
RenderApp, RenderStage,
},
window::WindowDescriptor,
window::WindowSetupDescriptor,
};
use std::borrow::Cow;

Expand All @@ -18,7 +18,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
// vsync: false,
..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 @@ -27,7 +27,7 @@ struct Bird {
/// Usage: spawn more entities by clicking on the screen.
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_lights.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,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
4 changes: 2 additions & 2 deletions examples/tools/scene_viewer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,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
2 changes: 1 addition & 1 deletion examples/ui/text_debug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use bevy::{
/// This example is for debugging text layout
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/window/low_power.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ fn main() {
..default()
})
// Turn off vsync to maximize CPU/GPU usage
.insert_resource(WindowDescriptor {
.insert_setup_resource(WindowSetupDescriptor {
present_mode: PresentMode::Immediate,
..default()
})
Expand Down
2 changes: 1 addition & 1 deletion examples/window/multiple_windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ fn create_new_window(mut create_window_events: EventWriter<CreateWindow>, mut co
// sends out a "CreateWindow" event, which will be received by the windowing backend
create_window_events.send(CreateWindow {
id: window_id,
descriptor: WindowDescriptor {
descriptor: WindowSetupDescriptor {
width: 800.,
height: 600.,
present_mode: PresentMode::Immediate,
Expand Down
2 changes: 1 addition & 1 deletion examples/window/scale_factor_override.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use bevy::prelude::*;
/// This example illustrates how to customize the default window settings
fn main() {
App::new()
.insert_resource(WindowDescriptor {
.insert_setup_resource(WindowSetupDescriptor {
width: 500.,
height: 300.,
..default()
Expand Down
Loading

0 comments on commit d5610ec

Please sign in to comment.