diff --git a/crates/bevy_app/src/app.rs b/crates/bevy_app/src/app.rs index 25c2271365544..760347372184d 100644 --- a/crates/bevy_app/src/app.rs +++ b/crates/bevy_app/src/app.rs @@ -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")] @@ -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); + #[allow(clippy::needless_doctest_main)] /// A container of app logic and data. /// @@ -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, + setup_resources: HashMap, } impl Debug for App { @@ -131,6 +139,7 @@ impl App { schedule: Default::default(), runner: Box::new(run_once), sub_apps: HashMap::default(), + setup_resources: Default::default(), } } @@ -156,6 +165,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); @@ -674,6 +685,52 @@ 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(&mut self, resource: R) -> &mut Self + where + R: Resource, + { + if R::IS_SETUP_RESOURCE { + self.setup_resources + .insert(std::any::TypeId::of::(), std::any::type_name::()); + self.insert_resource(Setup(resource)); + } else { + // Using `eprintln` here as this is supposed to be called before logs are set up + eprintln!( + "Resource {} is not a setup resource", + std::any::type_name::() + ); + } + 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(&mut self) -> Option + where + R: Resource, + { + self.setup_resources.remove(&std::any::TypeId::of::()); + self.world + .remove_resource::>() + .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 diff --git a/crates/bevy_asset/src/debug_asset_server.rs b/crates/bevy_asset/src/debug_asset_server.rs index fafc3be759164..9d9cf092b8d37 100644 --- a/crates/bevy_asset/src/debug_asset_server.rs +++ b/crates/bevy_asset/src/debug_asset_server.rs @@ -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, }) diff --git a/crates/bevy_asset/src/lib.rs b/crates/bevy_asset/src/lib.rs index 24e9d975b1193..b2be5d987e9af 100644 --- a/crates/bevy_asset/src/lib.rs +++ b/crates/bevy_asset/src/lib.rs @@ -70,6 +70,7 @@ pub struct AssetPlugin; /// /// This resource must be added before the [`AssetPlugin`] or `DefaultPlugins` to take effect. #[derive(Resource)] +#[resource(setup)] pub struct AssetServerSettings { /// The base folder where assets are loaded from, relative to the executable. pub asset_folder: String, @@ -93,8 +94,8 @@ impl Default for AssetServerSettings { /// delegate to the default `AssetIo` for the platform. pub fn create_platform_default_asset_io(app: &mut App) -> Box { let settings = app - .world - .get_resource_or_insert_with(AssetServerSettings::default); + .consume_setup_resource::() + .unwrap_or_default(); #[cfg(all(not(target_arch = "wasm32"), not(target_os = "android")))] let source = FileAssetIo::new(&settings.asset_folder, settings.watch_for_changes); diff --git a/crates/bevy_core/src/lib.rs b/crates/bevy_core/src/lib.rs index 58ece9d81f111..c24bb43586bec 100644 --- a/crates/bevy_core/src/lib.rs +++ b/crates/bevy_core/src/lib.rs @@ -29,9 +29,7 @@ pub struct CorePlugin; impl Plugin for CorePlugin { fn build(&self, app: &mut App) { // Setup the default bevy task pools - app.world - .get_resource::() - .cloned() + app.consume_setup_resource::() .unwrap_or_default() .create_default_pools(); diff --git a/crates/bevy_core/src/task_pool_options.rs b/crates/bevy_core/src/task_pool_options.rs index 43779a072c0a8..74c20c26c8cd8 100644 --- a/crates/bevy_core/src/task_pool_options.rs +++ b/crates/bevy_core/src/task_pool_options.rs @@ -35,6 +35,7 @@ impl TaskPoolThreadAssignmentPolicy { /// insert the default task pools into the resource map manually. If the pools are already inserted, /// this helper will do nothing. #[derive(Clone, Resource)] +#[resource(setup)] pub struct DefaultTaskPoolOptions { /// If the number of physical cores is less than min_total_threads, force using /// min_total_threads diff --git a/crates/bevy_ecs/macros/src/component.rs b/crates/bevy_ecs/macros/src/component.rs index a75c4a92b3fe9..440fe31468df7 100644 --- a/crates/bevy_ecs/macros/src/component.rs +++ b/crates/bevy_ecs/macros/src/component.rs @@ -4,24 +4,6 @@ use proc_macro2::{Span, TokenStream as TokenStream2}; use quote::{quote, ToTokens}; use syn::{parse_macro_input, parse_quote, DeriveInput, Error, Ident, Path, Result}; -pub fn derive_resource(input: TokenStream) -> TokenStream { - let mut ast = parse_macro_input!(input as DeriveInput); - let bevy_ecs_path: Path = crate::bevy_ecs_path(); - - ast.generics - .make_where_clause() - .predicates - .push(parse_quote! { Self: Send + Sync + 'static }); - - let struct_name = &ast.ident; - let (impl_generics, type_generics, where_clause) = &ast.generics.split_for_impl(); - - TokenStream::from(quote! { - impl #impl_generics #bevy_ecs_path::system::Resource for #struct_name #type_generics #where_clause { - } - }) -} - pub fn derive_component(input: TokenStream) -> TokenStream { let mut ast = parse_macro_input!(input as DeriveInput); let bevy_ecs_path: Path = crate::bevy_ecs_path(); diff --git a/crates/bevy_ecs/macros/src/lib.rs b/crates/bevy_ecs/macros/src/lib.rs index ed4391d7e0041..0774add8fe32b 100644 --- a/crates/bevy_ecs/macros/src/lib.rs +++ b/crates/bevy_ecs/macros/src/lib.rs @@ -2,6 +2,7 @@ extern crate proc_macro; mod component; mod fetch; +mod resource; use crate::fetch::derive_world_query_impl; use bevy_macro_utils::{derive_label, get_named_struct_fields, BevyManifest}; @@ -454,9 +455,9 @@ pub(crate) fn bevy_ecs_path() -> syn::Path { BevyManifest::default().get_path("bevy_ecs") } -#[proc_macro_derive(Resource)] +#[proc_macro_derive(Resource, attributes(resource))] pub fn derive_resource(input: TokenStream) -> TokenStream { - component::derive_resource(input) + resource::derive_resource(input) } #[proc_macro_derive(Component, attributes(component))] diff --git a/crates/bevy_ecs/macros/src/resource.rs b/crates/bevy_ecs/macros/src/resource.rs new file mode 100644 index 0000000000000..794c2f7bcfe5e --- /dev/null +++ b/crates/bevy_ecs/macros/src/resource.rs @@ -0,0 +1,73 @@ +use bevy_macro_utils::Symbol; +use proc_macro::TokenStream; +use proc_macro2::Span; +use quote::{quote, ToTokens}; +use syn::{parse_macro_input, parse_quote, DeriveInput, Error, Ident, Path, Result}; + +pub fn derive_resource(input: TokenStream) -> TokenStream { + let mut ast = parse_macro_input!(input as DeriveInput); + let bevy_ecs_path: Path = crate::bevy_ecs_path(); + + let attrs = match parse_resource_attr(&ast) { + Ok(attrs) => attrs, + Err(e) => return e.into_compile_error().into(), + }; + + let is_setup_resource = Ident::new(&format!("{}", attrs.is_setup_resource), Span::call_site()); + + ast.generics + .make_where_clause() + .predicates + .push(parse_quote! { Self: Send + Sync + 'static }); + + let struct_name = &ast.ident; + let (impl_generics, type_generics, where_clause) = &ast.generics.split_for_impl(); + + TokenStream::from(quote! { + impl #impl_generics #bevy_ecs_path::system::Resource for #struct_name #type_generics #where_clause { + const IS_SETUP_RESOURCE: bool = #is_setup_resource; + } + }) +} + +pub const RESOURCE: Symbol = Symbol("resource"); +pub const SETUP_RESOURCE: Symbol = Symbol("setup"); + +struct Attrs { + is_setup_resource: bool, +} + +fn parse_resource_attr(ast: &DeriveInput) -> Result { + let meta_items = bevy_macro_utils::parse_attrs(ast, RESOURCE)?; + + let mut attrs = Attrs { + is_setup_resource: false, + }; + + for meta in meta_items { + use syn::{ + Meta::Path, + NestedMeta::{Lit, Meta}, + }; + match meta { + Meta(Path(m)) if m == SETUP_RESOURCE => attrs.is_setup_resource = true, + Meta(meta_item) => { + return Err(Error::new_spanned( + meta_item.path(), + format!( + "unknown component attribute `{}`", + meta_item.path().into_token_stream() + ), + )); + } + Lit(lit) => { + return Err(Error::new_spanned( + lit, + "unexpected literal in component attribute", + )) + } + } + } + + Ok(attrs) +} diff --git a/crates/bevy_ecs/src/system/commands/mod.rs b/crates/bevy_ecs/src/system/commands/mod.rs index 9da52f1eb32be..baa70e9d865eb 100644 --- a/crates/bevy_ecs/src/system/commands/mod.rs +++ b/crates/bevy_ecs/src/system/commands/mod.rs @@ -439,9 +439,13 @@ impl<'w, 's> Commands<'w, 's> { /// # bevy_ecs::system::assert_is_system(initialise_scoreboard); /// ``` pub fn init_resource(&mut self) { - self.queue.push(InitResource:: { - _phantom: PhantomData::::default(), - }); + if !R::IS_SETUP_RESOURCE { + self.queue.push(InitResource:: { + _phantom: PhantomData::::default(), + }); + } else { + error!("Initializing resource {} during execution has no effect. It should be added during setup using `insert_setup_resource`.", std::any::type_name::()); + } } /// Pushes a [`Command`] to the queue for inserting a [`Resource`] in the [`World`] with a specific value. @@ -470,7 +474,11 @@ impl<'w, 's> Commands<'w, 's> { /// # bevy_ecs::system::assert_is_system(system); /// ``` pub fn insert_resource(&mut self, resource: R) { - self.queue.push(InsertResource { resource }); + if !R::IS_SETUP_RESOURCE { + self.queue.push(InsertResource { resource }); + } else { + error!("Inserting resource {} during execution has no effect. It should be added during setup using `insert_setup_resource`.", std::any::type_name::()); + } } /// Pushes a [`Command`] to the queue for removing a [`Resource`] from the [`World`]. diff --git a/crates/bevy_ecs/src/system/system_param.rs b/crates/bevy_ecs/src/system/system_param.rs index 6f57b2dd0e4a6..29119282afced 100644 --- a/crates/bevy_ecs/src/system/system_param.rs +++ b/crates/bevy_ecs/src/system/system_param.rs @@ -258,7 +258,9 @@ impl_param_set!(); /// # schedule.add_system_to_stage("update", write_resource_system.after("first")); /// # schedule.run_once(&mut world); /// ``` -pub trait Resource: Send + Sync + 'static {} +pub trait Resource: Send + Sync + 'static { + const IS_SETUP_RESOURCE: bool = false; +} /// Shared borrow of a [`Resource`]. /// diff --git a/crates/bevy_ecs/src/world/mod.rs b/crates/bevy_ecs/src/world/mod.rs index 3e45e8c100fea..8e4e6bdc9843d 100644 --- a/crates/bevy_ecs/src/world/mod.rs +++ b/crates/bevy_ecs/src/world/mod.rs @@ -21,7 +21,7 @@ use crate::{ system::Resource, }; use bevy_ptr::{OwningPtr, Ptr, UnsafeCellDeref}; -use bevy_utils::tracing::debug; +use bevy_utils::tracing::{debug, error}; use std::{ any::TypeId, fmt, @@ -734,13 +734,20 @@ impl World { /// you will overwrite any existing data. #[inline] pub fn insert_resource(&mut self, value: R) { - let component_id = self.components.init_resource::(); - OwningPtr::make(value, |ptr| { - // SAFETY: component_id was just initialized and corresponds to resource of type R - unsafe { - self.insert_resource_by_id(component_id, ptr); - } - }); + if !R::IS_SETUP_RESOURCE { + let component_id = self.components.init_resource::(); + OwningPtr::make(value, |ptr| { + // SAFETY: component_id was just initialized and corresponds to resource of type R + unsafe { + self.insert_resource_by_id(component_id, ptr); + } + }); + } else { + error!( + "Inserting setup resource {} as a normal resource, ignoring", + std::any::type_name::() + ); + } } /// Inserts a new non-send resource with standard starting values. diff --git a/crates/bevy_log/src/lib.rs b/crates/bevy_log/src/lib.rs index a7518327a5678..d55d1055d6a43 100644 --- a/crates/bevy_log/src/lib.rs +++ b/crates/bevy_log/src/lib.rs @@ -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(), /// }) @@ -92,6 +92,7 @@ pub struct LogPlugin; /// `LogPlugin` settings #[derive(Resource)] +#[resource(setup)] pub struct LogSettings { /// Filters logs using the [`EnvFilter`] format pub filter: String, @@ -122,7 +123,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::() + .unwrap_or_default(); format!("{},{}", settings.level, settings.filter) }; LogTracer::init().unwrap(); diff --git a/crates/bevy_render/src/texture/image.rs b/crates/bevy_render/src/texture/image.rs index 36a0708a992b8..3ce3c403ae168 100644 --- a/crates/bevy_render/src/texture/image.rs +++ b/crates/bevy_render/src/texture/image.rs @@ -160,8 +160,9 @@ impl ImageSampler { /// Global resource for [`Image`] settings. /// -/// Can be set via `insert_resource` during app initialization to change the default settings. +/// Can be set via `insert_setup_resource` during app initialization to change the default settings. #[derive(Resource)] +#[resource(setup)] pub struct ImageSettings { /// The default image sampler to use when [`ImageSampler`] is set to `Default`. pub default_sampler: wgpu::SamplerDescriptor<'static>, diff --git a/crates/bevy_render/src/texture/mod.rs b/crates/bevy_render/src/texture/mod.rs index cebb5d34cf92a..0fa7cc3902d05 100644 --- a/crates/bevy_render/src/texture/mod.rs +++ b/crates/bevy_render/src/texture/mod.rs @@ -67,10 +67,9 @@ impl Plugin for ImagePlugin { .set_untracked(DEFAULT_IMAGE_HANDLE, Image::default()); let default_sampler = app - .world - .get_resource_or_insert_with(ImageSettings::default) - .default_sampler - .clone(); + .consume_setup_resource::() + .unwrap_or_default() + .default_sampler; if let Ok(render_app) = app.get_sub_app_mut(RenderApp) { let default_sampler = { let device = render_app.world.resource::(); diff --git a/crates/bevy_window/src/lib.rs b/crates/bevy_window/src/lib.rs index 6b17c363d71be..311010a3c466a 100644 --- a/crates/bevy_window/src/lib.rs +++ b/crates/bevy_window/src/lib.rs @@ -99,9 +99,7 @@ impl Plugin for WindowPlugin { if settings.add_primary_window { let window_descriptor = app - .world - .get_resource::() - .cloned() + .consume_setup_resource::() .unwrap_or_default(); let mut create_window_event = app.world.resource_mut::>(); create_window_event.send(CreateWindow { diff --git a/crates/bevy_window/src/window.rs b/crates/bevy_window/src/window.rs index 3ebb9311c56ef..28b21d6a30f94 100644 --- a/crates/bevy_window/src/window.rs +++ b/crates/bevy_window/src/window.rs @@ -859,6 +859,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, PartialEq)] #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))] +#[resource(setup)] pub struct WindowDescriptor { /// The requested logical width of the window's client area. /// diff --git a/examples/2d/sprite_sheet.rs b/examples/2d/sprite_sheet.rs index b2abdc7be0939..057183b434b64 100644 --- a/examples/2d/sprite_sheet.rs +++ b/examples/2d/sprite_sheet.rs @@ -5,7 +5,7 @@ use bevy::prelude::*; fn main() { App::new() - .insert_resource(ImageSettings::default_nearest()) // prevents blurry sprites + .insert_setup_resource(ImageSettings::default_nearest()) // prevents blurry sprites .add_plugins(DefaultPlugins) .add_startup_system(setup) .add_system(animate_sprite) diff --git a/examples/2d/texture_atlas.rs b/examples/2d/texture_atlas.rs index 39933e496ecff..958410292d070 100644 --- a/examples/2d/texture_atlas.rs +++ b/examples/2d/texture_atlas.rs @@ -6,7 +6,7 @@ use bevy::{asset::LoadState, prelude::*}; fn main() { App::new() .init_resource::() - .insert_resource(ImageSettings::default_nearest()) // prevents blurry sprites + .insert_setup_resource(ImageSettings::default_nearest()) // prevents blurry sprites .add_plugins(DefaultPlugins) .add_state(AppState::Setup) .add_system_set(SystemSet::on_enter(AppState::Setup).with_system(load_textures)) diff --git a/examples/3d/3d_shapes.rs b/examples/3d/3d_shapes.rs index d102b56e4e985..2e9930a5e0f3c 100644 --- a/examples/3d/3d_shapes.rs +++ b/examples/3d/3d_shapes.rs @@ -10,7 +10,7 @@ use bevy::{ fn main() { App::new() - .insert_resource(ImageSettings::default_nearest()) + .insert_setup_resource(ImageSettings::default_nearest()) .add_plugins(DefaultPlugins) .add_startup_system(setup) .add_system(rotate) diff --git a/examples/app/logs.rs b/examples/app/logs.rs index 029637b608eef..b9805986869b9 100644 --- a/examples/app/logs.rs +++ b/examples/app/logs.rs @@ -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(), // }) @@ -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: diff --git a/examples/app/thread_pool_resources.rs b/examples/app/thread_pool_resources.rs index e49ab1636c621..688390ae7aa6e 100644 --- a/examples/app/thread_pool_resources.rs +++ b/examples/app/thread_pool_resources.rs @@ -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(); } diff --git a/examples/asset/hot_asset_reloading.rs b/examples/asset/hot_asset_reloading.rs index a6e28328922a2..568ed2025c151 100644 --- a/examples/asset/hot_asset_reloading.rs +++ b/examples/asset/hot_asset_reloading.rs @@ -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() }) diff --git a/examples/ios/src/lib.rs b/examples/ios/src/lib.rs index aca39c99a57b1..5d7895dfb9fb6 100644 --- a/examples/ios/src/lib.rs +++ b/examples/ios/src/lib.rs @@ -4,7 +4,7 @@ use bevy::{input::touch::TouchPhase, prelude::*, window::WindowMode}; #[bevy_main] fn main() { App::new() - .insert_resource(WindowDescriptor { + .insert_setup_resource(WindowDescriptor { resizable: false, mode: WindowMode::BorderlessFullscreen, ..default() diff --git a/examples/shader/compute_shader_game_of_life.rs b/examples/shader/compute_shader_game_of_life.rs index aff074fd28c87..2214870671c5b 100644 --- a/examples/shader/compute_shader_game_of_life.rs +++ b/examples/shader/compute_shader_game_of_life.rs @@ -22,7 +22,7 @@ const WORKGROUP_SIZE: u32 = 8; fn main() { App::new() .insert_resource(ClearColor(Color::BLACK)) - .insert_resource(WindowDescriptor { + .insert_setup_resource(WindowDescriptor { // uncomment for unthrottled FPS // present_mode: bevy::window::PresentMode::AutoNoVsync, ..default() diff --git a/examples/stress_tests/bevymark.rs b/examples/stress_tests/bevymark.rs index fbf250cf64c1a..5ac541e4a854c 100644 --- a/examples/stress_tests/bevymark.rs +++ b/examples/stress_tests/bevymark.rs @@ -29,7 +29,7 @@ struct Bird { fn main() { App::new() - .insert_resource(WindowDescriptor { + .insert_setup_resource(WindowDescriptor { title: "BevyMark".to_string(), width: 800., height: 600., diff --git a/examples/stress_tests/many_buttons.rs b/examples/stress_tests/many_buttons.rs index 74a3d6b37d6b4..9e7343888846b 100644 --- a/examples/stress_tests/many_buttons.rs +++ b/examples/stress_tests/many_buttons.rs @@ -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(WindowDescriptor { present_mode: PresentMode::Immediate, ..default() }) diff --git a/examples/stress_tests/many_cubes.rs b/examples/stress_tests/many_cubes.rs index b1afdadd64a29..613c25f3fcc9c 100644 --- a/examples/stress_tests/many_cubes.rs +++ b/examples/stress_tests/many_cubes.rs @@ -21,7 +21,7 @@ use bevy::{ fn main() { App::new() - .insert_resource(WindowDescriptor { + .insert_setup_resource(WindowDescriptor { present_mode: PresentMode::AutoNoVsync, ..default() }) diff --git a/examples/stress_tests/many_foxes.rs b/examples/stress_tests/many_foxes.rs index d67d05e5b50e0..cbe256a7d55d9 100644 --- a/examples/stress_tests/many_foxes.rs +++ b/examples/stress_tests/many_foxes.rs @@ -18,7 +18,7 @@ struct Foxes { fn main() { App::new() - .insert_resource(WindowDescriptor { + .insert_setup_resource(WindowDescriptor { title: "🦊🦊🦊 Many Foxes! 🦊🦊🦊".to_string(), present_mode: PresentMode::AutoNoVsync, ..default() diff --git a/examples/stress_tests/many_lights.rs b/examples/stress_tests/many_lights.rs index fa63701feeb46..d8eddd7b4fca3 100644 --- a/examples/stress_tests/many_lights.rs +++ b/examples/stress_tests/many_lights.rs @@ -15,7 +15,7 @@ use rand::{thread_rng, Rng}; fn main() { App::new() - .insert_resource(WindowDescriptor { + .insert_setup_resource(WindowDescriptor { width: 1024.0, height: 768.0, title: "many_lights".to_string(), diff --git a/examples/stress_tests/many_sprites.rs b/examples/stress_tests/many_sprites.rs index 1a232c37ae30e..e517e1041697b 100644 --- a/examples/stress_tests/many_sprites.rs +++ b/examples/stress_tests/many_sprites.rs @@ -24,7 +24,7 @@ struct ColorTint(bool); fn main() { App::new() - .insert_resource(WindowDescriptor { + .insert_setup_resource(WindowDescriptor { present_mode: PresentMode::AutoNoVsync, ..default() }) diff --git a/examples/tools/scene_viewer.rs b/examples/tools/scene_viewer.rs index 9f216e42fe6d5..9b7b6cf35f832 100644 --- a/examples/tools/scene_viewer.rs +++ b/examples/tools/scene_viewer.rs @@ -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(WindowDescriptor { title: "bevy scene viewer".to_string(), ..default() }) diff --git a/examples/ui/text_debug.rs b/examples/ui/text_debug.rs index 1426e7a3bb619..19769a9fd8711 100644 --- a/examples/ui/text_debug.rs +++ b/examples/ui/text_debug.rs @@ -8,7 +8,7 @@ use bevy::{ fn main() { App::new() - .insert_resource(WindowDescriptor { + .insert_setup_resource(WindowDescriptor { present_mode: PresentMode::AutoNoVsync, ..default() }) diff --git a/examples/window/low_power.rs b/examples/window/low_power.rs index e97f20fc5e501..57f5baba75456 100644 --- a/examples/window/low_power.rs +++ b/examples/window/low_power.rs @@ -25,7 +25,7 @@ fn main() { ..default() }) // Turn off vsync to maximize CPU/GPU usage - .insert_resource(WindowDescriptor { + .insert_setup_resource(WindowDescriptor { present_mode: PresentMode::AutoNoVsync, ..default() }) diff --git a/examples/window/scale_factor_override.rs b/examples/window/scale_factor_override.rs index 648a67b5dc6df..bffd32dfe6903 100644 --- a/examples/window/scale_factor_override.rs +++ b/examples/window/scale_factor_override.rs @@ -5,7 +5,7 @@ use bevy::prelude::*; fn main() { App::new() - .insert_resource(WindowDescriptor { + .insert_setup_resource(WindowDescriptor { width: 500., height: 300., ..default() diff --git a/examples/window/transparent_window.rs b/examples/window/transparent_window.rs index b229b05092a28..37a6fe11de7ea 100644 --- a/examples/window/transparent_window.rs +++ b/examples/window/transparent_window.rs @@ -10,7 +10,7 @@ fn main() { App::new() // ClearColor must have 0 alpha, otherwise some color will bleed through .insert_resource(ClearColor(Color::NONE)) - .insert_resource(WindowDescriptor { + .insert_setup_resource(WindowDescriptor { // Setting `transparent` allows the `ClearColor`'s alpha value to take effect transparent: true, // Disabling window decorations to make it feel more like a widget than a window diff --git a/examples/window/window_settings.rs b/examples/window/window_settings.rs index a56f20ee49ca1..8a4faaa6a7ddc 100644 --- a/examples/window/window_settings.rs +++ b/examples/window/window_settings.rs @@ -9,7 +9,7 @@ use bevy::{ fn main() { App::new() - .insert_resource(WindowDescriptor { + .insert_setup_resource(WindowDescriptor { title: "I am a window!".to_string(), width: 500., height: 300., diff --git a/tests/window/minimising.rs b/tests/window/minimising.rs index f7198fd187904..3753c6d2b6e97 100644 --- a/tests/window/minimising.rs +++ b/tests/window/minimising.rs @@ -6,7 +6,7 @@ fn main() { // TODO: Combine this with `resizing` once multiple_windows is simpler than // it is currently. App::new() - .insert_resource(WindowDescriptor { + .insert_setup_resource(WindowDescriptor { title: "Minimising".into(), ..Default::default() }) diff --git a/tests/window/resizing.rs b/tests/window/resizing.rs index 24824e0ed0c42..c2d2a100513cc 100644 --- a/tests/window/resizing.rs +++ b/tests/window/resizing.rs @@ -19,7 +19,7 @@ struct Dimensions { fn main() { App::new() - .insert_resource(WindowDescriptor { + .insert_setup_resource(WindowDescriptor { width: MAX_WIDTH.try_into().unwrap(), height: MAX_HEIGHT.try_into().unwrap(), scale_factor_override: Some(1.),