From 9a0bfc6f14241d58e6d4d1bc7ce72ebaa673b695 Mon Sep 17 00:00:00 2001 From: Benjamin Brienen Date: Thu, 26 Sep 2024 15:30:56 +0200 Subject: [PATCH 01/17] Fix action.yml syntax (#15430) # Objective Fixes #15429 ## Solution Fix type of default value ## Testing We'll see if the CI still works I guess. ## Showcase ![image](https://github.com/user-attachments/assets/aeb376fe-1c88-4b1c-8c91-fd8f142c2378) --- .github/actions/install-linux-deps/action.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/actions/install-linux-deps/action.yml b/.github/actions/install-linux-deps/action.yml index 00b904a514a6b..a59e2240b6128 100644 --- a/.github/actions/install-linux-deps/action.yml +++ b/.github/actions/install-linux-deps/action.yml @@ -20,19 +20,19 @@ inputs: alsa: description: Install alsa (libasound2-dev) required: false - default: true + default: "true" udev: description: Install udev (libudev-dev) required: false - default: true + default: "true" wayland: description: Install Wayland (libwayland-dev) required: false - default: false + default: "false" xkb: description: Install xkb (libxkbcommon-dev) required: false - default: false + default: "false" runs: using: composite steps: From 5e6b141c132df1d429038baa98b9b9f097a60112 Mon Sep 17 00:00:00 2001 From: SpecificProtagonist Date: Thu, 26 Sep 2024 15:31:11 +0200 Subject: [PATCH 02/17] List components for QueryEntityError::QueryDoesNotMatch (#15435) # Objective Make it easier to debug why an entity doesn't match a query. ## Solution List the entities components in `QueryEntityError::QueryDoesNotMatch`'s message, e.g. `The query does not match the entity 0v1, which has components foo::Bar, foo::Baz`. This covers most cases as expected components are typically known and filtering for change detection is rare when assessing a query by entity id. ## Testing Added a test confirming the new message matches the entity's components. ## Migration Guide - `QueryEntityError` now has a lifetime. Convert it to a custom error if you need to store it. --------- Co-authored-by: Alice Cecile Co-authored-by: poopy --- crates/bevy_ecs/src/query/error.rs | 109 ++++++++++++++++++-- crates/bevy_ecs/src/query/state.rs | 26 ++--- crates/bevy_ecs/src/world/mod.rs | 2 +- crates/bevy_render/src/render_phase/draw.rs | 3 +- crates/bevy_transform/src/helper.rs | 2 +- 5 files changed, 119 insertions(+), 23 deletions(-) diff --git a/crates/bevy_ecs/src/query/error.rs b/crates/bevy_ecs/src/query/error.rs index 1f1f33f2c4d56..bdf503b32cf41 100644 --- a/crates/bevy_ecs/src/query/error.rs +++ b/crates/bevy_ecs/src/query/error.rs @@ -1,26 +1,93 @@ use thiserror::Error; -use crate::entity::Entity; +use crate::{entity::Entity, world::unsafe_world_cell::UnsafeWorldCell}; /// An error that occurs when retrieving a specific [`Entity`]'s query result from [`Query`](crate::system::Query) or [`QueryState`](crate::query::QueryState). // TODO: return the type_name as part of this error -#[derive(Debug, PartialEq, Eq, Clone, Copy, Error)] -pub enum QueryEntityError { +#[derive(Clone, Copy)] +pub enum QueryEntityError<'w> { /// The given [`Entity`]'s components do not match the query. /// /// Either it does not have a requested component, or it has a component which the query filters out. - #[error("The components of entity {0:?} do not match the query")] - QueryDoesNotMatch(Entity), + QueryDoesNotMatch(Entity, UnsafeWorldCell<'w>), /// The given [`Entity`] does not exist. - #[error("The entity {0:?} does not exist")] NoSuchEntity(Entity), /// The [`Entity`] was requested mutably more than once. /// /// See [`QueryState::get_many_mut`](crate::query::QueryState::get_many_mut) for an example. - #[error("The entity {0:?} was requested mutably more than once")] AliasedMutability(Entity), } +impl<'w> std::error::Error for QueryEntityError<'w> {} + +impl<'w> std::fmt::Display for QueryEntityError<'w> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match *self { + Self::QueryDoesNotMatch(entity, world) => { + write!( + f, + "The query does not match the entity {entity}, which has components " + )?; + format_archetype(f, world, entity) + } + Self::NoSuchEntity(entity) => write!(f, "The entity {entity} does not exist"), + Self::AliasedMutability(entity) => write!( + f, + "The entity {entity} was requested mutably more than once" + ), + } + } +} + +impl<'w> std::fmt::Debug for QueryEntityError<'w> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match *self { + Self::QueryDoesNotMatch(entity, world) => { + write!(f, "QueryDoesNotMatch({entity} with components ")?; + format_archetype(f, world, entity)?; + write!(f, ")") + } + Self::NoSuchEntity(entity) => write!(f, "NoSuchEntity({entity})"), + Self::AliasedMutability(entity) => write!(f, "AliasedMutability({entity})"), + } + } +} + +fn format_archetype( + f: &mut std::fmt::Formatter<'_>, + world: UnsafeWorldCell<'_>, + entity: Entity, +) -> std::fmt::Result { + // We know entity is still alive + let entity = world + .get_entity(entity) + .expect("entity does not belong to world"); + for (i, component_id) in entity.archetype().components().enumerate() { + if i > 0 { + write!(f, ", ")?; + } + let name = world + .components() + .get_name(component_id) + .expect("entity does not belong to world"); + write!(f, "{name}")?; + } + Ok(()) +} + +impl<'w> PartialEq for QueryEntityError<'w> { + fn eq(&self, other: &Self) -> bool { + match (self, other) { + (Self::QueryDoesNotMatch(e1, _), Self::QueryDoesNotMatch(e2, _)) if e1 == e2 => true, + (Self::NoSuchEntity(e1), Self::NoSuchEntity(e2)) if e1 == e2 => true, + (Self::AliasedMutability(e1), Self::AliasedMutability(e2)) if e1 == e2 => true, + _ => false, + } + } +} + +impl<'w> Eq for QueryEntityError<'w> {} + /// An error that occurs when evaluating a [`Query`](crate::system::Query) or [`QueryState`](crate::query::QueryState) as a single expected result via /// [`get_single`](crate::system::Query::get_single) or [`get_single_mut`](crate::system::Query::get_single_mut). #[derive(Debug, Error)] @@ -32,3 +99,31 @@ pub enum QuerySingleError { #[error("Multiple entities fit the query {0}")] MultipleEntities(&'static str), } + +#[cfg(test)] +mod test { + use crate as bevy_ecs; + use crate::prelude::World; + use bevy_ecs_macros::Component; + + #[test] + fn query_does_not_match() { + let mut world = World::new(); + + #[derive(Component)] + struct Present1; + #[derive(Component)] + struct Present2; + #[derive(Component, Debug)] + struct NotPresent; + + let entity = world.spawn((Present1, Present2)).id(); + + let err = world + .query::<&NotPresent>() + .get(&world, entity) + .unwrap_err(); + + assert_eq!(format!("{err:?}"), "QueryDoesNotMatch(0v1 with components bevy_ecs::query::error::test::query_does_not_match::Present1, bevy_ecs::query::error::test::query_does_not_match::Present2)"); + } +} diff --git a/crates/bevy_ecs/src/query/state.rs b/crates/bevy_ecs/src/query/state.rs index ab9947f80be30..07c0f8bd47239 100644 --- a/crates/bevy_ecs/src/query/state.rs +++ b/crates/bevy_ecs/src/query/state.rs @@ -744,7 +744,7 @@ impl QueryState { &mut self, world: &'w World, entity: Entity, - ) -> Result, QueryEntityError> { + ) -> Result, QueryEntityError<'w>> { self.update_archetypes(world); // SAFETY: query is read only unsafe { @@ -794,7 +794,7 @@ impl QueryState { &mut self, world: &'w World, entities: [Entity; N], - ) -> Result<[ROQueryItem<'w, D>; N], QueryEntityError> { + ) -> Result<[ROQueryItem<'w, D>; N], QueryEntityError<'w>> { self.update_archetypes(world); // SAFETY: @@ -818,7 +818,7 @@ impl QueryState { &mut self, world: &'w mut World, entity: Entity, - ) -> Result, QueryEntityError> { + ) -> Result, QueryEntityError<'w>> { self.update_archetypes(world); let change_tick = world.change_tick(); let last_change_tick = world.last_change_tick(); @@ -868,7 +868,7 @@ impl QueryState { /// let invalid_entity = world.spawn_empty().id(); /// /// assert_eq!(query_state.get_many_mut(&mut world, [wrong_entity]).unwrap_err(), QueryEntityError::NoSuchEntity(wrong_entity)); - /// assert_eq!(query_state.get_many_mut(&mut world, [invalid_entity]).unwrap_err(), QueryEntityError::QueryDoesNotMatch(invalid_entity)); + /// assert_eq!(match query_state.get_many_mut(&mut world, [invalid_entity]).unwrap_err() {QueryEntityError::QueryDoesNotMatch(entity, _) => entity, _ => panic!()}, invalid_entity); /// assert_eq!(query_state.get_many_mut(&mut world, [entities[0], entities[0]]).unwrap_err(), QueryEntityError::AliasedMutability(entities[0])); /// ``` #[inline] @@ -876,7 +876,7 @@ impl QueryState { &mut self, world: &'w mut World, entities: [Entity; N], - ) -> Result<[D::Item<'w>; N], QueryEntityError> { + ) -> Result<[D::Item<'w>; N], QueryEntityError<'w>> { self.update_archetypes(world); let change_tick = world.change_tick(); @@ -911,7 +911,7 @@ impl QueryState { &self, world: &'w World, entity: Entity, - ) -> Result, QueryEntityError> { + ) -> Result, QueryEntityError<'w>> { self.validate_world(world.id()); // SAFETY: query is read only and world is validated unsafe { @@ -937,7 +937,7 @@ impl QueryState { &mut self, world: UnsafeWorldCell<'w>, entity: Entity, - ) -> Result, QueryEntityError> { + ) -> Result, QueryEntityError<'w>> { self.update_archetypes_unsafe_world_cell(world); self.get_unchecked_manual(world, entity, world.last_change_tick(), world.change_tick()) } @@ -960,7 +960,7 @@ impl QueryState { entity: Entity, last_run: Tick, this_run: Tick, - ) -> Result, QueryEntityError> { + ) -> Result, QueryEntityError<'w>> { let location = world .entities() .get(entity) @@ -969,7 +969,7 @@ impl QueryState { .matched_archetypes .contains(location.archetype_id.index()) { - return Err(QueryEntityError::QueryDoesNotMatch(entity)); + return Err(QueryEntityError::QueryDoesNotMatch(entity, world)); } let archetype = world .archetypes() @@ -989,7 +989,7 @@ impl QueryState { if F::filter_fetch(&mut filter, entity, location.table_row) { Ok(D::fetch(&mut fetch, entity, location.table_row)) } else { - Err(QueryEntityError::QueryDoesNotMatch(entity)) + Err(QueryEntityError::QueryDoesNotMatch(entity, world)) } } @@ -1008,7 +1008,7 @@ impl QueryState { entities: [Entity; N], last_run: Tick, this_run: Tick, - ) -> Result<[ROQueryItem<'w, D>; N], QueryEntityError> { + ) -> Result<[ROQueryItem<'w, D>; N], QueryEntityError<'w>> { let mut values = [(); N].map(|_| MaybeUninit::uninit()); for (value, entity) in std::iter::zip(&mut values, entities) { @@ -1042,7 +1042,7 @@ impl QueryState { entities: [Entity; N], last_run: Tick, this_run: Tick, - ) -> Result<[D::Item<'w>; N], QueryEntityError> { + ) -> Result<[D::Item<'w>; N], QueryEntityError<'w>> { // Verify that all entities are unique for i in 0..N { for j in 0..i { @@ -1442,7 +1442,7 @@ impl QueryState { /// # let invalid_entity = world.spawn_empty().id(); /// /// # assert_eq!(query_state.get_many_mut(&mut world, [wrong_entity]).unwrap_err(), QueryEntityError::NoSuchEntity(wrong_entity)); - /// # assert_eq!(query_state.get_many_mut(&mut world, [invalid_entity]).unwrap_err(), QueryEntityError::QueryDoesNotMatch(invalid_entity)); + /// assert_eq!(match query_state.get_many_mut(&mut world, [invalid_entity]).unwrap_err() {QueryEntityError::QueryDoesNotMatch(entity, _) => entity, _ => panic!()}, invalid_entity); /// # assert_eq!(query_state.get_many_mut(&mut world, [entities[0], entities[0]]).unwrap_err(), QueryEntityError::AliasedMutability(entities[0])); /// ``` /// diff --git a/crates/bevy_ecs/src/world/mod.rs b/crates/bevy_ecs/src/world/mod.rs index 00be7aee4d68f..568a70c0dc7e7 100644 --- a/crates/bevy_ecs/src/world/mod.rs +++ b/crates/bevy_ecs/src/world/mod.rs @@ -723,7 +723,7 @@ impl World { /// # Errors /// /// If any entities are duplicated. - fn verify_unique_entities(entities: &[Entity]) -> Result<(), QueryEntityError> { + fn verify_unique_entities(entities: &[Entity]) -> Result<(), QueryEntityError<'static>> { for i in 0..entities.len() { for j in 0..i { if entities[i] == entities[j] { diff --git a/crates/bevy_render/src/render_phase/draw.rs b/crates/bevy_render/src/render_phase/draw.rs index 0880ae797efd3..41a5f49897ec9 100644 --- a/crates/bevy_render/src/render_phase/draw.rs +++ b/crates/bevy_render/src/render_phase/draw.rs @@ -325,7 +325,8 @@ where Ok(view) => view, Err(err) => match err { QueryEntityError::NoSuchEntity(_) => return Err(DrawError::ViewEntityNotFound), - QueryEntityError::QueryDoesNotMatch(_) | QueryEntityError::AliasedMutability(_) => { + QueryEntityError::QueryDoesNotMatch(_, _) + | QueryEntityError::AliasedMutability(_) => { return Err(DrawError::InvalidViewQuery) } }, diff --git a/crates/bevy_transform/src/helper.rs b/crates/bevy_transform/src/helper.rs index 091e39e189bac..4a77f3fa72604 100644 --- a/crates/bevy_transform/src/helper.rs +++ b/crates/bevy_transform/src/helper.rs @@ -51,7 +51,7 @@ impl<'w, 's> TransformHelper<'w, 's> { fn map_error(err: QueryEntityError, ancestor: bool) -> ComputeGlobalTransformError { use ComputeGlobalTransformError::*; match err { - QueryEntityError::QueryDoesNotMatch(entity) => MissingTransform(entity), + QueryEntityError::QueryDoesNotMatch(entity, _) => MissingTransform(entity), QueryEntityError::NoSuchEntity(entity) => { if ancestor { MalformedHierarchy(entity) From e34a56c963424776432807b1c1a22821bd82cef0 Mon Sep 17 00:00:00 2001 From: Benjamin Brienen Date: Thu, 26 Sep 2024 15:32:33 +0200 Subject: [PATCH 03/17] Better info message (#15432) # Objective Fixes the confusion that caused #5660 ## Solution Make it clear that it is the hardware which doesn't support the format and not bevy's fault. --- examples/3d/skybox.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/examples/3d/skybox.rs b/examples/3d/skybox.rs index 115d378e2e2d6..12b22ae2e853d 100644 --- a/examples/3d/skybox.rs +++ b/examples/3d/skybox.rs @@ -127,7 +127,10 @@ fn cycle_cubemap_asset( if supported_compressed_formats.contains(CUBEMAPS[new_index].1) { break; } - info!("Skipping unsupported format: {:?}", CUBEMAPS[new_index]); + info!( + "Skipping format which is not supported by current hardware: {:?}", + CUBEMAPS[new_index] + ); } // Skip swapping to the same texture. Useful for when ktx2, zstd, or compressed texture support From 5fcbdc137a6e3e636aef3e5fd9190b0bc6ec2887 Mon Sep 17 00:00:00 2001 From: poopy Date: Thu, 26 Sep 2024 15:40:24 +0200 Subject: [PATCH 04/17] feature gate `use bevy_animation` in `bevy_gltf` (#15424) # Objective `bevy_gltf` have an instance where `use bevy_animation` is not behind `#[cfg(feature = "bevy_animation")]`. This resulted in a compile error when the feature is not enabled: `failed to resolve: use of undeclared crate or module 'bevy_animation'`. ## Solution move this instance of `use bevy_animation` behind the `cfg` attribute. ## Testing I no longer get the error when compiling without the feature. --- crates/bevy_gltf/src/loader.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/crates/bevy_gltf/src/loader.rs b/crates/bevy_gltf/src/loader.rs index e9ca9562da596..f7324223781e0 100644 --- a/crates/bevy_gltf/src/loader.rs +++ b/crates/bevy_gltf/src/loader.rs @@ -3,11 +3,13 @@ use crate::{ GltfMeshExtras, GltfNode, GltfSceneExtras, GltfSkin, }; -use bevy_animation::prelude::{ - Keyframes, MorphWeightsKeyframes, RotationKeyframes, ScaleKeyframes, TranslationKeyframes, -}; #[cfg(feature = "bevy_animation")] -use bevy_animation::{AnimationTarget, AnimationTargetId}; +use bevy_animation::{ + keyframes::{ + Keyframes, MorphWeightsKeyframes, RotationKeyframes, ScaleKeyframes, TranslationKeyframes, + }, + AnimationTarget, AnimationTargetId, +}; use bevy_asset::{ io::Reader, AssetLoadError, AssetLoader, Handle, LoadContext, ReadAssetBytesError, }; From 35d10866b893a106a853049b2fcc9ba0240da72c Mon Sep 17 00:00:00 2001 From: hshrimp <182684536+hooded-shrimp@users.noreply.github.com> Date: Thu, 26 Sep 2024 15:47:28 -0700 Subject: [PATCH 05/17] Rename init_component & friends (#15454) # Objective - Fixes #15451 ## Migration Guide - `World::init_component` has been renamed to `register_component`. - `World::init_component_with_descriptor` has been renamed to `register_component_with_descriptor`. - `World::init_bundle` has been renamed to `register_bundle`. - `Components::init_component` has been renamed to `register_component`. - `Components::init_component_with_descriptor` has been renamed to `register_component_with_descriptor`. - `Components::init_resource` has been renamed to `register_resource`. - `Components::init_non_send` had been renamed to `register_non_send`. --- crates/bevy_ecs/src/bundle.rs | 12 ++-- crates/bevy_ecs/src/component.rs | 50 +++++++-------- crates/bevy_ecs/src/lib.rs | 16 ++--- crates/bevy_ecs/src/observer/mod.rs | 12 ++-- crates/bevy_ecs/src/observer/runner.rs | 2 +- crates/bevy_ecs/src/observer/trigger_event.rs | 4 +- crates/bevy_ecs/src/query/builder.rs | 10 +-- crates/bevy_ecs/src/query/fetch.rs | 8 +-- crates/bevy_ecs/src/query/filter.rs | 8 +-- crates/bevy_ecs/src/query/state.rs | 16 ++--- crates/bevy_ecs/src/schedule/schedule.rs | 4 +- crates/bevy_ecs/src/storage/table/mod.rs | 2 +- crates/bevy_ecs/src/system/mod.rs | 2 +- crates/bevy_ecs/src/system/system_param.rs | 8 +-- crates/bevy_ecs/src/world/entity_ref.rs | 26 ++++---- crates/bevy_ecs/src/world/mod.rs | 62 +++++++++---------- examples/ecs/dynamic.rs | 2 +- 17 files changed, 122 insertions(+), 122 deletions(-) diff --git a/crates/bevy_ecs/src/bundle.rs b/crates/bevy_ecs/src/bundle.rs index dab5ec6caa22f..f1afd03fafc97 100644 --- a/crates/bevy_ecs/src/bundle.rs +++ b/crates/bevy_ecs/src/bundle.rs @@ -205,7 +205,7 @@ unsafe impl Bundle for C { storages: &mut Storages, ids: &mut impl FnMut(ComponentId), ) { - ids(components.init_component::(storages)); + ids(components.register_component::(storages)); } unsafe fn from_components(ctx: &mut T, func: &mut F) -> Self @@ -786,7 +786,7 @@ impl<'w> BundleInserter<'w> { ) -> Self { let bundle_id = world .bundles - .init_info::(&mut world.components, &mut world.storages); + .register_info::(&mut world.components, &mut world.storages); // SAFETY: We just ensured this bundle exists unsafe { Self::new_with_id(world, archetype_id, bundle_id, change_tick) } } @@ -1135,7 +1135,7 @@ impl<'w> BundleSpawner<'w> { pub fn new(world: &'w mut World, change_tick: Tick) -> Self { let bundle_id = world .bundles - .init_info::(&mut world.components, &mut world.storages); + .register_info::(&mut world.components, &mut world.storages); // SAFETY: we initialized this bundle_id in `init_info` unsafe { Self::new_with_id(world, bundle_id, change_tick) } } @@ -1318,10 +1318,10 @@ impl Bundles { self.bundle_ids.get(&type_id).cloned() } - /// Initializes a new [`BundleInfo`] for a statically known type. + /// Registers a new [`BundleInfo`] for a statically known type. /// - /// Also initializes all the components in the bundle. - pub(crate) fn init_info( + /// Also registers all the components in the bundle. + pub(crate) fn register_info( &mut self, components: &mut Components, storages: &mut Storages, diff --git a/crates/bevy_ecs/src/component.rs b/crates/bevy_ecs/src/component.rs index 107617002b9c7..a1215d01e6046 100644 --- a/crates/bevy_ecs/src/component.rs +++ b/crates/bevy_ecs/src/component.rs @@ -652,7 +652,7 @@ impl ComponentInfo { /// [`World`]. /// /// Each time a new `Component` type is registered within a `World` using -/// e.g. [`World::init_component`] or [`World::init_component_with_descriptor`] +/// e.g. [`World::register_component`] or [`World::register_component_with_descriptor`] /// or a Resource with e.g. [`World::init_resource`], /// a corresponding `ComponentId` is created to track it. /// @@ -837,16 +837,16 @@ pub struct Components { } impl Components { - /// Initializes a component of type `T` with this instance. - /// If a component of this type has already been initialized, this will return + /// Registers a component of type `T` with this instance. + /// If a component of this type has already been registered, this will return /// the ID of the pre-existing component. /// /// # See also /// /// * [`Components::component_id()`] - /// * [`Components::init_component_with_descriptor()`] + /// * [`Components::register_component_with_descriptor()`] #[inline] - pub fn init_component(&mut self, storages: &mut Storages) -> ComponentId { + pub fn register_component(&mut self, storages: &mut Storages) -> ComponentId { let mut registered = false; let id = { let Components { @@ -856,7 +856,7 @@ impl Components { } = self; let type_id = TypeId::of::(); *indices.entry(type_id).or_insert_with(|| { - let id = Components::init_component_inner( + let id = Components::register_component_inner( components, storages, ComponentDescriptor::new::(), @@ -875,7 +875,7 @@ impl Components { id } - /// Initializes a component described by `descriptor`. + /// Registers a component described by `descriptor`. /// /// ## Note /// @@ -885,17 +885,17 @@ impl Components { /// # See also /// /// * [`Components::component_id()`] - /// * [`Components::init_component()`] - pub fn init_component_with_descriptor( + /// * [`Components::register_component()`] + pub fn register_component_with_descriptor( &mut self, storages: &mut Storages, descriptor: ComponentDescriptor, ) -> ComponentId { - Components::init_component_inner(&mut self.components, storages, descriptor) + Components::register_component_inner(&mut self.components, storages, descriptor) } #[inline] - fn init_component_inner( + fn register_component_inner( components: &mut Vec, storages: &mut Storages, descriptor: ComponentDescriptor, @@ -966,7 +966,7 @@ impl Components { /// instance. /// /// Returns [`None`] if the `Component` type has not - /// yet been initialized using [`Components::init_component()`]. + /// yet been initialized using [`Components::register_component()`]. /// /// ``` /// use bevy_ecs::prelude::*; @@ -976,7 +976,7 @@ impl Components { /// #[derive(Component)] /// struct ComponentA; /// - /// let component_a_id = world.init_component::(); + /// let component_a_id = world.register_component::(); /// /// assert_eq!(component_a_id, world.components().component_id::().unwrap()) /// ``` @@ -1004,7 +1004,7 @@ impl Components { /// instance. /// /// Returns [`None`] if the `Resource` type has not - /// yet been initialized using [`Components::init_resource()`]. + /// yet been initialized using [`Components::register_resource()`]. /// /// ``` /// use bevy_ecs::prelude::*; @@ -1028,31 +1028,31 @@ impl Components { self.get_resource_id(TypeId::of::()) } - /// Initializes a [`Resource`] of type `T` with this instance. - /// If a resource of this type has already been initialized, this will return + /// Registers a [`Resource`] of type `T` with this instance. + /// If a resource of this type has already been registered, this will return /// the ID of the pre-existing resource. /// /// # See also /// /// * [`Components::resource_id()`] #[inline] - pub fn init_resource(&mut self) -> ComponentId { + pub fn register_resource(&mut self) -> ComponentId { // SAFETY: The [`ComponentDescriptor`] matches the [`TypeId`] unsafe { - self.get_or_insert_resource_with(TypeId::of::(), || { + self.get_or_register_resource_with(TypeId::of::(), || { ComponentDescriptor::new_resource::() }) } } - /// Initializes a [non-send resource](crate::system::NonSend) of type `T` with this instance. - /// If a resource of this type has already been initialized, this will return + /// Registers a [non-send resource](crate::system::NonSend) of type `T` with this instance. + /// If a resource of this type has already been registered, this will return /// the ID of the pre-existing resource. #[inline] - pub fn init_non_send(&mut self) -> ComponentId { + pub fn register_non_send(&mut self) -> ComponentId { // SAFETY: The [`ComponentDescriptor`] matches the [`TypeId`] unsafe { - self.get_or_insert_resource_with(TypeId::of::(), || { + self.get_or_register_resource_with(TypeId::of::(), || { ComponentDescriptor::new_non_send::(StorageType::default()) }) } @@ -1062,7 +1062,7 @@ impl Components { /// /// The [`ComponentDescriptor`] must match the [`TypeId`] #[inline] - unsafe fn get_or_insert_resource_with( + unsafe fn get_or_register_resource_with( &mut self, type_id: TypeId, func: impl FnOnce() -> ComponentDescriptor, @@ -1293,7 +1293,7 @@ struct InitComponentId { impl FromWorld for InitComponentId { fn from_world(world: &mut World) -> Self { Self { - component_id: world.init_component::(), + component_id: world.register_component::(), marker: PhantomData, } } @@ -1384,7 +1384,7 @@ impl RequiredComponents { storages: &mut Storages, constructor: fn() -> C, ) { - let component_id = components.init_component::(storages); + let component_id = components.register_component::(storages); let erased: RequiredComponentConstructor = RequiredComponentConstructor(Arc::new( move |table, sparse_sets, diff --git a/crates/bevy_ecs/src/lib.rs b/crates/bevy_ecs/src/lib.rs index c257231ccdb34..cf0a04e5b6353 100644 --- a/crates/bevy_ecs/src/lib.rs +++ b/crates/bevy_ecs/src/lib.rs @@ -181,8 +181,8 @@ mod tests { assert_eq!( ids, &[ - world.init_component::(), - world.init_component::(), + world.register_component::(), + world.register_component::(), ] ); @@ -235,10 +235,10 @@ mod tests { assert_eq!( ids, &[ - world.init_component::(), - world.init_component::(), - world.init_component::(), - world.init_component::(), + world.register_component::(), + world.register_component::(), + world.register_component::(), + world.register_component::(), ] ); @@ -288,7 +288,7 @@ mod tests { }, ); - assert_eq!(ids, &[world.init_component::(),]); + assert_eq!(ids, &[world.register_component::(),]); let e4 = world .spawn(BundleWithIgnored { @@ -2011,7 +2011,7 @@ mod tests { struct Y; let mut world = World::new(); - let x_id = world.init_component::(); + let x_id = world.register_component::(); let mut e = world.spawn_empty(); diff --git a/crates/bevy_ecs/src/observer/mod.rs b/crates/bevy_ecs/src/observer/mod.rs index c22ff12c5ba21..50ce3b7fdedef 100644 --- a/crates/bevy_ecs/src/observer/mod.rs +++ b/crates/bevy_ecs/src/observer/mod.rs @@ -733,7 +733,7 @@ mod tests { world.flush(); let mut event = EventWithData { counter: 0 }; - let component_a = world.init_component::(); + let component_a = world.register_component::(); world.trigger_targets_ref(&mut event, component_a); assert_eq!(5, event.counter); } @@ -756,7 +756,7 @@ mod tests { fn observer_multiple_events() { let mut world = World::new(); world.init_resource::(); - let on_remove = world.init_component::(); + let on_remove = world.register_component::(); world.spawn( // SAFETY: OnAdd and OnRemove are both unit types, so this is safe unsafe { @@ -779,8 +779,8 @@ mod tests { fn observer_multiple_components() { let mut world = World::new(); world.init_resource::(); - world.init_component::(); - world.init_component::(); + world.register_component::(); + world.register_component::(); world.observe(|_: Trigger, mut res: ResMut| res.observed("add_ab")); @@ -883,7 +883,7 @@ mod tests { let mut world = World::new(); world.init_resource::(); - let component_id = world.init_component::(); + let component_id = world.register_component::(); world.spawn( Observer::new(|_: Trigger, mut res: ResMut| res.observed("event_a")) .with_component(component_id), @@ -905,7 +905,7 @@ mod tests { fn observer_dynamic_trigger() { let mut world = World::new(); world.init_resource::(); - let event_a = world.init_component::(); + let event_a = world.register_component::(); world.spawn(ObserverState { // SAFETY: we registered `event_a` above and it matches the type of TriggerA diff --git a/crates/bevy_ecs/src/observer/runner.rs b/crates/bevy_ecs/src/observer/runner.rs index 87d0c35f4e1d2..024d46b3c93a6 100644 --- a/crates/bevy_ecs/src/observer/runner.rs +++ b/crates/bevy_ecs/src/observer/runner.rs @@ -393,7 +393,7 @@ fn hook_on_add>( _: ComponentId, ) { world.commands().queue(move |world: &mut World| { - let event_type = world.init_component::(); + let event_type = world.register_component::(); let mut components = Vec::new(); B::component_ids(&mut world.components, &mut world.storages, &mut |id| { components.push(id); diff --git a/crates/bevy_ecs/src/observer/trigger_event.rs b/crates/bevy_ecs/src/observer/trigger_event.rs index 2c90a478ee0f2..95d404a3985ff 100644 --- a/crates/bevy_ecs/src/observer/trigger_event.rs +++ b/crates/bevy_ecs/src/observer/trigger_event.rs @@ -16,14 +16,14 @@ pub struct TriggerEvent { impl TriggerEvent { pub(super) fn trigger(mut self, world: &mut World) { - let event_type = world.init_component::(); + let event_type = world.register_component::(); trigger_event(world, event_type, &mut self.event, self.targets); } } impl TriggerEvent<&mut E, Targets> { pub(super) fn trigger_ref(self, world: &mut World) { - let event_type = world.init_component::(); + let event_type = world.register_component::(); trigger_event(world, event_type, self.event, self.targets); } } diff --git a/crates/bevy_ecs/src/query/builder.rs b/crates/bevy_ecs/src/query/builder.rs index 23c5c5a65bff0..d2d007196e4ad 100644 --- a/crates/bevy_ecs/src/query/builder.rs +++ b/crates/bevy_ecs/src/query/builder.rs @@ -312,9 +312,9 @@ mod tests { let mut world = World::new(); let entity_a = world.spawn((A(0), B(0))).id(); let entity_b = world.spawn((A(0), C(0))).id(); - let component_id_a = world.init_component::(); - let component_id_b = world.init_component::(); - let component_id_c = world.init_component::(); + let component_id_a = world.register_component::(); + let component_id_b = world.register_component::(); + let component_id_c = world.register_component::(); let mut query_a = QueryBuilder::::new(&mut world) .with_id(component_id_a) @@ -401,8 +401,8 @@ mod tests { fn builder_dynamic_components() { let mut world = World::new(); let entity = world.spawn((A(0), B(1))).id(); - let component_id_a = world.init_component::(); - let component_id_b = world.init_component::(); + let component_id_a = world.register_component::(); + let component_id_b = world.register_component::(); let mut query = QueryBuilder::::new(&mut world) .ref_id(component_id_a) diff --git a/crates/bevy_ecs/src/query/fetch.rs b/crates/bevy_ecs/src/query/fetch.rs index 311ddcc9aaaaa..57ff7e39f1a00 100644 --- a/crates/bevy_ecs/src/query/fetch.rs +++ b/crates/bevy_ecs/src/query/fetch.rs @@ -1188,7 +1188,7 @@ unsafe impl WorldQuery for &T { } fn init_state(world: &mut World) -> ComponentId { - world.init_component::() + world.register_component::() } fn get_state(components: &Components) -> Option { @@ -1387,7 +1387,7 @@ unsafe impl<'__w, T: Component> WorldQuery for Ref<'__w, T> { } fn init_state(world: &mut World) -> ComponentId { - world.init_component::() + world.register_component::() } fn get_state(components: &Components) -> Option { @@ -1586,7 +1586,7 @@ unsafe impl<'__w, T: Component> WorldQuery for &'__w mut T { } fn init_state(world: &mut World) -> ComponentId { - world.init_component::() + world.register_component::() } fn get_state(components: &Components) -> Option { @@ -1976,7 +1976,7 @@ unsafe impl WorldQuery for Has { } fn init_state(world: &mut World) -> ComponentId { - world.init_component::() + world.register_component::() } fn get_state(components: &Components) -> Option { diff --git a/crates/bevy_ecs/src/query/filter.rs b/crates/bevy_ecs/src/query/filter.rs index ee447ec99bc42..0c0cffb656948 100644 --- a/crates/bevy_ecs/src/query/filter.rs +++ b/crates/bevy_ecs/src/query/filter.rs @@ -191,7 +191,7 @@ unsafe impl WorldQuery for With { } fn init_state(world: &mut World) -> ComponentId { - world.init_component::() + world.register_component::() } fn get_state(components: &Components) -> Option { @@ -302,7 +302,7 @@ unsafe impl WorldQuery for Without { } fn init_state(world: &mut World) -> ComponentId { - world.init_component::() + world.register_component::() } fn get_state(components: &Components) -> Option { @@ -730,7 +730,7 @@ unsafe impl WorldQuery for Added { } fn init_state(world: &mut World) -> ComponentId { - world.init_component::() + world.register_component::() } fn get_state(components: &Components) -> Option { @@ -948,7 +948,7 @@ unsafe impl WorldQuery for Changed { } fn init_state(world: &mut World) -> ComponentId { - world.init_component::() + world.register_component::() } fn get_state(components: &Components) -> Option { diff --git a/crates/bevy_ecs/src/query/state.rs b/crates/bevy_ecs/src/query/state.rs index 07c0f8bd47239..1049a41934cc5 100644 --- a/crates/bevy_ecs/src/query/state.rs +++ b/crates/bevy_ecs/src/query/state.rs @@ -1866,7 +1866,7 @@ mod tests { #[test] fn can_transmute_empty_tuple() { let mut world = World::new(); - world.init_component::(); + world.register_component::(); let entity = world.spawn(A(10)).id(); let q = world.query::<()>(); @@ -1922,8 +1922,8 @@ mod tests { )] fn cannot_transmute_to_include_data_not_in_original_query() { let mut world = World::new(); - world.init_component::(); - world.init_component::(); + world.register_component::(); + world.register_component::(); world.spawn(A(0)); let query_state = world.query::<&A>(); @@ -1962,7 +1962,7 @@ mod tests { )] fn cannot_transmute_entity_ref() { let mut world = World::new(); - world.init_component::(); + world.register_component::(); let q = world.query::(); let _ = q.transmute::<&A>(&world); @@ -2030,8 +2030,8 @@ mod tests { )] fn cannot_transmute_changed_without_access() { let mut world = World::new(); - world.init_component::(); - world.init_component::(); + world.register_component::(); + world.register_component::(); let query = QueryState::<&A>::new(&mut world); let _new_query = query.transmute_filtered::>(&world); } @@ -2044,7 +2044,7 @@ mod tests { world.spawn((A(1), B(2))); let mut world2 = World::new(); - world2.init_component::(); + world2.register_component::(); world.query::<(&A, &B)>().transmute::<&B>(&world2); } @@ -2134,7 +2134,7 @@ mod tests { (&bevy_ecs::query::state::tests::A, ()) joined with (&bevy_ecs::query::state::tests::B, ()).")] fn cannot_join_wrong_fetch() { let mut world = World::new(); - world.init_component::(); + world.register_component::(); let query_1 = QueryState::<&A>::new(&mut world); let query_2 = QueryState::<&B>::new(&mut world); let _query: QueryState<&C> = query_1.join(&world, &query_2); diff --git a/crates/bevy_ecs/src/schedule/schedule.rs b/crates/bevy_ecs/src/schedule/schedule.rs index f0d7642fa5575..3cb6d6ea02746 100644 --- a/crates/bevy_ecs/src/schedule/schedule.rs +++ b/crates/bevy_ecs/src/schedule/schedule.rs @@ -127,13 +127,13 @@ impl Schedules { /// Ignore system order ambiguities caused by conflicts on [`Component`]s of type `T`. pub fn allow_ambiguous_component(&mut self, world: &mut World) { self.ignored_scheduling_ambiguities - .insert(world.init_component::()); + .insert(world.register_component::()); } /// Ignore system order ambiguities caused by conflicts on [`Resource`]s of type `T`. pub fn allow_ambiguous_resource(&mut self, world: &mut World) { self.ignored_scheduling_ambiguities - .insert(world.components.init_resource::()); + .insert(world.components.register_resource::()); } /// Iterate through the [`ComponentId`]'s that will be ignored. diff --git a/crates/bevy_ecs/src/storage/table/mod.rs b/crates/bevy_ecs/src/storage/table/mod.rs index e15812461769a..a255d1ff71c06 100644 --- a/crates/bevy_ecs/src/storage/table/mod.rs +++ b/crates/bevy_ecs/src/storage/table/mod.rs @@ -831,7 +831,7 @@ mod tests { fn table() { let mut components = Components::default(); let mut storages = Storages::default(); - let component_id = components.init_component::>(&mut storages); + let component_id = components.register_component::>(&mut storages); let columns = &[component_id]; let mut table = TableBuilder::with_capacity(0, columns.len()) .add_column(components.get_info(component_id).unwrap()) diff --git a/crates/bevy_ecs/src/system/mod.rs b/crates/bevy_ecs/src/system/mod.rs index f44116344761a..0da0a8c49de90 100644 --- a/crates/bevy_ecs/src/system/mod.rs +++ b/crates/bevy_ecs/src/system/mod.rs @@ -1445,7 +1445,7 @@ mod tests { let mut world = World::default(); let mut system = IntoSystem::into_system(a_not_b_system); let mut expected_ids = HashSet::::new(); - let a_id = world.init_component::(); + let a_id = world.register_component::(); // set up system and verify its access is empty system.initialize(&mut world); diff --git a/crates/bevy_ecs/src/system/system_param.rs b/crates/bevy_ecs/src/system/system_param.rs index 916fbeb969ef3..cb2730b3382fc 100644 --- a/crates/bevy_ecs/src/system/system_param.rs +++ b/crates/bevy_ecs/src/system/system_param.rs @@ -591,7 +591,7 @@ unsafe impl<'a, T: Resource> SystemParam for Res<'a, T> { type Item<'w, 's> = Res<'w, T>; fn init_state(world: &mut World, system_meta: &mut SystemMeta) -> Self::State { - let component_id = world.components.init_resource::(); + let component_id = world.components.register_resource::(); let archetype_component_id = world.initialize_resource_internal(component_id).id(); let combined_access = system_meta.component_access_set.combined_access(); @@ -698,7 +698,7 @@ unsafe impl<'a, T: Resource> SystemParam for ResMut<'a, T> { type Item<'w, 's> = ResMut<'w, T>; fn init_state(world: &mut World, system_meta: &mut SystemMeta) -> Self::State { - let component_id = world.components.init_resource::(); + let component_id = world.components.register_resource::(); let archetype_component_id = world.initialize_resource_internal(component_id).id(); let combined_access = system_meta.component_access_set.combined_access(); @@ -1248,7 +1248,7 @@ unsafe impl<'a, T: 'static> SystemParam for NonSend<'a, T> { fn init_state(world: &mut World, system_meta: &mut SystemMeta) -> Self::State { system_meta.set_non_send(); - let component_id = world.components.init_non_send::(); + let component_id = world.components.register_non_send::(); let archetype_component_id = world.initialize_non_send_internal(component_id).id(); let combined_access = system_meta.component_access_set.combined_access(); @@ -1352,7 +1352,7 @@ unsafe impl<'a, T: 'static> SystemParam for NonSendMut<'a, T> { fn init_state(world: &mut World, system_meta: &mut SystemMeta) -> Self::State { system_meta.set_non_send(); - let component_id = world.components.init_non_send::(); + let component_id = world.components.register_non_send::(); let archetype_component_id = world.initialize_non_send_internal(component_id).id(); let combined_access = system_meta.component_access_set.combined_access(); diff --git a/crates/bevy_ecs/src/world/entity_ref.rs b/crates/bevy_ecs/src/world/entity_ref.rs index 5477e79c3fdde..157b2a55f18ff 100644 --- a/crates/bevy_ecs/src/world/entity_ref.rs +++ b/crates/bevy_ecs/src/world/entity_ref.rs @@ -955,7 +955,7 @@ impl<'w> EntityWorldMut<'w> { let world = &mut self.world; let storages = &mut world.storages; let components = &mut world.components; - let bundle_id = world.bundles.init_info::(components, storages); + let bundle_id = world.bundles.register_info::(components, storages); // SAFETY: We just ensured this bundle exists let bundle_info = unsafe { world.bundles.get_unchecked(bundle_id) }; let old_location = self.location; @@ -1221,7 +1221,7 @@ impl<'w> EntityWorldMut<'w> { pub fn remove(&mut self) -> &mut Self { let storages = &mut self.world.storages; let components = &mut self.world.components; - let bundle_info = self.world.bundles.init_info::(components, storages); + let bundle_info = self.world.bundles.register_info::(components, storages); // SAFETY: the `BundleInfo` is initialized above self.location = unsafe { self.remove_bundle(bundle_info) }; @@ -1237,7 +1237,7 @@ impl<'w> EntityWorldMut<'w> { let storages = &mut self.world.storages; let components = &mut self.world.components; - let retained_bundle = self.world.bundles.init_info::(components, storages); + let retained_bundle = self.world.bundles.register_info::(components, storages); // SAFETY: `retained_bundle` exists as we just initialized it. let retained_bundle_info = unsafe { self.world.bundles.get_unchecked(retained_bundle) }; let old_location = self.location; @@ -3107,7 +3107,7 @@ mod tests { #[test] fn entity_mut_insert_by_id() { let mut world = World::new(); - let test_component_id = world.init_component::(); + let test_component_id = world.register_component::(); let mut entity = world.spawn_empty(); OwningPtr::make(TestComponent(42), |ptr| { @@ -3135,8 +3135,8 @@ mod tests { #[test] fn entity_mut_insert_bundle_by_id() { let mut world = World::new(); - let test_component_id = world.init_component::(); - let test_component_2_id = world.init_component::(); + let test_component_id = world.register_component::(); + let test_component_2_id = world.register_component::(); let component_ids = [test_component_id, test_component_2_id]; let test_component_value = TestComponent(42); @@ -3175,7 +3175,7 @@ mod tests { #[test] fn entity_mut_remove_by_id() { let mut world = World::new(); - let test_component_id = world.init_component::(); + let test_component_id = world.register_component::(); let mut entity = world.spawn(TestComponent(42)); entity.remove_by_id(test_component_id); @@ -3192,8 +3192,8 @@ mod tests { #[test] fn entity_ref_except() { let mut world = World::new(); - world.init_component::(); - world.init_component::(); + world.register_component::(); + world.register_component::(); world.spawn(TestComponent(0)).insert(TestComponent2(0)); @@ -3458,7 +3458,7 @@ mod tests { #[test] fn filtered_entity_ref_normal() { let mut world = World::new(); - let a_id = world.init_component::(); + let a_id = world.register_component::(); let e: FilteredEntityRef = world.spawn(A).into(); @@ -3472,7 +3472,7 @@ mod tests { #[test] fn filtered_entity_ref_missing() { let mut world = World::new(); - let a_id = world.init_component::(); + let a_id = world.register_component::(); let e: FilteredEntityRef = world.spawn(()).into(); @@ -3486,7 +3486,7 @@ mod tests { #[test] fn filtered_entity_mut_normal() { let mut world = World::new(); - let a_id = world.init_component::(); + let a_id = world.register_component::(); let mut e: FilteredEntityMut = world.spawn(A).into(); @@ -3502,7 +3502,7 @@ mod tests { #[test] fn filtered_entity_mut_missing() { let mut world = World::new(); - let a_id = world.init_component::(); + let a_id = world.register_component::(); let mut e: FilteredEntityMut = world.spawn(()).into(); diff --git a/crates/bevy_ecs/src/world/mod.rs b/crates/bevy_ecs/src/world/mod.rs index 568a70c0dc7e7..094a21af67f82 100644 --- a/crates/bevy_ecs/src/world/mod.rs +++ b/crates/bevy_ecs/src/world/mod.rs @@ -172,10 +172,10 @@ impl World { /// This _must_ be run as part of constructing a [`World`], before it is returned to the caller. #[inline] fn bootstrap(&mut self) { - assert_eq!(ON_ADD, self.init_component::()); - assert_eq!(ON_INSERT, self.init_component::()); - assert_eq!(ON_REPLACE, self.init_component::()); - assert_eq!(ON_REMOVE, self.init_component::()); + assert_eq!(ON_ADD, self.register_component::()); + assert_eq!(ON_INSERT, self.register_component::()); + assert_eq!(ON_REPLACE, self.register_component::()); + assert_eq!(ON_REMOVE, self.register_component::()); } /// Creates a new empty [`World`]. /// @@ -261,17 +261,17 @@ impl World { unsafe { Commands::new_raw_from_entities(self.command_queue.clone(), &self.entities) } } - /// Initializes a new [`Component`] type and returns the [`ComponentId`] created for it. - pub fn init_component(&mut self) -> ComponentId { - self.components.init_component::(&mut self.storages) + /// Registers a new [`Component`] type and returns the [`ComponentId`] created for it. + pub fn register_component(&mut self) -> ComponentId { + self.components.register_component::(&mut self.storages) } /// Returns a mutable reference to the [`ComponentHooks`] for a [`Component`] type. /// /// Will panic if `T` exists in any archetypes. pub fn register_component_hooks(&mut self) -> &mut ComponentHooks { - let index = self.init_component::(); - assert!(!self.archetypes.archetypes.iter().any(|a| a.contains(index)), "Components hooks cannot be modified if the component already exists in an archetype, use init_component if {} may already be in use", std::any::type_name::()); + let index = self.register_component::(); + assert!(!self.archetypes.archetypes.iter().any(|a| a.contains(index)), "Components hooks cannot be modified if the component already exists in an archetype, use register_component if {} may already be in use", std::any::type_name::()); // SAFETY: We just created this component unsafe { self.components.get_hooks_mut(index).debug_checked_unwrap() } } @@ -283,25 +283,25 @@ impl World { &mut self, id: ComponentId, ) -> Option<&mut ComponentHooks> { - assert!(!self.archetypes.archetypes.iter().any(|a| a.contains(id)), "Components hooks cannot be modified if the component already exists in an archetype, use init_component if the component with id {:?} may already be in use", id); + assert!(!self.archetypes.archetypes.iter().any(|a| a.contains(id)), "Components hooks cannot be modified if the component already exists in an archetype, use register_component if the component with id {:?} may already be in use", id); self.components.get_hooks_mut(id) } - /// Initializes a new [`Component`] type and returns the [`ComponentId`] created for it. + /// Registers a new [`Component`] type and returns the [`ComponentId`] created for it. /// - /// This method differs from [`World::init_component`] in that it uses a [`ComponentDescriptor`] - /// to initialize the new component type instead of statically available type information. This - /// enables the dynamic initialization of new component definitions at runtime for advanced use cases. + /// This method differs from [`World::register_component`] in that it uses a [`ComponentDescriptor`] + /// to register the new component type instead of statically available type information. This + /// enables the dynamic registration of new component definitions at runtime for advanced use cases. /// - /// While the option to initialize a component from a descriptor is useful in type-erased - /// contexts, the standard `World::init_component` function should always be used instead + /// While the option to register a component from a descriptor is useful in type-erased + /// contexts, the standard [`World::register_component`] function should always be used instead /// when type information is available at compile time. - pub fn init_component_with_descriptor( + pub fn register_component_with_descriptor( &mut self, descriptor: ComponentDescriptor, ) -> ComponentId { self.components - .init_component_with_descriptor(&mut self.storages, descriptor) + .register_component_with_descriptor(&mut self.storages, descriptor) } /// Returns the [`ComponentId`] of the given [`Component`] type `T`. @@ -310,7 +310,7 @@ impl World { /// it was retrieved from and should not be used with another `World` instance. /// /// Returns [`None`] if the `Component` type has not yet been initialized within - /// the `World` using [`World::init_component`]. + /// the `World` using [`World::register_component`]. /// /// ``` /// use bevy_ecs::prelude::*; @@ -320,7 +320,7 @@ impl World { /// #[derive(Component)] /// struct ComponentA; /// - /// let component_a_id = world.init_component::(); + /// let component_a_id = world.register_component::(); /// /// assert_eq!(component_a_id, world.component_id::().unwrap()) /// ``` @@ -1312,7 +1312,7 @@ impl World { pub fn init_resource(&mut self) -> ComponentId { #[cfg(feature = "track_change_detection")] let caller = Location::caller(); - let component_id = self.components.init_resource::(); + let component_id = self.components.register_resource::(); if self .storages .resources @@ -1358,7 +1358,7 @@ impl World { value: R, #[cfg(feature = "track_change_detection")] caller: &'static Location, ) { - let component_id = self.components.init_resource::(); + let component_id = self.components.register_resource::(); OwningPtr::make(value, |ptr| { // SAFETY: component_id was just initialized and corresponds to resource of type R. unsafe { @@ -1388,7 +1388,7 @@ impl World { pub fn init_non_send_resource(&mut self) -> ComponentId { #[cfg(feature = "track_change_detection")] let caller = Location::caller(); - let component_id = self.components.init_non_send::(); + let component_id = self.components.register_non_send::(); if self .storages .non_send_resources @@ -1425,7 +1425,7 @@ impl World { pub fn insert_non_send_resource(&mut self, value: R) { #[cfg(feature = "track_change_detection")] let caller = Location::caller(); - let component_id = self.components.init_non_send::(); + let component_id = self.components.register_non_send::(); OwningPtr::make(value, |ptr| { // SAFETY: component_id was just initialized and corresponds to resource of type R. unsafe { @@ -1704,7 +1704,7 @@ impl World { let change_tick = self.change_tick(); let last_change_tick = self.last_change_tick(); - let component_id = self.components.init_resource::(); + let component_id = self.components.register_resource::(); let data = self.initialize_resource_internal(component_id); if !data.is_present() { OwningPtr::make(func(), |ptr| { @@ -1861,7 +1861,7 @@ impl World { let bundle_id = self .bundles - .init_info::(&mut self.components, &mut self.storages); + .register_info::(&mut self.components, &mut self.storages); enum SpawnOrInsert<'w> { Spawn(BundleSpawner<'w>), Insert(BundleInserter<'w>, ArchetypeId), @@ -2441,16 +2441,16 @@ impl World { self.storages.non_send_resources.clear(); } - /// Initializes all of the components in the given [`Bundle`] and returns both the component + /// Registers all of the components in the given [`Bundle`] and returns both the component /// ids and the bundle id. /// - /// This is largely equivalent to calling [`init_component`](Self::init_component) on each + /// This is largely equivalent to calling [`register_component`](Self::register_component) on each /// component in the bundle. #[inline] - pub fn init_bundle(&mut self) -> &BundleInfo { + pub fn register_bundle(&mut self) -> &BundleInfo { let id = self .bundles - .init_info::(&mut self.components, &mut self.storages); + .register_info::(&mut self.components, &mut self.storages); // SAFETY: We just initialised the bundle so its id should definitely be valid. unsafe { self.bundles.get(id).debug_checked_unwrap() } } @@ -3246,7 +3246,7 @@ mod tests { ) }; - let component_id = world.init_component_with_descriptor(descriptor); + let component_id = world.register_component_with_descriptor(descriptor); let value: [u8; 8] = [0, 1, 2, 3, 4, 5, 6, 7]; OwningPtr::make(value, |ptr| { diff --git a/examples/ecs/dynamic.rs b/examples/ecs/dynamic.rs index fe1523dd5bd21..7cec3a47fdd89 100644 --- a/examples/ecs/dynamic.rs +++ b/examples/ecs/dynamic.rs @@ -85,7 +85,7 @@ fn main() { }; // Register our new component to the world with a layout specified by it's size // SAFETY: [u64] is Send + Sync - let id = world.init_component_with_descriptor(unsafe { + let id = world.register_component_with_descriptor(unsafe { ComponentDescriptor::new_with_layout( name.to_string(), StorageType::Table, From 0fe33c3bbaf58ce89d85e97092fc45438d2da4ff Mon Sep 17 00:00:00 2001 From: ickshonpe Date: Fri, 27 Sep 2024 00:10:35 +0100 Subject: [PATCH 06/17] use precomputed border values (#15163) # Objective Fixes #15142 ## Solution * Moved all the UI border geometry calculations that were scattered through the UI extraction functions into `ui_layout_system`. * Added a `border: BorderRect` field to `Node` to store the border size computed by `ui_layout_system`. * Use the border values returned from Taffy rather than calculate them ourselves during extraction. * Removed the `logical_rect` and `physical_rect` methods from `Node` the descriptions and namings are deceptive, it's better to create the rects manually instead. * Added a method `outline_radius` to `Node` that calculates the border radius of outlines. * For border values `ExtractedUiNode` takes `BorderRect` and `ResolvedBorderRadius` now instead of raw `[f32; 4]` values and converts them in `prepare_uinodes`. * Removed some unnecessary scaling and clamping of border values (#15142). * Added a `BorderRect::ZERO` constant. * Added an `outlined_node_size` method to `Node`. ## Testing Added some non-uniform borders to the border example. Everything seems to be in order: nub ## Migration Guide The `logical_rect` and `physical_rect` methods have been removed from `Node`. Use `Rect::from_center_size` with the translation and node size instead. The types of the fields border and border_radius of `ExtractedUiNode` have been changed to `BorderRect` and `ResolvedBorderRadius` respectively. --------- Co-authored-by: UkoeHB <37489173+UkoeHB@users.noreply.github.com> Co-authored-by: akimakinai <105044389+akimakinai@users.noreply.github.com> --- .../src/texture_slice/border_rect.rs | 3 + crates/bevy_ui/src/focus.rs | 5 +- crates/bevy_ui/src/layout/mod.rs | 31 +- crates/bevy_ui/src/picking_backend.rs | 7 +- crates/bevy_ui/src/render/mod.rs | 278 ++++-------------- crates/bevy_ui/src/render/ui.wgsl | 2 +- .../src/render/ui_material_pipeline.rs | 49 +-- crates/bevy_ui/src/ui_node.rs | 117 +++++--- crates/bevy_ui/src/update.rs | 3 +- examples/ui/borders.rs | 12 +- 10 files changed, 186 insertions(+), 321 deletions(-) diff --git a/crates/bevy_sprite/src/texture_slice/border_rect.rs b/crates/bevy_sprite/src/texture_slice/border_rect.rs index e32f2891c1579..fc15b428516a3 100644 --- a/crates/bevy_sprite/src/texture_slice/border_rect.rs +++ b/crates/bevy_sprite/src/texture_slice/border_rect.rs @@ -14,6 +14,9 @@ pub struct BorderRect { } impl BorderRect { + /// An empty border with zero padding values in each direction + pub const ZERO: Self = Self::square(0.); + /// Creates a new border as a square, with identical pixel padding values on every direction #[must_use] #[inline] diff --git a/crates/bevy_ui/src/focus.rs b/crates/bevy_ui/src/focus.rs index 59f75f1b3c3a2..9e67d4d6f97ff 100644 --- a/crates/bevy_ui/src/focus.rs +++ b/crates/bevy_ui/src/focus.rs @@ -243,7 +243,10 @@ pub fn ui_focus_system( .map(TargetCamera::entity) .or(default_ui_camera.get())?; - let node_rect = node.node.logical_rect(node.global_transform); + let node_rect = Rect::from_center_size( + node.global_transform.translation().truncate(), + node.node.size(), + ); // Intersect with the calculated clip rect to find the bounds of the visible region of the node let visible_rect = node diff --git a/crates/bevy_ui/src/layout/mod.rs b/crates/bevy_ui/src/layout/mod.rs index 5399e9a124c31..233ccd7186bea 100644 --- a/crates/bevy_ui/src/layout/mod.rs +++ b/crates/bevy_ui/src/layout/mod.rs @@ -1,6 +1,6 @@ use crate::{ - BorderRadius, ContentSize, DefaultUiCamera, Node, Outline, OverflowAxis, ScrollPosition, Style, - TargetCamera, UiScale, + BorderRadius, ContentSize, DefaultUiCamera, Display, Node, Outline, OverflowAxis, + ScrollPosition, Style, TargetCamera, UiScale, }; use bevy_ecs::{ change_detection::{DetectChanges, DetectChangesMut}, @@ -14,6 +14,7 @@ use bevy_ecs::{ use bevy_hierarchy::{Children, Parent}; use bevy_math::{UVec2, Vec2}; use bevy_render::camera::{Camera, NormalizedRenderTarget}; +use bevy_sprite::BorderRect; #[cfg(feature = "bevy_text")] use bevy_text::{CosmicBuffer, TextPipeline}; use bevy_transform::components::Transform; @@ -344,6 +345,13 @@ pub fn ui_layout_system( node.unrounded_size = layout_size; } + node.bypass_change_detection().border = BorderRect { + left: layout.border.left * inverse_target_scale_factor, + right: layout.border.right * inverse_target_scale_factor, + top: layout.border.top * inverse_target_scale_factor, + bottom: layout.border.bottom * inverse_target_scale_factor, + }; + let viewport_size = root_size.unwrap_or(node.calculated_size); if let Some(border_radius) = maybe_border_radius { @@ -355,11 +363,15 @@ pub fn ui_layout_system( if let Some(outline) = maybe_outline { // don't trigger change detection when only outlines are changed let node = node.bypass_change_detection(); - node.outline_width = outline - .width - .resolve(node.size().x, viewport_size) - .unwrap_or(0.) - .max(0.); + node.outline_width = if style.display != Display::None { + outline + .width + .resolve(node.size().x, viewport_size) + .unwrap_or(0.) + .max(0.) + } else { + 0. + }; node.outline_offset = outline .offset @@ -834,7 +846,10 @@ mod tests { .fold( Option::<(Rect, bool)>::None, |option_rect, (entity, node, global_transform)| { - let current_rect = node.logical_rect(global_transform); + let current_rect = Rect::from_center_size( + global_transform.translation().truncate(), + node.size(), + ); assert!( current_rect.height().abs() + current_rect.width().abs() > 0., "root ui node {entity:?} doesn't have a logical size" diff --git a/crates/bevy_ui/src/picking_backend.rs b/crates/bevy_ui/src/picking_backend.rs index e88409f27c8bf..bb57537145725 100644 --- a/crates/bevy_ui/src/picking_backend.rs +++ b/crates/bevy_ui/src/picking_backend.rs @@ -26,7 +26,7 @@ use crate::{focus::pick_rounded_rect, prelude::*, UiStack}; use bevy_app::prelude::*; use bevy_ecs::{prelude::*, query::QueryData}; -use bevy_math::Vec2; +use bevy_math::{Rect, Vec2}; use bevy_render::prelude::*; use bevy_transform::prelude::*; use bevy_utils::hashbrown::HashMap; @@ -139,7 +139,10 @@ pub fn ui_picking( continue; }; - let node_rect = node.node.logical_rect(node.global_transform); + let node_rect = Rect::from_center_size( + node.global_transform.translation().truncate(), + node.node.size(), + ); // Nodes with Display::None have a (0., 0.) logical rect and can be ignored if node_rect.size() == Vec2::ZERO { diff --git a/crates/bevy_ui/src/render/mod.rs b/crates/bevy_ui/src/render/mod.rs index 3160e65aed14d..c3c7fbc8daa28 100644 --- a/crates/bevy_ui/src/render/mod.rs +++ b/crates/bevy_ui/src/render/mod.rs @@ -3,43 +3,21 @@ mod render_pass; mod ui_material_pipeline; pub mod ui_texture_slice_pipeline; -use bevy_color::{Alpha, ColorToComponents, LinearRgba}; -use bevy_core_pipeline::{ - core_2d::{ - graph::{Core2d, Node2d}, - Camera2d, - }, - core_3d::{ - graph::{Core3d, Node3d}, - Camera3d, - }, -}; -use bevy_hierarchy::Parent; -use bevy_render::{ - render_phase::{PhaseItem, PhaseItemExtraIndex, ViewSortedRenderPhases}, - texture::{GpuImage, TRANSPARENT_IMAGE_HANDLE}, - view::ViewVisibility, - ExtractSchedule, Render, -}; -use bevy_sprite::{ImageScaleMode, SpriteAssetEvents, TextureAtlas}; -pub use pipeline::*; -pub use render_pass::*; -pub use ui_material_pipeline::*; -use ui_texture_slice_pipeline::UiTextureSlicerPlugin; - use crate::{ - graph::{NodeUi, SubGraphUi}, - BackgroundColor, BorderColor, CalculatedClip, DefaultUiCamera, Display, Node, Outline, Style, - TargetCamera, UiAntiAlias, UiImage, UiScale, Val, + BackgroundColor, BorderColor, CalculatedClip, DefaultUiCamera, Node, Outline, + ResolvedBorderRadius, TargetCamera, UiAntiAlias, UiImage, UiScale, }; - use bevy_app::prelude::*; use bevy_asset::{load_internal_asset, AssetEvent, AssetId, Assets, Handle}; -use bevy_ecs::{ - entity::{EntityHashMap, EntityHashSet}, - prelude::*, -}; -use bevy_math::{FloatOrd, Mat4, Rect, URect, UVec4, Vec2, Vec3, Vec3Swizzles, Vec4, Vec4Swizzles}; +use bevy_color::{Alpha, ColorToComponents, LinearRgba}; +use bevy_core_pipeline::core_2d::graph::{Core2d, Node2d}; +use bevy_core_pipeline::core_3d::graph::{Core3d, Node3d}; +use bevy_core_pipeline::{core_2d::Camera2d, core_3d::Camera3d}; +use bevy_ecs::entity::{EntityHashMap, EntityHashSet}; +use bevy_ecs::prelude::*; +use bevy_math::{FloatOrd, Mat4, Rect, URect, UVec4, Vec2, Vec3, Vec3Swizzles, Vec4Swizzles}; +use bevy_render::render_phase::ViewSortedRenderPhases; +use bevy_render::texture::TRANSPARENT_IMAGE_HANDLE; use bevy_render::{ camera::Camera, render_asset::RenderAssets, @@ -51,13 +29,25 @@ use bevy_render::{ view::{ExtractedView, ViewUniforms}, Extract, RenderApp, RenderSet, }; +use bevy_render::{ + render_phase::{PhaseItem, PhaseItemExtraIndex}, + texture::GpuImage, + view::ViewVisibility, + ExtractSchedule, Render, +}; use bevy_sprite::TextureAtlasLayout; +use bevy_sprite::{BorderRect, ImageScaleMode, SpriteAssetEvents, TextureAtlas}; #[cfg(feature = "bevy_text")] use bevy_text::{PositionedGlyph, Text, TextLayoutInfo}; use bevy_transform::components::GlobalTransform; use bevy_utils::HashMap; use bytemuck::{Pod, Zeroable}; +use graph::{NodeUi, SubGraphUi}; +pub use pipeline::*; +pub use render_pass::*; use std::ops::Range; +pub use ui_material_pipeline::*; +use ui_texture_slice_pipeline::UiTextureSlicerPlugin; pub mod graph { use bevy_render::render_graph::{RenderLabel, RenderSubGraph}; @@ -183,11 +173,9 @@ pub struct ExtractedUiNode { // Nodes with ambiguous camera will be ignored. pub camera_entity: Entity, /// Border radius of the UI node. - /// Ordering: top left, top right, bottom right, bottom left. - pub border_radius: [f32; 4], + pub border_radius: ResolvedBorderRadius, /// Border thickness of the UI node. - /// Ordering: left, top, right, bottom. - pub border: [f32; 4], + pub border: BorderRect, pub node_type: NodeType, } @@ -198,9 +186,7 @@ pub struct ExtractedUiNodes { pub fn extract_uinode_background_colors( mut extracted_uinodes: ResMut, - camera_query: Extract>, default_ui_camera: Extract, - ui_scale: Extract>, uinode_query: Extract< Query<( Entity, @@ -210,23 +196,11 @@ pub fn extract_uinode_background_colors( Option<&CalculatedClip>, Option<&TargetCamera>, &BackgroundColor, - &Style, - Option<&Parent>, )>, >, - node_query: Extract>, ) { - for ( - entity, - uinode, - transform, - view_visibility, - clip, - camera, - background_color, - style, - parent, - ) in &uinode_query + for (entity, uinode, transform, view_visibility, clip, camera, background_color) in + &uinode_query { let Some(camera_entity) = camera.map(TargetCamera::entity).or(default_ui_camera.get()) else { @@ -238,39 +212,6 @@ pub fn extract_uinode_background_colors( continue; } - let ui_logical_viewport_size = camera_query - .get(camera_entity) - .ok() - .and_then(|(_, c)| c.logical_viewport_size()) - .unwrap_or(Vec2::ZERO) - // The logical window resolution returned by `Window` only takes into account the window scale factor and not `UiScale`, - // so we have to divide by `UiScale` to get the size of the UI viewport. - / ui_scale.0; - - // Both vertical and horizontal percentage border values are calculated based on the width of the parent node - // - let parent_width = parent - .and_then(|parent| node_query.get(parent.get()).ok()) - .map(|parent_node| parent_node.size().x) - .unwrap_or(ui_logical_viewport_size.x); - let left = - resolve_border_thickness(style.border.left, parent_width, ui_logical_viewport_size); - let right = - resolve_border_thickness(style.border.right, parent_width, ui_logical_viewport_size); - let top = - resolve_border_thickness(style.border.top, parent_width, ui_logical_viewport_size); - let bottom = - resolve_border_thickness(style.border.bottom, parent_width, ui_logical_viewport_size); - - let border = [left, top, right, bottom]; - - let border_radius = [ - uinode.border_radius.top_left, - uinode.border_radius.top_right, - uinode.border_radius.bottom_right, - uinode.border_radius.bottom_left, - ]; - extracted_uinodes.uinodes.insert( entity, ExtractedUiNode { @@ -287,8 +228,8 @@ pub fn extract_uinode_background_colors( flip_x: false, flip_y: false, camera_entity, - border, - border_radius, + border: uinode.border(), + border_radius: uinode.border_radius(), node_type: NodeType::Rect, }, ); @@ -299,9 +240,7 @@ pub fn extract_uinode_background_colors( pub fn extract_uinode_images( mut commands: Commands, mut extracted_uinodes: ResMut, - camera_query: Extract>, texture_atlases: Extract>>, - ui_scale: Extract>, default_ui_camera: Extract, uinode_query: Extract< Query< @@ -313,17 +252,12 @@ pub fn extract_uinode_images( Option<&TargetCamera>, &UiImage, Option<&TextureAtlas>, - Option<&Parent>, - &Style, ), Without, >, >, - node_query: Extract>, ) { - for (uinode, transform, view_visibility, clip, camera, image, atlas, parent, style) in - &uinode_query - { + for (uinode, transform, view_visibility, clip, camera, image, atlas) in &uinode_query { let Some(camera_entity) = camera.map(TargetCamera::entity).or(default_ui_camera.get()) else { continue; @@ -364,39 +298,6 @@ pub fn extract_uinode_images( None }; - let ui_logical_viewport_size = camera_query - .get(camera_entity) - .ok() - .and_then(|(_, c)| c.logical_viewport_size()) - .unwrap_or(Vec2::ZERO) - // The logical window resolution returned by `Window` only takes into account the window scale factor and not `UiScale`, - // so we have to divide by `UiScale` to get the size of the UI viewport. - / ui_scale.0; - - // Both vertical and horizontal percentage border values are calculated based on the width of the parent node - // - let parent_width = parent - .and_then(|parent| node_query.get(parent.get()).ok()) - .map(|parent_node| parent_node.size().x) - .unwrap_or(ui_logical_viewport_size.x); - let left = - resolve_border_thickness(style.border.left, parent_width, ui_logical_viewport_size); - let right = - resolve_border_thickness(style.border.right, parent_width, ui_logical_viewport_size); - let top = - resolve_border_thickness(style.border.top, parent_width, ui_logical_viewport_size); - let bottom = - resolve_border_thickness(style.border.bottom, parent_width, ui_logical_viewport_size); - - let border = [left, top, right, bottom]; - - let border_radius = [ - uinode.border_radius.top_left, - uinode.border_radius.top_right, - uinode.border_radius.bottom_right, - uinode.border_radius.bottom_left, - ]; - extracted_uinodes.uinodes.insert( commands.spawn_empty().id(), ExtractedUiNode { @@ -410,54 +311,18 @@ pub fn extract_uinode_images( flip_x: image.flip_x, flip_y: image.flip_y, camera_entity, - border, - border_radius, + border: uinode.border, + border_radius: uinode.border_radius, node_type: NodeType::Rect, }, ); } } -pub(crate) fn resolve_border_thickness(value: Val, parent_width: f32, viewport_size: Vec2) -> f32 { - match value { - Val::Auto => 0., - Val::Px(px) => px.max(0.), - Val::Percent(percent) => (parent_width * percent / 100.).max(0.), - Val::Vw(percent) => (viewport_size.x * percent / 100.).max(0.), - Val::Vh(percent) => (viewport_size.y * percent / 100.).max(0.), - Val::VMin(percent) => (viewport_size.min_element() * percent / 100.).max(0.), - Val::VMax(percent) => (viewport_size.max_element() * percent / 100.).max(0.), - } -} - -#[inline] -fn clamp_corner(r: f32, size: Vec2, offset: Vec2) -> f32 { - let s = 0.5 * size + offset; - let sm = s.x.min(s.y); - r.min(sm) -} - -#[inline] -fn clamp_radius( - [top_left, top_right, bottom_right, bottom_left]: [f32; 4], - size: Vec2, - border: Vec4, -) -> [f32; 4] { - let s = size - border.xy() - border.zw(); - [ - clamp_corner(top_left, s, border.xy()), - clamp_corner(top_right, s, border.zy()), - clamp_corner(bottom_right, s, border.zw()), - clamp_corner(bottom_left, s, border.xw()), - ] -} - pub fn extract_uinode_borders( mut commands: Commands, mut extracted_uinodes: ResMut, - camera_query: Extract>, default_ui_camera: Extract, - ui_scale: Extract>, uinode_query: Extract< Query<( &Node, @@ -465,12 +330,9 @@ pub fn extract_uinode_borders( &ViewVisibility, Option<&CalculatedClip>, Option<&TargetCamera>, - Option<&Parent>, - &Style, AnyOf<(&BorderColor, &Outline)>, )>, >, - node_query: Extract>, ) { let image = AssetId::::default(); @@ -480,8 +342,6 @@ pub fn extract_uinode_borders( view_visibility, maybe_clip, maybe_camera, - maybe_parent, - style, (maybe_border_color, maybe_outline), ) in &uinode_query { @@ -494,50 +354,14 @@ pub fn extract_uinode_borders( // Skip invisible borders if !view_visibility.get() - || style.display == Display::None || maybe_border_color.is_some_and(|border_color| border_color.0.is_fully_transparent()) && maybe_outline.is_some_and(|outline| outline.color.is_fully_transparent()) { continue; } - let ui_logical_viewport_size = camera_query - .get(camera_entity) - .ok() - .and_then(|(_, c)| c.logical_viewport_size()) - .unwrap_or(Vec2::ZERO) - // The logical window resolution returned by `Window` only takes into account the window scale factor and not `UiScale`, - // so we have to divide by `UiScale` to get the size of the UI viewport. - / ui_scale.0; - - // Both vertical and horizontal percentage border values are calculated based on the width of the parent node - // - let parent_width = maybe_parent - .and_then(|parent| node_query.get(parent.get()).ok()) - .map(|parent_node| parent_node.size().x) - .unwrap_or(ui_logical_viewport_size.x); - let left = - resolve_border_thickness(style.border.left, parent_width, ui_logical_viewport_size); - let right = - resolve_border_thickness(style.border.right, parent_width, ui_logical_viewport_size); - let top = - resolve_border_thickness(style.border.top, parent_width, ui_logical_viewport_size); - let bottom = - resolve_border_thickness(style.border.bottom, parent_width, ui_logical_viewport_size); - - let border = [left, top, right, bottom]; - - let border_radius = [ - uinode.border_radius.top_left, - uinode.border_radius.top_right, - uinode.border_radius.bottom_right, - uinode.border_radius.bottom_left, - ]; - - let border_radius = clamp_radius(border_radius, uinode.size(), border.into()); - // don't extract border if no border or the node is zero-sized (a zero sized node can still have an outline). - if !uinode.is_empty() && border != [0.; 4] { + if !uinode.is_empty() && uinode.border() != BorderRect::ZERO { if let Some(border_color) = maybe_border_color { extracted_uinodes.uinodes.insert( commands.spawn_empty().id(), @@ -555,8 +379,8 @@ pub fn extract_uinode_borders( flip_x: false, flip_y: false, camera_entity, - border_radius, - border, + border_radius: uinode.border_radius(), + border: uinode.border(), node_type: NodeType::Border, }, ); @@ -564,15 +388,7 @@ pub fn extract_uinode_borders( } if let Some(outline) = maybe_outline { - let outer_distance = uinode.outline_offset() + uinode.outline_width(); - let outline_radius = border_radius.map(|radius| { - if radius > 0. { - radius + outer_distance - } else { - 0. - } - }); - let outline_size = uinode.size() + 2. * outer_distance; + let outline_size = uinode.outlined_node_size(); extracted_uinodes.uinodes.insert( commands.spawn_empty().id(), ExtractedUiNode { @@ -589,8 +405,8 @@ pub fn extract_uinode_borders( flip_x: false, flip_y: false, camera_entity, - border: [uinode.outline_width(); 4], - border_radius: outline_radius, + border: BorderRect::square(uinode.outline_width()), + border_radius: uinode.outline_radius(), node_type: NodeType::Border, }, ); @@ -775,8 +591,8 @@ pub fn extract_uinode_text( flip_x: false, flip_y: false, camera_entity, - border: [0.; 4], - border_radius: [0.; 4], + border: BorderRect::ZERO, + border_radius: ResolvedBorderRadius::ZERO, node_type: NodeType::Rect, }, ); @@ -1130,8 +946,18 @@ pub fn prepare_uinodes( uv: uvs[i].into(), color, flags: flags | shader_flags::CORNERS[i], - radius: extracted_uinode.border_radius, - border: extracted_uinode.border, + radius: [ + extracted_uinode.border_radius.top_left, + extracted_uinode.border_radius.top_right, + extracted_uinode.border_radius.bottom_right, + extracted_uinode.border_radius.bottom_left, + ], + border: [ + extracted_uinode.border.left, + extracted_uinode.border.top, + extracted_uinode.border.right, + extracted_uinode.border.bottom, + ], size: rect_size.xy().into(), }); } diff --git a/crates/bevy_ui/src/render/ui.wgsl b/crates/bevy_ui/src/render/ui.wgsl index ad82783d7fc53..c46e0b4926279 100644 --- a/crates/bevy_ui/src/render/ui.wgsl +++ b/crates/bevy_ui/src/render/ui.wgsl @@ -184,7 +184,7 @@ fn fragment(in: VertexOutput) -> @location(0) vec4 { let texture_color = textureSample(sprite_texture, sprite_sampler, in.uv); if enabled(in.flags, BORDER) { - return draw(in, texture_color); + return draw(in, texture_color); } else { return draw_background(in, texture_color); } diff --git a/crates/bevy_ui/src/render/ui_material_pipeline.rs b/crates/bevy_ui/src/render/ui_material_pipeline.rs index aa814cf081fc0..b8b3d7395fbbd 100644 --- a/crates/bevy_ui/src/render/ui_material_pipeline.rs +++ b/crates/bevy_ui/src/render/ui_material_pipeline.rs @@ -10,7 +10,6 @@ use bevy_ecs::{ *, }, }; -use bevy_hierarchy::Parent; use bevy_math::{FloatOrd, Mat4, Rect, Vec2, Vec4Swizzles}; use bevy_render::{ extract_component::ExtractComponentPlugin, @@ -24,7 +23,6 @@ use bevy_render::{ Extract, ExtractSchedule, Render, RenderSet, }; use bevy_transform::prelude::GlobalTransform; -use bevy_window::{PrimaryWindow, Window}; use bytemuck::{Pod, Zeroable}; use crate::*; @@ -355,7 +353,6 @@ impl Default for ExtractedUiMaterialNodes { } } -#[allow(clippy::too_many_arguments)] pub fn extract_ui_material_nodes( mut extracted_uinodes: ResMut>, materials: Extract>>, @@ -365,35 +362,20 @@ pub fn extract_ui_material_nodes( ( Entity, &Node, - &Style, &GlobalTransform, &Handle, &ViewVisibility, Option<&CalculatedClip>, Option<&TargetCamera>, - Option<&Parent>, ), Without, >, >, - windows: Extract>>, - ui_scale: Extract>, - node_query: Extract>, ) { - let ui_logical_viewport_size = windows - .get_single() - .map(Window::size) - .unwrap_or(Vec2::ZERO) - // The logical window resolution returned by `Window` only takes into account the window scale factor and not `UiScale`, - // so we have to divide by `UiScale` to get the size of the UI viewport. - / ui_scale.0; - // If there is only one camera, we use it as default let default_single_camera = default_ui_camera.get(); - for (entity, uinode, style, transform, handle, view_visibility, clip, camera, maybe_parent) in - uinode_query.iter() - { + for (entity, uinode, transform, handle, view_visibility, clip, camera) in uinode_query.iter() { let Some(camera_entity) = camera.map(TargetCamera::entity).or(default_single_camera) else { continue; }; @@ -408,25 +390,12 @@ pub fn extract_ui_material_nodes( continue; } - // Both vertical and horizontal percentage border values are calculated based on the width of the parent node - // - let parent_width = maybe_parent - .and_then(|parent| node_query.get(parent.get()).ok()) - .map(|parent_node| parent_node.size().x) - .unwrap_or(ui_logical_viewport_size.x); - - let left = - resolve_border_thickness(style.border.left, parent_width, ui_logical_viewport_size) - / uinode.size().x; - let right = - resolve_border_thickness(style.border.right, parent_width, ui_logical_viewport_size) - / uinode.size().x; - let top = - resolve_border_thickness(style.border.top, parent_width, ui_logical_viewport_size) - / uinode.size().y; - let bottom = - resolve_border_thickness(style.border.bottom, parent_width, ui_logical_viewport_size) - / uinode.size().y; + let border = [ + uinode.border.left / uinode.size().x, + uinode.border.right / uinode.size().x, + uinode.border.top / uinode.size().y, + uinode.border.bottom / uinode.size().y, + ]; extracted_uinodes.uinodes.insert( entity, @@ -436,9 +405,9 @@ pub fn extract_ui_material_nodes( material: handle.id(), rect: Rect { min: Vec2::ZERO, - max: uinode.calculated_size, + max: uinode.size(), }, - border: [left, right, top, bottom], + border, clip: clip.map(|clip| clip.clip), camera_entity, }, diff --git a/crates/bevy_ui/src/ui_node.rs b/crates/bevy_ui/src/ui_node.rs index b5489b4543d1e..358e955f0e796 100644 --- a/crates/bevy_ui/src/ui_node.rs +++ b/crates/bevy_ui/src/ui_node.rs @@ -2,13 +2,13 @@ use crate::{UiRect, Val}; use bevy_asset::Handle; use bevy_color::Color; use bevy_ecs::{prelude::*, system::SystemParam}; -use bevy_math::{Rect, Vec2}; +use bevy_math::{vec4, Rect, Vec2, Vec4Swizzles}; use bevy_reflect::prelude::*; use bevy_render::{ camera::{Camera, RenderTarget}, texture::{Image, TRANSPARENT_IMAGE_HANDLE}, }; -use bevy_transform::prelude::GlobalTransform; +use bevy_sprite::BorderRect; use bevy_utils::warn_once; use bevy_window::{PrimaryWindow, WindowRef}; use smallvec::SmallVec; @@ -48,6 +48,11 @@ pub struct Node { /// /// Automatically calculated by [`super::layout::ui_layout_system`]. pub(crate) unrounded_size: Vec2, + /// Resolved border values in logical pixels + /// Border updates bypass change detection. + /// + /// Automatically calculated by [`super::layout::ui_layout_system`]. + pub(crate) border: BorderRect, /// Resolved border radius values in logical pixels. /// Border radius updates bypass change detection. /// @@ -72,6 +77,8 @@ impl Node { /// The order of the node in the UI layout. /// Nodes with a higher stack index are drawn on top of and receive interactions before nodes with lower stack indices. + /// + /// Automatically calculated by [`super::layout::ui_layout_system`]. pub const fn stack_index(&self) -> u32 { self.stack_index } @@ -83,53 +90,90 @@ impl Node { self.unrounded_size } - /// Returns the size of the node in physical pixels based on the given scale factor and `UiScale`. + /// Returns the thickness of the UI node's outline in logical pixels. + /// If this value is negative or `0.` then no outline will be rendered. + /// + /// Automatically calculated by [`super::layout::ui_layout_system`]. #[inline] - pub fn physical_size(&self, scale_factor: f32, ui_scale: f32) -> Vec2 { - Vec2::new( - self.calculated_size.x * scale_factor * ui_scale, - self.calculated_size.y * scale_factor * ui_scale, - ) + pub fn outline_width(&self) -> f32 { + self.outline_width } - /// Returns the logical pixel coordinates of the UI node, based on its [`GlobalTransform`]. + /// Returns the amount of space between the outline and the edge of the node in logical pixels. + /// + /// Automatically calculated by [`super::layout::ui_layout_system`]. #[inline] - pub fn logical_rect(&self, transform: &GlobalTransform) -> Rect { - Rect::from_center_size(transform.translation().truncate(), self.size()) + pub fn outline_offset(&self) -> f32 { + self.outline_offset } - /// Returns the physical pixel coordinates of the UI node, based on its [`GlobalTransform`] and the scale factor. + /// Returns the size of the node when including its outline. + /// + /// Automatically calculated by [`super::layout::ui_layout_system`]. #[inline] - pub fn physical_rect( - &self, - transform: &GlobalTransform, - scale_factor: f32, - ui_scale: f32, - ) -> Rect { - let rect = self.logical_rect(transform); - Rect { - min: Vec2::new( - rect.min.x * scale_factor * ui_scale, - rect.min.y * scale_factor * ui_scale, - ), - max: Vec2::new( - rect.max.x * scale_factor * ui_scale, - rect.max.y * scale_factor * ui_scale, - ), + pub fn outlined_node_size(&self) -> Vec2 { + self.size() + 2. * (self.outline_offset + self.outline_width) + } + + /// Returns the border radius for each corner of the outline + /// An outline's border radius is derived from the node's border-radius + /// so that the outline wraps the border equally at all points. + /// + /// Automatically calculated by [`super::layout::ui_layout_system`]. + #[inline] + pub fn outline_radius(&self) -> ResolvedBorderRadius { + let outer_distance = self.outline_width + self.outline_offset; + let compute_radius = |radius| { + if radius > 0. { + radius + outer_distance + } else { + 0. + } + }; + ResolvedBorderRadius { + top_left: compute_radius(self.border_radius.top_left), + top_right: compute_radius(self.border_radius.top_right), + bottom_left: compute_radius(self.border_radius.bottom_left), + bottom_right: compute_radius(self.border_radius.bottom_right), } } + /// Returns the thickness of the node's border on each edge in logical pixels. + /// + /// Automatically calculated by [`super::layout::ui_layout_system`]. #[inline] - /// Returns the thickness of the UI node's outline in logical pixels. - /// If this value is negative or `0.` then no outline will be rendered. - pub fn outline_width(&self) -> f32 { - self.outline_width + pub fn border(&self) -> BorderRect { + self.border } + /// Returns the border radius for each of the node's corners in logical pixels. + /// + /// Automatically calculated by [`super::layout::ui_layout_system`]. #[inline] - /// Returns the amount of space between the outline and the edge of the node in logical pixels. - pub fn outline_offset(&self) -> f32 { - self.outline_offset + pub fn border_radius(&self) -> ResolvedBorderRadius { + self.border_radius + } + + /// Returns the inner border radius for each of the node's corners in logical pixels. + pub fn inner_radius(&self) -> ResolvedBorderRadius { + fn clamp_corner(r: f32, size: Vec2, offset: Vec2) -> f32 { + let s = 0.5 * size + offset; + let sm = s.x.min(s.y); + r.min(sm) + } + let b = vec4( + self.border.left, + self.border.top, + self.border.right, + self.border.bottom, + ); + let s = self.size() - b.xy() - b.zw(); + ResolvedBorderRadius { + top_left: clamp_corner(self.border_radius.top_left, s, b.xy()), + top_right: clamp_corner(self.border_radius.top_right, s, b.zy()), + bottom_left: clamp_corner(self.border_radius.bottom_right, s, b.zw()), + bottom_right: clamp_corner(self.border_radius.bottom_left, s, b.xw()), + } } } @@ -141,6 +185,7 @@ impl Node { outline_offset: 0., unrounded_size: Vec2::ZERO, border_radius: ResolvedBorderRadius::ZERO, + border: BorderRect::ZERO, }; } @@ -2316,7 +2361,7 @@ impl BorderRadius { /// Represents the resolved border radius values for a UI node. /// /// The values are in logical pixels. -#[derive(Copy, Clone, Debug, PartialEq, Reflect)] +#[derive(Copy, Clone, Debug, Default, PartialEq, Reflect)] pub struct ResolvedBorderRadius { pub top_left: f32, pub top_right: f32, diff --git a/crates/bevy_ui/src/update.rs b/crates/bevy_ui/src/update.rs index e93e8214b97c8..d0448388ab934 100644 --- a/crates/bevy_ui/src/update.rs +++ b/crates/bevy_ui/src/update.rs @@ -80,7 +80,8 @@ fn update_clipping( // current node's clip and the inherited clip. This handles the case // of nested `Overflow::Hidden` nodes. If parent `clip` is not // defined, use the current node's clip. - let mut node_rect = node.logical_rect(global_transform); + let mut node_rect = + Rect::from_center_size(global_transform.translation().truncate(), node.size()); if style.overflow.x == OverflowAxis::Visible { node_rect.min.x = -f32::INFINITY; node_rect.max.x = f32::INFINITY; diff --git a/examples/ui/borders.rs b/examples/ui/borders.rs index e7bda08ddc0e1..c306a9f59460b 100644 --- a/examples/ui/borders.rs +++ b/examples/ui/borders.rs @@ -77,17 +77,17 @@ fn setup(mut commands: Commands) { UiRect::horizontal(Val::Px(10.)), UiRect::vertical(Val::Px(10.)), UiRect { - left: Val::Px(10.), + left: Val::Px(20.), top: Val::Px(10.), ..Default::default() }, UiRect { left: Val::Px(10.), - bottom: Val::Px(10.), + bottom: Val::Px(20.), ..Default::default() }, UiRect { - right: Val::Px(10.), + right: Val::Px(20.), top: Val::Px(10.), ..Default::default() }, @@ -98,7 +98,7 @@ fn setup(mut commands: Commands) { }, UiRect { right: Val::Px(10.), - top: Val::Px(10.), + top: Val::Px(20.), bottom: Val::Px(10.), ..Default::default() }, @@ -109,7 +109,7 @@ fn setup(mut commands: Commands) { ..Default::default() }, UiRect { - left: Val::Px(10.), + left: Val::Px(20.), right: Val::Px(10.), top: Val::Px(10.), ..Default::default() @@ -117,7 +117,7 @@ fn setup(mut commands: Commands) { UiRect { left: Val::Px(10.), right: Val::Px(10.), - bottom: Val::Px(10.), + bottom: Val::Px(20.), ..Default::default() }, ]; From 4e7801388c4fc0a5aff918013fc00331acba5bbc Mon Sep 17 00:00:00 2001 From: Mohamed Osama <67656249+moOsama76@users.noreply.github.com> Date: Fri, 27 Sep 2024 03:50:06 +0300 Subject: [PATCH 07/17] Rename UiPickingBackend to UiPickingBackendPlugin (#15462) solves #15450 --- crates/bevy_ui/src/lib.rs | 2 +- crates/bevy_ui/src/picking_backend.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/bevy_ui/src/lib.rs b/crates/bevy_ui/src/lib.rs index 90089f58f4795..9a840ac7d90d4 100644 --- a/crates/bevy_ui/src/lib.rs +++ b/crates/bevy_ui/src/lib.rs @@ -194,7 +194,7 @@ impl Plugin for UiPlugin { build_ui_render(app); #[cfg(feature = "bevy_ui_picking_backend")] - app.add_plugins(picking_backend::UiPickingBackend); + app.add_plugins(picking_backend::UiPickingBackendPlugin); } fn finish(&self, app: &mut App) { diff --git a/crates/bevy_ui/src/picking_backend.rs b/crates/bevy_ui/src/picking_backend.rs index bb57537145725..d66c3f995c15e 100644 --- a/crates/bevy_ui/src/picking_backend.rs +++ b/crates/bevy_ui/src/picking_backend.rs @@ -36,8 +36,8 @@ use bevy_picking::backend::prelude::*; /// A plugin that adds picking support for UI nodes. #[derive(Clone)] -pub struct UiPickingBackend; -impl Plugin for UiPickingBackend { +pub struct UiPickingBackendPlugin; +impl Plugin for UiPickingBackendPlugin { fn build(&self, app: &mut App) { app.add_systems(PreUpdate, ui_picking.in_set(PickSet::Backend)); } From d70595b6674124f4d105a5bd7c029bd0377056c5 Mon Sep 17 00:00:00 2001 From: Zachary Harrold Date: Fri, 27 Sep 2024 10:59:59 +1000 Subject: [PATCH 08/17] Add `core` and `alloc` over `std` Lints (#15281) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Objective - Fixes #6370 - Closes #6581 ## Solution - Added the following lints to the workspace: - `std_instead_of_core` - `std_instead_of_alloc` - `alloc_instead_of_core` - Used `cargo +nightly fmt` with [item level use formatting](https://rust-lang.github.io/rustfmt/?version=v1.6.0&search=#Item%5C%3A) to split all `use` statements into single items. - Used `cargo clippy --workspace --all-targets --all-features --fix --allow-dirty` to _attempt_ to resolve the new linting issues, and intervened where the lint was unable to resolve the issue automatically (usually due to needing an `extern crate alloc;` statement in a crate root). - Manually removed certain uses of `std` where negative feature gating prevented `--all-features` from finding the offending uses. - Used `cargo +nightly fmt` with [crate level use formatting](https://rust-lang.github.io/rustfmt/?version=v1.6.0&search=#Crate%5C%3A) to re-merge all `use` statements matching Bevy's previous styling. - Manually fixed cases where the `fmt` tool could not re-merge `use` statements due to conditional compilation attributes. ## Testing - Ran CI locally ## Migration Guide The MSRV is now 1.81. Please update to this version or higher. ## Notes - This is a _massive_ change to try and push through, which is why I've outlined the semi-automatic steps I used to create this PR, in case this fails and someone else tries again in the future. - Making this change has no impact on user code, but does mean Bevy contributors will be warned to use `core` and `alloc` instead of `std` where possible. - This lint is a critical first step towards investigating `no_std` options for Bevy. --------- Co-authored-by: François Mockers --- Cargo.toml | 44 ++++++++- benches/benches/bevy_ecs/change_detection.rs | 30 +++--- benches/benches/bevy_ecs/components/mod.rs | 16 +-- benches/benches/bevy_ecs/events/iter.rs | 2 +- benches/benches/bevy_ecs/events/mod.rs | 8 +- benches/benches/bevy_ecs/events/send.rs | 2 +- benches/benches/bevy_ecs/fragmentation/mod.rs | 6 +- .../bevy_ecs/iteration/heavy_compute.rs | 4 +- .../benches/bevy_ecs/iteration/iter_simple.rs | 2 +- .../bevy_ecs/iteration/iter_simple_foreach.rs | 2 +- .../iter_simple_foreach_sparse_set.rs | 2 +- .../iteration/iter_simple_foreach_wide.rs | 2 +- .../iter_simple_foreach_wide_sparse_set.rs | 2 +- .../iteration/iter_simple_sparse_set.rs | 2 +- .../bevy_ecs/iteration/iter_simple_system.rs | 2 +- .../bevy_ecs/iteration/iter_simple_wide.rs | 2 +- .../iteration/iter_simple_wide_sparse_set.rs | 2 +- benches/benches/bevy_ecs/iteration/mod.rs | 16 +-- .../bevy_ecs/iteration/par_iter_simple.rs | 2 +- .../benches/bevy_ecs/observers/propagation.rs | 4 +- benches/benches/bevy_ecs/observers/simple.rs | 4 +- .../bevy_ecs/scheduling/run_condition.rs | 16 +-- .../bevy_ecs/scheduling/running_systems.rs | 26 ++--- .../benches/bevy_ecs/scheduling/schedule.rs | 14 +-- benches/benches/bevy_ecs/world/commands.rs | 24 ++--- benches/benches/bevy_ecs/world/entity_hash.rs | 2 +- benches/benches/bevy_ecs/world/spawn.rs | 4 +- benches/benches/bevy_ecs/world/world_get.rs | 30 +++--- benches/benches/bevy_reflect/list.rs | 2 +- benches/benches/bevy_reflect/map.rs | 2 +- benches/benches/bevy_reflect/path.rs | 2 +- benches/benches/bevy_reflect/struct.rs | 2 +- benches/benches/bevy_tasks/iter.rs | 12 +-- crates/bevy_a11y/src/lib.rs | 8 +- crates/bevy_animation/src/graph.rs | 6 +- crates/bevy_animation/src/keyframes.rs | 2 +- crates/bevy_animation/src/lib.rs | 6 +- crates/bevy_app/src/app.rs | 22 ++--- crates/bevy_app/src/lib.rs | 2 + crates/bevy_app/src/plugin.rs | 4 +- crates/bevy_app/src/plugin_group.rs | 56 +++++------ crates/bevy_app/src/schedule_runner.rs | 8 +- crates/bevy_app/src/sub_app.rs | 22 ++--- .../bevy_app/src/terminal_ctrl_c_handler.rs | 2 +- crates/bevy_asset/src/assets.rs | 14 +-- crates/bevy_asset/src/event.rs | 4 +- crates/bevy_asset/src/handle.rs | 32 +++--- crates/bevy_asset/src/id.rs | 34 +++---- crates/bevy_asset/src/io/android.rs | 8 +- .../src/io/embedded/embedded_watcher.rs | 2 +- crates/bevy_asset/src/io/embedded/mod.rs | 6 +- crates/bevy_asset/src/io/file/mod.rs | 2 +- .../bevy_asset/src/io/file/sync_file_asset.rs | 15 ++- crates/bevy_asset/src/io/gated.rs | 3 +- crates/bevy_asset/src/io/memory.rs | 11 +-- crates/bevy_asset/src/io/mod.rs | 11 ++- crates/bevy_asset/src/io/processor_gated.rs | 8 +- crates/bevy_asset/src/io/source.rs | 7 +- crates/bevy_asset/src/io/wasm.rs | 5 +- crates/bevy_asset/src/lib.rs | 16 +-- crates/bevy_asset/src/loader.rs | 18 ++-- crates/bevy_asset/src/loader_builders.rs | 3 +- crates/bevy_asset/src/meta.rs | 2 +- crates/bevy_asset/src/path.rs | 12 +-- crates/bevy_asset/src/processor/mod.rs | 19 ++-- crates/bevy_asset/src/processor/process.rs | 14 +-- crates/bevy_asset/src/reflect.rs | 4 +- crates/bevy_asset/src/saver.rs | 10 +- crates/bevy_asset/src/server/info.rs | 24 +++-- crates/bevy_asset/src/server/loaders.rs | 23 ++--- crates/bevy_asset/src/server/mod.rs | 26 ++--- crates/bevy_asset/src/transformer.rs | 6 +- crates/bevy_audio/src/audio_output.rs | 2 +- crates/bevy_audio/src/audio_source.rs | 3 +- crates/bevy_audio/src/lib.rs | 2 + crates/bevy_audio/src/pitch.rs | 4 +- .../bevy_color/crates/gen_tests/src/main.rs | 4 +- crates/bevy_color/src/color_ops.rs | 2 +- crates/bevy_color/src/color_range.rs | 2 +- crates/bevy_color/src/lib.rs | 20 ++-- crates/bevy_color/src/srgba.rs | 2 +- crates/bevy_core/src/lib.rs | 4 +- crates/bevy_core/src/name.rs | 28 +++--- crates/bevy_core/src/serde.rs | 2 +- .../src/auto_exposure/pipeline.rs | 2 +- .../src/auto_exposure/settings.rs | 2 +- crates/bevy_core_pipeline/src/core_2d/mod.rs | 2 +- .../core_3d/main_transmissive_pass_3d_node.rs | 2 +- crates/bevy_core_pipeline/src/core_3d/mod.rs | 2 +- crates/bevy_core_pipeline/src/deferred/mod.rs | 2 +- crates/bevy_core_pipeline/src/prepass/mod.rs | 2 +- .../invalid_attribute_fail.rs | 2 +- .../mismatched_target_type_fail.rs | 2 +- .../missing_attribute_fail.rs | 2 +- .../multiple_attributes_fail.rs | 2 +- .../deref_mut_derive/multiple_fields_pass.rs | 2 +- .../deref_mut_derive/single_field_pass.rs | 2 +- crates/bevy_derive/src/derefs.rs | 4 +- crates/bevy_dev_tools/src/ci_testing/mod.rs | 2 +- .../bevy_dev_tools/src/ci_testing/systems.rs | 2 +- crates/bevy_dev_tools/src/states.rs | 2 +- .../src/ui_debug_overlay/mod.rs | 2 +- crates/bevy_diagnostic/src/diagnostic.rs | 11 +-- crates/bevy_diagnostic/src/lib.rs | 2 + crates/bevy_ecs/examples/change_detection.rs | 2 + crates/bevy_ecs/examples/resources.rs | 2 + crates/bevy_ecs/macros/src/lib.rs | 2 +- crates/bevy_ecs/src/archetype.rs | 2 +- crates/bevy_ecs/src/batching.rs | 2 +- crates/bevy_ecs/src/bundle.rs | 6 +- crates/bevy_ecs/src/change_detection.rs | 25 ++--- crates/bevy_ecs/src/component.rs | 19 ++-- crates/bevy_ecs/src/entity/hash.rs | 2 +- crates/bevy_ecs/src/entity/mod.rs | 20 ++-- crates/bevy_ecs/src/event/base.rs | 4 +- crates/bevy_ecs/src/event/collections.rs | 15 +-- crates/bevy_ecs/src/event/event_cursor.rs | 2 +- crates/bevy_ecs/src/event/iterators.rs | 4 +- crates/bevy_ecs/src/event/mod.rs | 4 +- crates/bevy_ecs/src/event/mut_iterators.rs | 2 +- crates/bevy_ecs/src/event/update.rs | 2 +- crates/bevy_ecs/src/identifier/error.rs | 4 +- crates/bevy_ecs/src/identifier/masks.rs | 2 +- crates/bevy_ecs/src/identifier/mod.rs | 8 +- crates/bevy_ecs/src/intern.rs | 30 +++--- crates/bevy_ecs/src/label.rs | 26 ++--- crates/bevy_ecs/src/lib.rs | 29 +++--- .../bevy_ecs/src/observer/entity_observer.rs | 2 +- crates/bevy_ecs/src/observer/mod.rs | 6 +- crates/bevy_ecs/src/observer/runner.rs | 4 +- crates/bevy_ecs/src/observer/trigger_event.rs | 4 +- crates/bevy_ecs/src/query/access.rs | 5 +- crates/bevy_ecs/src/query/builder.rs | 4 +- crates/bevy_ecs/src/query/error.rs | 14 +-- crates/bevy_ecs/src/query/fetch.rs | 20 ++-- crates/bevy_ecs/src/query/filter.rs | 8 +- crates/bevy_ecs/src/query/iter.rs | 12 ++- crates/bevy_ecs/src/query/mod.rs | 7 +- crates/bevy_ecs/src/query/state.rs | 34 +++---- crates/bevy_ecs/src/reflect/bundle.rs | 6 +- .../bevy_ecs/src/reflect/entity_commands.rs | 3 +- crates/bevy_ecs/src/reflect/mod.rs | 4 +- crates/bevy_ecs/src/removal_detection.rs | 2 +- crates/bevy_ecs/src/schedule/condition.rs | 5 +- crates/bevy_ecs/src/schedule/executor/mod.rs | 2 +- .../src/schedule/executor/multi_threaded.rs | 15 +-- .../bevy_ecs/src/schedule/executor/simple.rs | 2 +- .../src/schedule/executor/single_threaded.rs | 2 +- crates/bevy_ecs/src/schedule/graph_utils.rs | 2 +- crates/bevy_ecs/src/schedule/mod.rs | 7 +- crates/bevy_ecs/src/schedule/schedule.rs | 16 ++- crates/bevy_ecs/src/schedule/set.rs | 6 +- crates/bevy_ecs/src/schedule/stepping.rs | 13 +-- crates/bevy_ecs/src/storage/blob_array.rs | 26 +++-- crates/bevy_ecs/src/storage/blob_vec.rs | 33 +++---- crates/bevy_ecs/src/storage/resource.rs | 5 +- crates/bevy_ecs/src/storage/sparse_set.rs | 6 +- crates/bevy_ecs/src/storage/table/column.rs | 6 +- crates/bevy_ecs/src/storage/table/mod.rs | 8 +- crates/bevy_ecs/src/storage/thin_array_ptr.rs | 9 +- crates/bevy_ecs/src/system/adapter_system.rs | 2 +- crates/bevy_ecs/src/system/builder.rs | 2 +- crates/bevy_ecs/src/system/combinator.rs | 3 +- crates/bevy_ecs/src/system/commands/mod.rs | 19 ++-- .../src/system/exclusive_function_system.rs | 5 +- .../src/system/exclusive_system_param.rs | 4 +- crates/bevy_ecs/src/system/function_system.rs | 11 ++- crates/bevy_ecs/src/system/input.rs | 2 +- crates/bevy_ecs/src/system/mod.rs | 20 ++-- crates/bevy_ecs/src/system/query.rs | 6 +- crates/bevy_ecs/src/system/system.rs | 5 +- crates/bevy_ecs/src/system/system_name.rs | 9 +- crates/bevy_ecs/src/system/system_param.rs | 38 +++---- crates/bevy_ecs/src/system/system_registry.rs | 20 ++-- crates/bevy_ecs/src/world/command_queue.rs | 26 +++-- crates/bevy_ecs/src/world/deferred_world.rs | 10 +- crates/bevy_ecs/src/world/entity_ref.rs | 12 +-- crates/bevy_ecs/src/world/identifier.rs | 6 +- crates/bevy_ecs/src/world/mod.rs | 57 ++++++----- crates/bevy_ecs/src/world/reflect.rs | 2 +- crates/bevy_ecs/src/world/spawn_batch.rs | 4 +- .../bevy_ecs/src/world/unsafe_world_cell.rs | 6 +- crates/bevy_gizmos/src/arcs.rs | 4 +- crates/bevy_gizmos/src/circles.rs | 2 +- crates/bevy_gizmos/src/config.rs | 4 +- crates/bevy_gizmos/src/gizmos.rs | 2 +- crates/bevy_gizmos/src/lib.rs | 55 ++++++----- crates/bevy_gizmos/src/light.rs | 2 +- crates/bevy_gizmos/src/primitives/dim2.rs | 2 +- crates/bevy_gizmos/src/primitives/helpers.rs | 4 +- crates/bevy_gizmos/src/rounded_box.rs | 4 +- crates/bevy_gltf/src/lib.rs | 6 +- crates/bevy_gltf/src/loader.rs | 21 ++-- crates/bevy_hierarchy/src/child_builder.rs | 8 +- .../bevy_hierarchy/src/components/children.rs | 7 +- .../bevy_hierarchy/src/components/parent.rs | 4 +- crates/bevy_hierarchy/src/hierarchy.rs | 2 +- crates/bevy_hierarchy/src/lib.rs | 2 + crates/bevy_hierarchy/src/query_extension.rs | 6 +- .../src/valid_parent_check_plugin.rs | 9 +- crates/bevy_input/src/axis.rs | 2 +- crates/bevy_input/src/button_input.rs | 11 ++- crates/bevy_input/src/common_conditions.rs | 2 +- crates/bevy_input/src/gamepad.rs | 9 +- crates/bevy_input/src/mouse.rs | 7 +- crates/bevy_log/src/android_tracing.rs | 10 +- crates/bevy_log/src/lib.rs | 18 ++-- crates/bevy_macro_utils/src/fq_std.rs | 2 +- crates/bevy_macro_utils/src/label.rs | 12 +-- crates/bevy_macro_utils/src/symbol.rs | 2 +- .../bevy_math/src/bounding/bounded2d/mod.rs | 8 +- .../src/bounding/bounded2d/primitive_impls.rs | 8 +- .../src/bounding/bounded3d/extrusion.rs | 4 +- .../bevy_math/src/bounding/bounded3d/mod.rs | 8 +- .../src/bounding/bounded3d/primitive_impls.rs | 2 +- crates/bevy_math/src/common_traits.rs | 2 +- crates/bevy_math/src/cubic_splines.rs | 8 +- crates/bevy_math/src/curve/interval.rs | 4 +- crates/bevy_math/src/curve/mod.rs | 4 +- crates/bevy_math/src/direction.rs | 38 +++---- crates/bevy_math/src/float_ord.rs | 2 +- crates/bevy_math/src/isometry.rs | 14 +-- crates/bevy_math/src/lib.rs | 11 ++- crates/bevy_math/src/primitives/dim2.rs | 12 +-- crates/bevy_math/src/primitives/dim3.rs | 12 +-- crates/bevy_math/src/primitives/serde.rs | 4 +- crates/bevy_math/src/rotation2d.rs | 12 +-- .../bevy_math/src/sampling/shape_sampling.rs | 2 +- crates/bevy_math/src/sampling/standard.rs | 2 +- crates/bevy_mikktspace/src/generated.rs | 2 +- crates/bevy_pbr/src/cluster/assign.rs | 2 +- crates/bevy_pbr/src/cluster/mod.rs | 4 +- crates/bevy_pbr/src/fog.rs | 2 +- crates/bevy_pbr/src/lib.rs | 4 +- crates/bevy_pbr/src/light/mod.rs | 8 +- crates/bevy_pbr/src/light/spot_light.rs | 2 +- .../src/light_probe/environment_map.rs | 2 +- .../src/light_probe/irradiance_volume.rs | 2 +- crates/bevy_pbr/src/light_probe/mod.rs | 2 +- crates/bevy_pbr/src/material.rs | 7 +- crates/bevy_pbr/src/meshlet/asset.rs | 8 +- crates/bevy_pbr/src/meshlet/from_mesh.rs | 3 +- .../bevy_pbr/src/meshlet/instance_manager.rs | 2 +- .../src/meshlet/material_pipeline_prepare.rs | 2 +- .../src/meshlet/meshlet_mesh_manager.rs | 3 +- .../bevy_pbr/src/meshlet/persistent_buffer.rs | 2 +- .../src/meshlet/persistent_buffer_impls.rs | 2 +- .../bevy_pbr/src/meshlet/resource_manager.rs | 6 +- .../meshlet/visibility_buffer_raster_node.rs | 2 +- crates/bevy_pbr/src/prepass/mod.rs | 2 +- crates/bevy_pbr/src/render/gpu_preprocess.rs | 2 +- crates/bevy_pbr/src/render/light.rs | 19 ++-- crates/bevy_pbr/src/render/mesh.rs | 2 +- .../bevy_pbr/src/render/mesh_view_bindings.rs | 3 +- crates/bevy_pbr/src/render/morph.rs | 4 +- crates/bevy_pbr/src/render/skin.rs | 2 +- crates/bevy_pbr/src/ssao/mod.rs | 2 +- crates/bevy_pbr/src/volumetric_fog/render.rs | 2 +- crates/bevy_picking/src/events.rs | 8 +- crates/bevy_picking/src/focus.rs | 7 +- crates/bevy_picking/src/lib.rs | 2 + crates/bevy_picking/src/pointer.rs | 2 +- crates/bevy_ptr/src/lib.rs | 4 +- .../tests/reflect_derive/custom_where_fail.rs | 4 +- .../tests/reflect_derive/custom_where_pass.rs | 6 +- crates/bevy_reflect/derive/src/derive_data.rs | 17 ++-- .../bevy_reflect/derive/src/enum_utility.rs | 3 +- crates/bevy_reflect/derive/src/lib.rs | 2 +- crates/bevy_reflect/derive/src/remote.rs | 4 +- .../bevy_reflect/derive/src/struct_utility.rs | 2 +- crates/bevy_reflect/src/array.rs | 8 +- crates/bevy_reflect/src/attributes.rs | 16 +-- crates/bevy_reflect/src/enums/dynamic_enum.rs | 4 +- crates/bevy_reflect/src/enums/enum_trait.rs | 3 +- crates/bevy_reflect/src/enums/helpers.rs | 6 +- crates/bevy_reflect/src/enums/variants.rs | 4 +- crates/bevy_reflect/src/fields.rs | 2 +- crates/bevy_reflect/src/func/args/arg.rs | 14 +-- crates/bevy_reflect/src/func/args/list.rs | 2 +- .../bevy_reflect/src/func/dynamic_function.rs | 5 +- crates/bevy_reflect/src/func/info.rs | 10 +- crates/bevy_reflect/src/func/mod.rs | 4 +- crates/bevy_reflect/src/func/registry.rs | 12 +-- crates/bevy_reflect/src/impls/petgraph.rs | 4 +- crates/bevy_reflect/src/impls/smallvec.rs | 2 +- crates/bevy_reflect/src/impls/std.rs | 99 +++++++++---------- crates/bevy_reflect/src/kind.rs | 4 +- crates/bevy_reflect/src/lib.rs | 39 ++++---- crates/bevy_reflect/src/list.rs | 12 +-- crates/bevy_reflect/src/map.rs | 12 +-- crates/bevy_reflect/src/path/access.rs | 3 +- crates/bevy_reflect/src/path/error.rs | 4 +- crates/bevy_reflect/src/path/mod.rs | 6 +- crates/bevy_reflect/src/path/parse.rs | 2 +- crates/bevy_reflect/src/reflect.rs | 14 +-- crates/bevy_reflect/src/remote.rs | 2 +- crates/bevy_reflect/src/serde/de/arrays.rs | 3 +- .../bevy_reflect/src/serde/de/deserializer.rs | 3 +- crates/bevy_reflect/src/serde/de/enums.rs | 3 +- .../bevy_reflect/src/serde/de/error_utils.rs | 2 +- crates/bevy_reflect/src/serde/de/helpers.rs | 6 +- crates/bevy_reflect/src/serde/de/lists.rs | 3 +- crates/bevy_reflect/src/serde/de/maps.rs | 3 +- crates/bevy_reflect/src/serde/de/mod.rs | 2 +- crates/bevy_reflect/src/serde/de/options.rs | 3 +- .../src/serde/de/registrations.rs | 3 +- crates/bevy_reflect/src/serde/de/sets.rs | 3 +- crates/bevy_reflect/src/serde/de/structs.rs | 3 +- .../src/serde/de/tuple_structs.rs | 3 +- crates/bevy_reflect/src/serde/de/tuples.rs | 3 +- .../bevy_reflect/src/serde/ser/error_utils.rs | 2 +- crates/bevy_reflect/src/serde/ser/mod.rs | 4 +- .../src/serde/ser/serializable.rs | 2 +- crates/bevy_reflect/src/set.rs | 10 +- crates/bevy_reflect/src/struct_trait.rs | 13 ++- crates/bevy_reflect/src/tuple.rs | 8 +- crates/bevy_reflect/src/tuple_struct.rs | 12 +-- crates/bevy_reflect/src/type_info.rs | 11 +-- crates/bevy_reflect/src/type_path.rs | 6 +- crates/bevy_reflect/src/type_registry.rs | 15 +-- crates/bevy_reflect/src/utility.rs | 4 +- crates/bevy_remote/src/builtin_methods.rs | 2 +- crates/bevy_remote/src/lib.rs | 6 +- crates/bevy_render/src/camera/camera.rs | 4 +- .../src/camera/manual_texture_view.rs | 4 +- crates/bevy_render/src/camera/projection.rs | 4 +- crates/bevy_render/src/diagnostic/internal.rs | 17 ++-- crates/bevy_render/src/diagnostic/mod.rs | 7 +- crates/bevy_render/src/extract_component.rs | 2 +- crates/bevy_render/src/extract_instances.rs | 2 +- crates/bevy_render/src/extract_param.rs | 2 +- crates/bevy_render/src/extract_resource.rs | 6 +- .../src/gpu_component_array_buffer.rs | 2 +- crates/bevy_render/src/lib.rs | 12 +-- crates/bevy_render/src/mesh/allocator.rs | 5 +- .../bevy_render/src/mesh/mesh/conversions.rs | 2 +- crates/bevy_render/src/mesh/mesh/mod.rs | 13 +-- crates/bevy_render/src/mesh/mesh/skinning.rs | 2 +- crates/bevy_render/src/mesh/mod.rs | 6 +- crates/bevy_render/src/mesh/morph.rs | 2 +- .../bevy_render/src/mesh/primitives/dim2.rs | 8 +- .../src/mesh/primitives/dim3/capsule.rs | 4 +- .../src/mesh/primitives/dim3/cone.rs | 2 +- .../mesh/primitives/dim3/conical_frustum.rs | 2 +- .../src/mesh/primitives/dim3/cylinder.rs | 2 +- .../src/mesh/primitives/dim3/sphere.rs | 4 +- .../src/mesh/primitives/dim3/torus.rs | 6 +- crates/bevy_render/src/primitives/mod.rs | 2 +- crates/bevy_render/src/render_asset.rs | 10 +- .../bevy_render/src/render_graph/context.rs | 2 +- crates/bevy_render/src/render_graph/graph.rs | 4 +- crates/bevy_render/src/render_graph/node.rs | 6 +- .../bevy_render/src/render_graph/node_slot.rs | 3 +- crates/bevy_render/src/render_phase/draw.rs | 16 ++- .../src/render_phase/draw_state.rs | 2 +- crates/bevy_render/src/render_phase/mod.rs | 4 +- .../render_resource/batched_uniform_buffer.rs | 2 +- .../src/render_resource/bind_group.rs | 2 +- .../src/render_resource/bind_group_entries.rs | 4 +- .../src/render_resource/bind_group_layout.rs | 2 +- .../bind_group_layout_entries.rs | 8 +- .../bevy_render/src/render_resource/buffer.rs | 2 +- .../src/render_resource/buffer_vec.rs | 2 +- .../src/render_resource/gpu_array_buffer.rs | 2 +- .../src/render_resource/pipeline.rs | 3 +- .../src/render_resource/pipeline_cache.rs | 11 +-- .../render_resource/pipeline_specializer.rs | 6 +- .../src/render_resource/resource_macros.rs | 26 ++--- .../bevy_render/src/render_resource/shader.rs | 5 +- .../src/render_resource/storage_buffer.rs | 2 +- .../src/render_resource/texture.rs | 2 +- .../src/render_resource/uniform_buffer.rs | 2 +- .../bevy_render/src/renderer/graph_runner.rs | 2 +- crates/bevy_render/src/renderer/mod.rs | 4 +- crates/bevy_render/src/settings.rs | 3 +- crates/bevy_render/src/texture/image.rs | 2 +- .../bevy_render/src/texture/image_loader.rs | 4 +- crates/bevy_render/src/texture/ktx2.rs | 2 +- .../src/texture/texture_attachment.rs | 6 +- crates/bevy_render/src/view/mod.rs | 8 +- crates/bevy_render/src/view/visibility/mod.rs | 2 +- .../bevy_render/src/view/visibility/range.rs | 2 +- .../src/view/visibility/render_layers.rs | 16 +-- crates/bevy_render/src/view/window/mod.rs | 4 +- .../bevy_render/src/view/window/screenshot.rs | 6 +- .../bevy_scene/src/dynamic_scene_builder.rs | 4 +- crates/bevy_scene/src/lib.rs | 2 + crates/bevy_scene/src/scene_filter.rs | 2 +- crates/bevy_scene/src/scene_spawner.rs | 10 +- crates/bevy_scene/src/serde.rs | 10 +- crates/bevy_sprite/src/lib.rs | 3 + crates/bevy_sprite/src/mesh2d/material.rs | 4 +- crates/bevy_sprite/src/picking_backend.rs | 2 +- crates/bevy_sprite/src/render/mod.rs | 2 +- .../bevy_sprite/src/texture_atlas_builder.rs | 2 +- crates/bevy_state/src/app.rs | 8 +- crates/bevy_state/src/lib.rs | 26 +++-- crates/bevy_state/src/reflect.rs | 2 +- .../bevy_state/src/state/computed_states.rs | 2 +- crates/bevy_state/src/state/resources.rs | 4 +- crates/bevy_state/src/state/states.rs | 4 +- crates/bevy_state/src/state/transitions.rs | 2 +- crates/bevy_state/src/state_scoped_events.rs | 2 +- crates/bevy_tasks/src/iter/adapters.rs | 32 +++--- crates/bevy_tasks/src/iter/mod.rs | 16 +-- crates/bevy_tasks/src/lib.rs | 6 +- .../src/single_threaded_task_pool.rs | 3 +- crates/bevy_tasks/src/slice.rs | 8 +- crates/bevy_tasks/src/task.rs | 2 +- crates/bevy_tasks/src/task_pool.rs | 23 ++--- crates/bevy_tasks/src/thread_executor.rs | 10 +- crates/bevy_tasks/src/usages.rs | 3 +- crates/bevy_tasks/src/wasm_task.rs | 10 +- crates/bevy_text/src/font.rs | 2 +- crates/bevy_text/src/font_atlas.rs | 4 +- crates/bevy_text/src/lib.rs | 2 + crates/bevy_text/src/pipeline.rs | 4 +- crates/bevy_time/src/lib.rs | 2 +- crates/bevy_time/src/time.rs | 9 +- .../src/components/global_transform.rs | 11 ++- .../src/components/transform.rs | 9 +- crates/bevy_transform/src/helper.rs | 2 +- crates/bevy_transform/src/lib.rs | 7 +- crates/bevy_transform/src/systems.rs | 2 +- crates/bevy_ui/src/geometry.rs | 2 +- crates/bevy_ui/src/layout/debug.rs | 2 +- crates/bevy_ui/src/layout/mod.rs | 5 +- crates/bevy_ui/src/layout/ui_surface.rs | 4 +- crates/bevy_ui/src/lib.rs | 13 +-- crates/bevy_ui/src/measurement.rs | 8 +- crates/bevy_ui/src/node_bundles.rs | 15 +-- crates/bevy_ui/src/render/mod.rs | 12 ++- crates/bevy_ui/src/render/render_pass.rs | 2 +- .../src/render/ui_material_pipeline.rs | 2 +- .../src/render/ui_texture_slice_pipeline.rs | 2 +- crates/bevy_ui/src/ui_material.rs | 4 +- crates/bevy_ui/src/ui_node.rs | 2 +- crates/bevy_ui/src/widget/text.rs | 4 +- crates/bevy_utils/macros/src/lib.rs | 4 +- crates/bevy_utils/src/lib.rs | 4 +- crates/bevy_utils/src/once.rs | 2 +- crates/bevy_window/src/lib.rs | 5 +- crates/bevy_window/src/raw_handle.rs | 9 +- crates/bevy_window/src/window.rs | 2 +- crates/bevy_winit/src/accessibility.rs | 6 +- crates/bevy_winit/src/lib.rs | 4 +- crates/bevy_winit/src/state.rs | 2 +- crates/bevy_winit/src/winit_windows.rs | 6 +- examples/2d/mesh2d_arcs.rs | 1 + examples/animation/animation_graph.rs | 14 ++- examples/audio/decodable.rs | 1 + examples/ui/overflow_debug.rs | 1 + tools/build-templated-pages/src/examples.rs | 3 +- tools/build-templated-pages/src/features.rs | 5 +- tools/example-showcase/disable-audio.patch | 2 +- tools/example-showcase/src/main.rs | 11 ++- 456 files changed, 1718 insertions(+), 1659 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 120fd6d67981c..6fdb2b37f4989 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -48,6 +48,10 @@ ref_as_ptr = "warn" # see: https://github.com/bevyengine/bevy/pull/15375#issuecomment-2366966219 too_long_first_doc_paragraph = "allow" +std_instead_of_core = "warn" +std_instead_of_alloc = "warn" +alloc_instead_of_core = "warn" + [workspace.lints.rust] missing_docs = "warn" unexpected_cfgs = { level = "warn", check-cfg = ['cfg(docsrs_dep)'] } @@ -55,8 +59,44 @@ unsafe_code = "deny" unsafe_op_in_unsafe_fn = "warn" unused_qualifications = "warn" -[lints] -workspace = true +# Unfortunately, cargo does not currently support overriding workspace lints +# inside a particular crate. See https://github.com/rust-lang/cargo/issues/13157 +# +# We require an override for cases like `std_instead_of_core`, which are intended +# for the library contributors and not for how users should consume Bevy. +# To ensure examples aren't subject to these lints, below is a duplication of the +# workspace lints, with the "overrides" applied. +# +# [lints] +# workspace = true + +[lints.clippy] +doc_markdown = "warn" +manual_let_else = "warn" +match_same_arms = "warn" +redundant_closure_for_method_calls = "warn" +redundant_else = "warn" +semicolon_if_nothing_returned = "warn" +type_complexity = "allow" +undocumented_unsafe_blocks = "warn" +unwrap_or_default = "warn" + +ptr_as_ptr = "warn" +ptr_cast_constness = "warn" +ref_as_ptr = "warn" + +too_long_first_doc_paragraph = "allow" + +std_instead_of_core = "allow" +std_instead_of_alloc = "allow" +alloc_instead_of_core = "allow" + +[lints.rust] +missing_docs = "warn" +unexpected_cfgs = { level = "warn", check-cfg = ['cfg(docsrs_dep)'] } +unsafe_code = "deny" +unsafe_op_in_unsafe_fn = "warn" +unused_qualifications = "warn" [features] default = [ diff --git a/benches/benches/bevy_ecs/change_detection.rs b/benches/benches/bevy_ecs/change_detection.rs index ae602738fe368..6c4428efed8bb 100644 --- a/benches/benches/bevy_ecs/change_detection.rs +++ b/benches/benches/bevy_ecs/change_detection.rs @@ -86,7 +86,7 @@ fn generic_bench( fn all_added_detection_generic(group: &mut BenchGroup, entity_count: u32) { group.bench_function( - format!("{}_entities_{}", entity_count, std::any::type_name::()), + format!("{}_entities_{}", entity_count, core::any::type_name::()), |bencher| { bencher.iter_batched_ref( || { @@ -110,8 +110,8 @@ fn all_added_detection_generic(group: &mut BenchGroup, e fn all_added_detection(criterion: &mut Criterion) { let mut group = criterion.benchmark_group("all_added_detection"); - group.warm_up_time(std::time::Duration::from_millis(500)); - group.measurement_time(std::time::Duration::from_secs(4)); + group.warm_up_time(core::time::Duration::from_millis(500)); + group.measurement_time(core::time::Duration::from_secs(4)); for &entity_count in ENTITIES_TO_BENCH_COUNT { generic_bench( &mut group, @@ -129,7 +129,7 @@ fn all_changed_detection_generic( entity_count: u32, ) { group.bench_function( - format!("{}_entities_{}", entity_count, std::any::type_name::()), + format!("{}_entities_{}", entity_count, core::any::type_name::()), |bencher| { bencher.iter_batched_ref( || { @@ -158,8 +158,8 @@ fn all_changed_detection_generic( fn all_changed_detection(criterion: &mut Criterion) { let mut group = criterion.benchmark_group("all_changed_detection"); - group.warm_up_time(std::time::Duration::from_millis(500)); - group.measurement_time(std::time::Duration::from_secs(4)); + group.warm_up_time(core::time::Duration::from_millis(500)); + group.measurement_time(core::time::Duration::from_secs(4)); for &entity_count in ENTITIES_TO_BENCH_COUNT { generic_bench( &mut group, @@ -179,7 +179,7 @@ fn few_changed_detection_generic( let ratio_to_modify = 0.1; let amount_to_modify = (entity_count as f32 * ratio_to_modify) as usize; group.bench_function( - format!("{}_entities_{}", entity_count, std::any::type_name::()), + format!("{}_entities_{}", entity_count, core::any::type_name::()), |bencher| { bencher.iter_batched_ref( || { @@ -208,8 +208,8 @@ fn few_changed_detection_generic( fn few_changed_detection(criterion: &mut Criterion) { let mut group = criterion.benchmark_group("few_changed_detection"); - group.warm_up_time(std::time::Duration::from_millis(500)); - group.measurement_time(std::time::Duration::from_secs(4)); + group.warm_up_time(core::time::Duration::from_millis(500)); + group.measurement_time(core::time::Duration::from_secs(4)); for &entity_count in ENTITIES_TO_BENCH_COUNT { generic_bench( &mut group, @@ -227,7 +227,7 @@ fn none_changed_detection_generic( entity_count: u32, ) { group.bench_function( - format!("{}_entities_{}", entity_count, std::any::type_name::()), + format!("{}_entities_{}", entity_count, core::any::type_name::()), |bencher| { bencher.iter_batched_ref( || { @@ -252,8 +252,8 @@ fn none_changed_detection_generic( fn none_changed_detection(criterion: &mut Criterion) { let mut group = criterion.benchmark_group("none_changed_detection"); - group.warm_up_time(std::time::Duration::from_millis(500)); - group.measurement_time(std::time::Duration::from_secs(4)); + group.warm_up_time(core::time::Duration::from_millis(500)); + group.measurement_time(core::time::Duration::from_secs(4)); for &entity_count in ENTITIES_TO_BENCH_COUNT { generic_bench( &mut group, @@ -308,7 +308,7 @@ fn multiple_archetype_none_changed_detection_generic() + core::any::type_name::() ), |bencher| { bencher.iter_batched_ref( @@ -356,8 +356,8 @@ fn multiple_archetype_none_changed_detection_generic( diff --git a/benches/benches/bevy_ecs/components/mod.rs b/benches/benches/bevy_ecs/components/mod.rs index 6da93681005a0..592f40fba7d07 100644 --- a/benches/benches/bevy_ecs/components/mod.rs +++ b/benches/benches/bevy_ecs/components/mod.rs @@ -23,8 +23,8 @@ criterion_group!( fn add_remove(c: &mut Criterion) { let mut group = c.benchmark_group("add_remove"); - group.warm_up_time(std::time::Duration::from_millis(500)); - group.measurement_time(std::time::Duration::from_secs(4)); + group.warm_up_time(core::time::Duration::from_millis(500)); + group.measurement_time(core::time::Duration::from_secs(4)); group.bench_function("table", |b| { let mut bench = add_remove_table::Benchmark::new(); b.iter(move || bench.run()); @@ -38,8 +38,8 @@ fn add_remove(c: &mut Criterion) { fn add_remove_big(c: &mut Criterion) { let mut group = c.benchmark_group("add_remove_big"); - group.warm_up_time(std::time::Duration::from_millis(500)); - group.measurement_time(std::time::Duration::from_secs(4)); + group.warm_up_time(core::time::Duration::from_millis(500)); + group.measurement_time(core::time::Duration::from_secs(4)); group.bench_function("table", |b| { let mut bench = add_remove_big_table::Benchmark::new(); b.iter(move || bench.run()); @@ -53,8 +53,8 @@ fn add_remove_big(c: &mut Criterion) { fn add_remove_very_big(c: &mut Criterion) { let mut group = c.benchmark_group("add_remove_very_big"); - group.warm_up_time(std::time::Duration::from_millis(500)); - group.measurement_time(std::time::Duration::from_secs(4)); + group.warm_up_time(core::time::Duration::from_millis(500)); + group.measurement_time(core::time::Duration::from_secs(4)); group.bench_function("table", |b| { let mut bench = add_remove_very_big_table::Benchmark::new(); b.iter(move || bench.run()); @@ -64,8 +64,8 @@ fn add_remove_very_big(c: &mut Criterion) { fn insert_simple(c: &mut Criterion) { let mut group = c.benchmark_group("insert_simple"); - group.warm_up_time(std::time::Duration::from_millis(500)); - group.measurement_time(std::time::Duration::from_secs(4)); + group.warm_up_time(core::time::Duration::from_millis(500)); + group.measurement_time(core::time::Duration::from_secs(4)); group.bench_function("base", |b| { let mut bench = insert_simple::Benchmark::new(); b.iter(move || bench.run()); diff --git a/benches/benches/bevy_ecs/events/iter.rs b/benches/benches/bevy_ecs/events/iter.rs index 50fb65554e837..dc20bc3395a52 100644 --- a/benches/benches/bevy_ecs/events/iter.rs +++ b/benches/benches/bevy_ecs/events/iter.rs @@ -19,7 +19,7 @@ impl Benchmark { pub fn run(&mut self) { let mut reader = self.0.get_cursor(); for evt in reader.read(&self.0) { - std::hint::black_box(evt); + core::hint::black_box(evt); } } } diff --git a/benches/benches/bevy_ecs/events/mod.rs b/benches/benches/bevy_ecs/events/mod.rs index f7130594c6ed2..5d20ef25cd018 100644 --- a/benches/benches/bevy_ecs/events/mod.rs +++ b/benches/benches/bevy_ecs/events/mod.rs @@ -7,8 +7,8 @@ criterion_group!(event_benches, send, iter); fn send(c: &mut Criterion) { let mut group = c.benchmark_group("events_send"); - group.warm_up_time(std::time::Duration::from_millis(500)); - group.measurement_time(std::time::Duration::from_secs(4)); + group.warm_up_time(core::time::Duration::from_millis(500)); + group.measurement_time(core::time::Duration::from_secs(4)); for count in [100, 1000, 10000, 50000] { group.bench_function(format!("size_4_events_{}", count), |b| { let mut bench = send::Benchmark::<4>::new(count); @@ -32,8 +32,8 @@ fn send(c: &mut Criterion) { fn iter(c: &mut Criterion) { let mut group = c.benchmark_group("events_iter"); - group.warm_up_time(std::time::Duration::from_millis(500)); - group.measurement_time(std::time::Duration::from_secs(4)); + group.warm_up_time(core::time::Duration::from_millis(500)); + group.measurement_time(core::time::Duration::from_secs(4)); for count in [100, 1000, 10000, 50000] { group.bench_function(format!("size_4_events_{}", count), |b| { let mut bench = iter::Benchmark::<4>::new(count); diff --git a/benches/benches/bevy_ecs/events/send.rs b/benches/benches/bevy_ecs/events/send.rs index 2c81583d74ca1..fa996b50aa5d0 100644 --- a/benches/benches/bevy_ecs/events/send.rs +++ b/benches/benches/bevy_ecs/events/send.rs @@ -32,7 +32,7 @@ impl Benchmark { pub fn run(&mut self) { for _ in 0..self.count { self.events - .send(std::hint::black_box(BenchEvent([0u8; SIZE]))); + .send(core::hint::black_box(BenchEvent([0u8; SIZE]))); } self.events.update(); } diff --git a/benches/benches/bevy_ecs/fragmentation/mod.rs b/benches/benches/bevy_ecs/fragmentation/mod.rs index c5b364622139c..ae44aae4a48c5 100644 --- a/benches/benches/bevy_ecs/fragmentation/mod.rs +++ b/benches/benches/bevy_ecs/fragmentation/mod.rs @@ -2,7 +2,7 @@ use bevy_ecs::prelude::*; use bevy_ecs::system::SystemState; use criterion::*; use glam::*; -use std::hint::black_box; +use core::hint::black_box; criterion_group!(fragmentation_benches, iter_frag_empty); @@ -17,8 +17,8 @@ fn flip_coin() -> bool { } fn iter_frag_empty(c: &mut Criterion) { let mut group = c.benchmark_group("iter_fragmented(4096)_empty"); - group.warm_up_time(std::time::Duration::from_millis(500)); - group.measurement_time(std::time::Duration::from_secs(4)); + group.warm_up_time(core::time::Duration::from_millis(500)); + group.measurement_time(core::time::Duration::from_secs(4)); group.bench_function("foreach_table", |b| { let mut world = World::new(); diff --git a/benches/benches/bevy_ecs/iteration/heavy_compute.rs b/benches/benches/bevy_ecs/iteration/heavy_compute.rs index 9a53092903f48..3a3e350637236 100644 --- a/benches/benches/bevy_ecs/iteration/heavy_compute.rs +++ b/benches/benches/bevy_ecs/iteration/heavy_compute.rs @@ -17,8 +17,8 @@ pub fn heavy_compute(c: &mut Criterion) { struct Transform(Mat4); let mut group = c.benchmark_group("heavy_compute"); - group.warm_up_time(std::time::Duration::from_millis(500)); - group.measurement_time(std::time::Duration::from_secs(4)); + group.warm_up_time(core::time::Duration::from_millis(500)); + group.measurement_time(core::time::Duration::from_secs(4)); group.bench_function("base", |b| { ComputeTaskPool::get_or_init(TaskPool::default); diff --git a/benches/benches/bevy_ecs/iteration/iter_simple.rs b/benches/benches/bevy_ecs/iteration/iter_simple.rs index 79af49b44dc6d..1fc86f5087679 100644 --- a/benches/benches/bevy_ecs/iteration/iter_simple.rs +++ b/benches/benches/bevy_ecs/iteration/iter_simple.rs @@ -20,7 +20,7 @@ impl<'w> Benchmark<'w> { let mut world = World::new(); world.spawn_batch( - std::iter::repeat(( + core::iter::repeat(( Transform(Mat4::from_scale(Vec3::ONE)), Position(Vec3::X), Rotation(Vec3::X), diff --git a/benches/benches/bevy_ecs/iteration/iter_simple_foreach.rs b/benches/benches/bevy_ecs/iteration/iter_simple_foreach.rs index a7975f9b6ee05..f0a41d18be53b 100644 --- a/benches/benches/bevy_ecs/iteration/iter_simple_foreach.rs +++ b/benches/benches/bevy_ecs/iteration/iter_simple_foreach.rs @@ -20,7 +20,7 @@ impl<'w> Benchmark<'w> { let mut world = World::new(); world.spawn_batch( - std::iter::repeat(( + core::iter::repeat(( Transform(Mat4::from_scale(Vec3::ONE)), Position(Vec3::X), Rotation(Vec3::X), diff --git a/benches/benches/bevy_ecs/iteration/iter_simple_foreach_sparse_set.rs b/benches/benches/bevy_ecs/iteration/iter_simple_foreach_sparse_set.rs index 3864a519b0171..0075c2706ba20 100644 --- a/benches/benches/bevy_ecs/iteration/iter_simple_foreach_sparse_set.rs +++ b/benches/benches/bevy_ecs/iteration/iter_simple_foreach_sparse_set.rs @@ -22,7 +22,7 @@ impl<'w> Benchmark<'w> { let mut world = World::new(); world.spawn_batch( - std::iter::repeat(( + core::iter::repeat(( Transform(Mat4::from_scale(Vec3::ONE)), Position(Vec3::X), Rotation(Vec3::X), diff --git a/benches/benches/bevy_ecs/iteration/iter_simple_foreach_wide.rs b/benches/benches/bevy_ecs/iteration/iter_simple_foreach_wide.rs index 284706417268e..7dbd11d1e0499 100644 --- a/benches/benches/bevy_ecs/iteration/iter_simple_foreach_wide.rs +++ b/benches/benches/bevy_ecs/iteration/iter_simple_foreach_wide.rs @@ -34,7 +34,7 @@ impl<'w> Benchmark<'w> { let mut world = World::new(); world.spawn_batch( - std::iter::repeat(( + core::iter::repeat(( Transform(Mat4::from_scale(Vec3::ONE)), Rotation(Vec3::X), Position::<0>(Vec3::X), diff --git a/benches/benches/bevy_ecs/iteration/iter_simple_foreach_wide_sparse_set.rs b/benches/benches/bevy_ecs/iteration/iter_simple_foreach_wide_sparse_set.rs index c25edcd9b8608..f520ffde42662 100644 --- a/benches/benches/bevy_ecs/iteration/iter_simple_foreach_wide_sparse_set.rs +++ b/benches/benches/bevy_ecs/iteration/iter_simple_foreach_wide_sparse_set.rs @@ -36,7 +36,7 @@ impl<'w> Benchmark<'w> { let mut world = World::new(); world.spawn_batch( - std::iter::repeat(( + core::iter::repeat(( Transform(Mat4::from_scale(Vec3::ONE)), Rotation(Vec3::X), Position::<0>(Vec3::X), diff --git a/benches/benches/bevy_ecs/iteration/iter_simple_sparse_set.rs b/benches/benches/bevy_ecs/iteration/iter_simple_sparse_set.rs index d4394b5adee60..e4ba3759412c7 100644 --- a/benches/benches/bevy_ecs/iteration/iter_simple_sparse_set.rs +++ b/benches/benches/bevy_ecs/iteration/iter_simple_sparse_set.rs @@ -22,7 +22,7 @@ impl<'w> Benchmark<'w> { let mut world = World::new(); world.spawn_batch( - std::iter::repeat(( + core::iter::repeat(( Transform(Mat4::from_scale(Vec3::ONE)), Position(Vec3::X), Rotation(Vec3::X), diff --git a/benches/benches/bevy_ecs/iteration/iter_simple_system.rs b/benches/benches/bevy_ecs/iteration/iter_simple_system.rs index e583ffc558fd7..18918ee234f9f 100644 --- a/benches/benches/bevy_ecs/iteration/iter_simple_system.rs +++ b/benches/benches/bevy_ecs/iteration/iter_simple_system.rs @@ -20,7 +20,7 @@ impl Benchmark { let mut world = World::new(); world.spawn_batch( - std::iter::repeat(( + core::iter::repeat(( Transform(Mat4::from_scale(Vec3::ONE)), Position(Vec3::X), Rotation(Vec3::X), diff --git a/benches/benches/bevy_ecs/iteration/iter_simple_wide.rs b/benches/benches/bevy_ecs/iteration/iter_simple_wide.rs index 193ca0c7fb760..7d013b3bf6003 100644 --- a/benches/benches/bevy_ecs/iteration/iter_simple_wide.rs +++ b/benches/benches/bevy_ecs/iteration/iter_simple_wide.rs @@ -34,7 +34,7 @@ impl<'w> Benchmark<'w> { let mut world = World::new(); world.spawn_batch( - std::iter::repeat(( + core::iter::repeat(( Transform(Mat4::from_scale(Vec3::ONE)), Rotation(Vec3::X), Position::<0>(Vec3::X), diff --git a/benches/benches/bevy_ecs/iteration/iter_simple_wide_sparse_set.rs b/benches/benches/bevy_ecs/iteration/iter_simple_wide_sparse_set.rs index a4cea147ac91a..28a6dbd85dc28 100644 --- a/benches/benches/bevy_ecs/iteration/iter_simple_wide_sparse_set.rs +++ b/benches/benches/bevy_ecs/iteration/iter_simple_wide_sparse_set.rs @@ -36,7 +36,7 @@ impl<'w> Benchmark<'w> { let mut world = World::new(); world.spawn_batch( - std::iter::repeat(( + core::iter::repeat(( Transform(Mat4::from_scale(Vec3::ONE)), Rotation(Vec3::X), Position::<0>(Vec3::X), diff --git a/benches/benches/bevy_ecs/iteration/mod.rs b/benches/benches/bevy_ecs/iteration/mod.rs index a5dcca441c2fe..62d8b166040dc 100644 --- a/benches/benches/bevy_ecs/iteration/mod.rs +++ b/benches/benches/bevy_ecs/iteration/mod.rs @@ -35,8 +35,8 @@ criterion_group!( fn iter_simple(c: &mut Criterion) { let mut group = c.benchmark_group("iter_simple"); - group.warm_up_time(std::time::Duration::from_millis(500)); - group.measurement_time(std::time::Duration::from_secs(4)); + group.warm_up_time(core::time::Duration::from_millis(500)); + group.measurement_time(core::time::Duration::from_secs(4)); group.bench_function("base", |b| { let mut bench = iter_simple::Benchmark::new(); b.iter(move || bench.run()); @@ -82,8 +82,8 @@ fn iter_simple(c: &mut Criterion) { fn iter_frag(c: &mut Criterion) { let mut group = c.benchmark_group("iter_fragmented"); - group.warm_up_time(std::time::Duration::from_millis(500)); - group.measurement_time(std::time::Duration::from_secs(4)); + group.warm_up_time(core::time::Duration::from_millis(500)); + group.measurement_time(core::time::Duration::from_secs(4)); group.bench_function("base", |b| { let mut bench = iter_frag::Benchmark::new(); b.iter(move || bench.run()); @@ -105,8 +105,8 @@ fn iter_frag(c: &mut Criterion) { fn iter_frag_sparse(c: &mut Criterion) { let mut group = c.benchmark_group("iter_fragmented_sparse"); - group.warm_up_time(std::time::Duration::from_millis(500)); - group.measurement_time(std::time::Duration::from_secs(4)); + group.warm_up_time(core::time::Duration::from_millis(500)); + group.measurement_time(core::time::Duration::from_secs(4)); group.bench_function("base", |b| { let mut bench = iter_frag_sparse::Benchmark::new(); b.iter(move || bench.run()); @@ -128,8 +128,8 @@ fn iter_frag_sparse(c: &mut Criterion) { fn par_iter_simple(c: &mut Criterion) { let mut group = c.benchmark_group("par_iter_simple"); - group.warm_up_time(std::time::Duration::from_millis(500)); - group.measurement_time(std::time::Duration::from_secs(4)); + group.warm_up_time(core::time::Duration::from_millis(500)); + group.measurement_time(core::time::Duration::from_secs(4)); for f in [0, 10, 100, 1000] { group.bench_function(format!("with_{}_fragment", f), |b| { let mut bench = par_iter_simple::Benchmark::new(f); diff --git a/benches/benches/bevy_ecs/iteration/par_iter_simple.rs b/benches/benches/bevy_ecs/iteration/par_iter_simple.rs index 76489e33a84a3..dfd3f9dfdab0d 100644 --- a/benches/benches/bevy_ecs/iteration/par_iter_simple.rs +++ b/benches/benches/bevy_ecs/iteration/par_iter_simple.rs @@ -31,7 +31,7 @@ impl<'w> Benchmark<'w> { let mut world = World::new(); let iter = world.spawn_batch( - std::iter::repeat(( + core::iter::repeat(( Transform(Mat4::from_scale(Vec3::ONE)), Position(Vec3::X), Rotation(Vec3::X), diff --git a/benches/benches/bevy_ecs/observers/propagation.rs b/benches/benches/bevy_ecs/observers/propagation.rs index 4b42234f96520..b702662e7dd8c 100644 --- a/benches/benches/bevy_ecs/observers/propagation.rs +++ b/benches/benches/bevy_ecs/observers/propagation.rs @@ -22,8 +22,8 @@ fn deterministic_rand() -> ChaCha8Rng { pub fn event_propagation(criterion: &mut Criterion) { let mut group = criterion.benchmark_group("event_propagation"); - group.warm_up_time(std::time::Duration::from_millis(500)); - group.measurement_time(std::time::Duration::from_secs(4)); + group.warm_up_time(core::time::Duration::from_millis(500)); + group.measurement_time(core::time::Duration::from_secs(4)); group.bench_function("single_event_type", |bencher| { let mut world = World::new(); diff --git a/benches/benches/bevy_ecs/observers/simple.rs b/benches/benches/bevy_ecs/observers/simple.rs index 77457d6af2e4e..4d4d5bc2aa852 100644 --- a/benches/benches/bevy_ecs/observers/simple.rs +++ b/benches/benches/bevy_ecs/observers/simple.rs @@ -12,8 +12,8 @@ struct EventBase; pub fn observe_simple(criterion: &mut Criterion) { let mut group = criterion.benchmark_group("observe"); - group.warm_up_time(std::time::Duration::from_millis(500)); - group.measurement_time(std::time::Duration::from_secs(4)); + group.warm_up_time(core::time::Duration::from_millis(500)); + group.measurement_time(core::time::Duration::from_secs(4)); group.bench_function("trigger_simple", |bencher| { let mut world = World::new(); diff --git a/benches/benches/bevy_ecs/scheduling/run_condition.rs b/benches/benches/bevy_ecs/scheduling/run_condition.rs index 7f0100633d8f5..1a033f36ef8b8 100644 --- a/benches/benches/bevy_ecs/scheduling/run_condition.rs +++ b/benches/benches/bevy_ecs/scheduling/run_condition.rs @@ -14,8 +14,8 @@ fn no() -> bool { pub fn run_condition_yes(criterion: &mut Criterion) { let mut world = World::new(); let mut group = criterion.benchmark_group("run_condition/yes"); - group.warm_up_time(std::time::Duration::from_millis(500)); - group.measurement_time(std::time::Duration::from_secs(3)); + group.warm_up_time(core::time::Duration::from_millis(500)); + group.measurement_time(core::time::Duration::from_secs(3)); fn empty() {} for amount in 0..21 { let mut schedule = Schedule::default(); @@ -37,8 +37,8 @@ pub fn run_condition_yes(criterion: &mut Criterion) { pub fn run_condition_no(criterion: &mut Criterion) { let mut world = World::new(); let mut group = criterion.benchmark_group("run_condition/no"); - group.warm_up_time(std::time::Duration::from_millis(500)); - group.measurement_time(std::time::Duration::from_secs(3)); + group.warm_up_time(core::time::Duration::from_millis(500)); + group.measurement_time(core::time::Duration::from_secs(3)); fn empty() {} for amount in 0..21 { let mut schedule = Schedule::default(); @@ -64,8 +64,8 @@ pub fn run_condition_yes_with_query(criterion: &mut Criterion) { let mut world = World::new(); world.spawn(TestBool(true)); let mut group = criterion.benchmark_group("run_condition/yes_using_query"); - group.warm_up_time(std::time::Duration::from_millis(500)); - group.measurement_time(std::time::Duration::from_secs(3)); + group.warm_up_time(core::time::Duration::from_millis(500)); + group.measurement_time(core::time::Duration::from_secs(3)); fn empty() {} fn yes_with_query(query: Query<&TestBool>) -> bool { query.single().0 @@ -93,8 +93,8 @@ pub fn run_condition_yes_with_resource(criterion: &mut Criterion) { let mut world = World::new(); world.insert_resource(TestBool(true)); let mut group = criterion.benchmark_group("run_condition/yes_using_resource"); - group.warm_up_time(std::time::Duration::from_millis(500)); - group.measurement_time(std::time::Duration::from_secs(3)); + group.warm_up_time(core::time::Duration::from_millis(500)); + group.measurement_time(core::time::Duration::from_secs(3)); fn empty() {} fn yes_with_resource(res: Res) -> bool { res.0 diff --git a/benches/benches/bevy_ecs/scheduling/running_systems.rs b/benches/benches/bevy_ecs/scheduling/running_systems.rs index 6d5d0ed3df566..d2ea51307f87f 100644 --- a/benches/benches/bevy_ecs/scheduling/running_systems.rs +++ b/benches/benches/bevy_ecs/scheduling/running_systems.rs @@ -17,8 +17,8 @@ const ENTITY_BUNCH: usize = 5000; pub fn empty_systems(criterion: &mut Criterion) { let mut world = World::new(); let mut group = criterion.benchmark_group("empty_systems"); - group.warm_up_time(std::time::Duration::from_millis(500)); - group.measurement_time(std::time::Duration::from_secs(3)); + group.warm_up_time(core::time::Duration::from_millis(500)); + group.measurement_time(core::time::Duration::from_secs(3)); fn empty() {} for amount in 0..5 { let mut schedule = Schedule::default(); @@ -50,23 +50,23 @@ pub fn empty_systems(criterion: &mut Criterion) { pub fn busy_systems(criterion: &mut Criterion) { fn ab(mut q: Query<(&mut A, &mut B)>) { q.iter_mut().for_each(|(mut a, mut b)| { - std::mem::swap(&mut a.0, &mut b.0); + core::mem::swap(&mut a.0, &mut b.0); }); } fn cd(mut q: Query<(&mut C, &mut D)>) { q.iter_mut().for_each(|(mut c, mut d)| { - std::mem::swap(&mut c.0, &mut d.0); + core::mem::swap(&mut c.0, &mut d.0); }); } fn ce(mut q: Query<(&mut C, &mut E)>) { q.iter_mut().for_each(|(mut c, mut e)| { - std::mem::swap(&mut c.0, &mut e.0); + core::mem::swap(&mut c.0, &mut e.0); }); } let mut world = World::new(); let mut group = criterion.benchmark_group("busy_systems"); - group.warm_up_time(std::time::Duration::from_millis(500)); - group.measurement_time(std::time::Duration::from_secs(3)); + group.warm_up_time(core::time::Duration::from_millis(500)); + group.measurement_time(core::time::Duration::from_secs(3)); for entity_bunches in 1..6 { world.spawn_batch((0..4 * ENTITY_BUNCH).map(|_| (A(0.0), B(0.0)))); world.spawn_batch((0..4 * ENTITY_BUNCH).map(|_| (A(0.0), B(0.0), C(0.0)))); @@ -99,26 +99,26 @@ pub fn busy_systems(criterion: &mut Criterion) { pub fn contrived(criterion: &mut Criterion) { fn s_0(mut q_0: Query<(&mut A, &mut B)>) { q_0.iter_mut().for_each(|(mut c_0, mut c_1)| { - std::mem::swap(&mut c_0.0, &mut c_1.0); + core::mem::swap(&mut c_0.0, &mut c_1.0); }); } fn s_1(mut q_0: Query<(&mut A, &mut C)>, mut q_1: Query<(&mut B, &mut D)>) { q_0.iter_mut().for_each(|(mut c_0, mut c_1)| { - std::mem::swap(&mut c_0.0, &mut c_1.0); + core::mem::swap(&mut c_0.0, &mut c_1.0); }); q_1.iter_mut().for_each(|(mut c_0, mut c_1)| { - std::mem::swap(&mut c_0.0, &mut c_1.0); + core::mem::swap(&mut c_0.0, &mut c_1.0); }); } fn s_2(mut q_0: Query<(&mut C, &mut D)>) { q_0.iter_mut().for_each(|(mut c_0, mut c_1)| { - std::mem::swap(&mut c_0.0, &mut c_1.0); + core::mem::swap(&mut c_0.0, &mut c_1.0); }); } let mut world = World::new(); let mut group = criterion.benchmark_group("contrived"); - group.warm_up_time(std::time::Duration::from_millis(500)); - group.measurement_time(std::time::Duration::from_secs(3)); + group.warm_up_time(core::time::Duration::from_millis(500)); + group.measurement_time(core::time::Duration::from_secs(3)); for entity_bunches in 1..6 { world.spawn_batch((0..ENTITY_BUNCH).map(|_| (A(0.0), B(0.0), C(0.0), D(0.0)))); world.spawn_batch((0..ENTITY_BUNCH).map(|_| (A(0.0), B(0.0)))); diff --git a/benches/benches/bevy_ecs/scheduling/schedule.rs b/benches/benches/bevy_ecs/scheduling/schedule.rs index 0930d8e122b0f..4571899a9b7b5 100644 --- a/benches/benches/bevy_ecs/scheduling/schedule.rs +++ b/benches/benches/bevy_ecs/scheduling/schedule.rs @@ -16,25 +16,25 @@ pub fn schedule(c: &mut Criterion) { fn ab(mut query: Query<(&mut A, &mut B)>) { query.iter_mut().for_each(|(mut a, mut b)| { - std::mem::swap(&mut a.0, &mut b.0); + core::mem::swap(&mut a.0, &mut b.0); }); } fn cd(mut query: Query<(&mut C, &mut D)>) { query.iter_mut().for_each(|(mut c, mut d)| { - std::mem::swap(&mut c.0, &mut d.0); + core::mem::swap(&mut c.0, &mut d.0); }); } fn ce(mut query: Query<(&mut C, &mut E)>) { query.iter_mut().for_each(|(mut c, mut e)| { - std::mem::swap(&mut c.0, &mut e.0); + core::mem::swap(&mut c.0, &mut e.0); }); } let mut group = c.benchmark_group("schedule"); - group.warm_up_time(std::time::Duration::from_millis(500)); - group.measurement_time(std::time::Duration::from_secs(4)); + group.warm_up_time(core::time::Duration::from_millis(500)); + group.measurement_time(core::time::Duration::from_secs(4)); group.bench_function("base", |b| { let mut world = World::default(); @@ -68,8 +68,8 @@ pub fn build_schedule(criterion: &mut Criterion) { struct DummySet; let mut group = criterion.benchmark_group("build_schedule"); - group.warm_up_time(std::time::Duration::from_millis(500)); - group.measurement_time(std::time::Duration::from_secs(15)); + group.warm_up_time(core::time::Duration::from_millis(500)); + group.measurement_time(core::time::Duration::from_secs(15)); // Method: generate a set of `graph_size` systems which have a One True Ordering. // Add system to the schedule with full constraints. Hopefully this should be maximally diff --git a/benches/benches/bevy_ecs/world/commands.rs b/benches/benches/bevy_ecs/world/commands.rs index e27ccbe17285c..5f2f8a01f5213 100644 --- a/benches/benches/bevy_ecs/world/commands.rs +++ b/benches/benches/bevy_ecs/world/commands.rs @@ -15,8 +15,8 @@ struct C; pub fn empty_commands(criterion: &mut Criterion) { let mut group = criterion.benchmark_group("empty_commands"); - group.warm_up_time(std::time::Duration::from_millis(500)); - group.measurement_time(std::time::Duration::from_secs(4)); + group.warm_up_time(core::time::Duration::from_millis(500)); + group.measurement_time(core::time::Duration::from_secs(4)); group.bench_function("0_entities", |bencher| { let mut world = World::default(); @@ -32,8 +32,8 @@ pub fn empty_commands(criterion: &mut Criterion) { pub fn spawn_commands(criterion: &mut Criterion) { let mut group = criterion.benchmark_group("spawn_commands"); - group.warm_up_time(std::time::Duration::from_millis(500)); - group.measurement_time(std::time::Duration::from_secs(4)); + group.warm_up_time(core::time::Duration::from_millis(500)); + group.measurement_time(core::time::Duration::from_secs(4)); for entity_count in (1..5).map(|i| i * 2 * 1000) { group.bench_function(format!("{}_entities", entity_count), |bencher| { @@ -69,8 +69,8 @@ struct Vec3([f32; 3]); pub fn insert_commands(criterion: &mut Criterion) { let mut group = criterion.benchmark_group("insert_commands"); - group.warm_up_time(std::time::Duration::from_millis(500)); - group.measurement_time(std::time::Duration::from_secs(4)); + group.warm_up_time(core::time::Duration::from_millis(500)); + group.measurement_time(core::time::Duration::from_secs(4)); let entity_count = 10_000; group.bench_function("insert", |bencher| { @@ -132,8 +132,8 @@ impl Command for FakeCommandB { pub fn fake_commands(criterion: &mut Criterion) { let mut group = criterion.benchmark_group("fake_commands"); - group.warm_up_time(std::time::Duration::from_millis(500)); - group.measurement_time(std::time::Duration::from_secs(4)); + group.warm_up_time(core::time::Duration::from_millis(500)); + group.measurement_time(core::time::Duration::from_secs(4)); for command_count in (1..5).map(|i| i * 2 * 1000) { group.bench_function(format!("{}_commands", command_count), |bencher| { @@ -177,8 +177,8 @@ impl Default for LargeStruct { pub fn sized_commands_impl(criterion: &mut Criterion) { let mut group = criterion.benchmark_group(format!("sized_commands_{}_bytes", size_of::())); - group.warm_up_time(std::time::Duration::from_millis(500)); - group.measurement_time(std::time::Duration::from_secs(4)); + group.warm_up_time(core::time::Duration::from_millis(500)); + group.measurement_time(core::time::Duration::from_secs(4)); for command_count in (1..5).map(|i| i * 2 * 1000) { group.bench_function(format!("{}_commands", command_count), |bencher| { @@ -212,8 +212,8 @@ pub fn large_sized_commands(criterion: &mut Criterion) { pub fn get_or_spawn(criterion: &mut Criterion) { let mut group = criterion.benchmark_group("get_or_spawn"); - group.warm_up_time(std::time::Duration::from_millis(500)); - group.measurement_time(std::time::Duration::from_secs(4)); + group.warm_up_time(core::time::Duration::from_millis(500)); + group.measurement_time(core::time::Duration::from_secs(4)); group.bench_function("individual", |bencher| { let mut world = World::default(); diff --git a/benches/benches/bevy_ecs/world/entity_hash.rs b/benches/benches/bevy_ecs/world/entity_hash.rs index c337e9d86a401..3bd148d90da63 100644 --- a/benches/benches/bevy_ecs/world/entity_hash.rs +++ b/benches/benches/bevy_ecs/world/entity_hash.rs @@ -33,7 +33,7 @@ pub fn entity_set_build_and_lookup(c: &mut Criterion) { // Get some random-but-consistent entities to use for all the benches below. let mut rng = ChaCha8Rng::seed_from_u64(size as u64); let entities = - Vec::from_iter(std::iter::repeat_with(|| make_entity(&mut rng, size)).take(size)); + Vec::from_iter(core::iter::repeat_with(|| make_entity(&mut rng, size)).take(size)); group.throughput(Throughput::Elements(size as u64)); group.bench_function(BenchmarkId::new("entity_set_build", size), |bencher| { diff --git a/benches/benches/bevy_ecs/world/spawn.rs b/benches/benches/bevy_ecs/world/spawn.rs index 0404209eaace2..0777a20cb9827 100644 --- a/benches/benches/bevy_ecs/world/spawn.rs +++ b/benches/benches/bevy_ecs/world/spawn.rs @@ -9,8 +9,8 @@ struct B(Vec4); pub fn world_spawn(criterion: &mut Criterion) { let mut group = criterion.benchmark_group("spawn_world"); - group.warm_up_time(std::time::Duration::from_millis(500)); - group.measurement_time(std::time::Duration::from_secs(4)); + group.warm_up_time(core::time::Duration::from_millis(500)); + group.measurement_time(core::time::Duration::from_secs(4)); for entity_count in (0..5).map(|i| 10_u32.pow(i)) { group.bench_function(format!("{}_entities", entity_count), |bencher| { diff --git a/benches/benches/bevy_ecs/world/world_get.rs b/benches/benches/bevy_ecs/world/world_get.rs index 4812d44f6bca6..4c235cd1b46e3 100644 --- a/benches/benches/bevy_ecs/world/world_get.rs +++ b/benches/benches/bevy_ecs/world/world_get.rs @@ -22,7 +22,7 @@ struct WideTable(f32); #[component(storage = "SparseSet")] struct WideSparse(f32); -const RANGE: std::ops::Range = 5..6; +const RANGE: core::ops::Range = 5..6; fn deterministic_rand() -> ChaCha8Rng { ChaCha8Rng::seed_from_u64(42) @@ -42,8 +42,8 @@ fn setup_wide(entity_count: u32) -> World { pub fn world_entity(criterion: &mut Criterion) { let mut group = criterion.benchmark_group("world_entity"); - group.warm_up_time(std::time::Duration::from_millis(500)); - group.measurement_time(std::time::Duration::from_secs(4)); + group.warm_up_time(core::time::Duration::from_millis(500)); + group.measurement_time(core::time::Duration::from_secs(4)); for entity_count in RANGE.map(|i| i * 10_000) { group.bench_function(format!("{}_entities", entity_count), |bencher| { @@ -63,8 +63,8 @@ pub fn world_entity(criterion: &mut Criterion) { pub fn world_get(criterion: &mut Criterion) { let mut group = criterion.benchmark_group("world_get"); - group.warm_up_time(std::time::Duration::from_millis(500)); - group.measurement_time(std::time::Duration::from_secs(4)); + group.warm_up_time(core::time::Duration::from_millis(500)); + group.measurement_time(core::time::Duration::from_secs(4)); for entity_count in RANGE.map(|i| i * 10_000) { group.bench_function(format!("{}_entities_table", entity_count), |bencher| { @@ -94,8 +94,8 @@ pub fn world_get(criterion: &mut Criterion) { pub fn world_query_get(criterion: &mut Criterion) { let mut group = criterion.benchmark_group("world_query_get"); - group.warm_up_time(std::time::Duration::from_millis(500)); - group.measurement_time(std::time::Duration::from_secs(4)); + group.warm_up_time(core::time::Duration::from_millis(500)); + group.measurement_time(core::time::Duration::from_secs(4)); for entity_count in RANGE.map(|i| i * 10_000) { group.bench_function(format!("{}_entities_table", entity_count), |bencher| { @@ -180,8 +180,8 @@ pub fn world_query_get(criterion: &mut Criterion) { pub fn world_query_iter(criterion: &mut Criterion) { let mut group = criterion.benchmark_group("world_query_iter"); - group.warm_up_time(std::time::Duration::from_millis(500)); - group.measurement_time(std::time::Duration::from_secs(4)); + group.warm_up_time(core::time::Duration::from_millis(500)); + group.measurement_time(core::time::Duration::from_secs(4)); for entity_count in RANGE.map(|i| i * 10_000) { group.bench_function(format!("{}_entities_table", entity_count), |bencher| { @@ -219,8 +219,8 @@ pub fn world_query_iter(criterion: &mut Criterion) { pub fn world_query_for_each(criterion: &mut Criterion) { let mut group = criterion.benchmark_group("world_query_for_each"); - group.warm_up_time(std::time::Duration::from_millis(500)); - group.measurement_time(std::time::Duration::from_secs(4)); + group.warm_up_time(core::time::Duration::from_millis(500)); + group.measurement_time(core::time::Duration::from_secs(4)); for entity_count in RANGE.map(|i| i * 10_000) { group.bench_function(format!("{}_entities_table", entity_count), |bencher| { @@ -258,8 +258,8 @@ pub fn world_query_for_each(criterion: &mut Criterion) { pub fn query_get(criterion: &mut Criterion) { let mut group = criterion.benchmark_group("query_get"); - group.warm_up_time(std::time::Duration::from_millis(500)); - group.measurement_time(std::time::Duration::from_secs(4)); + group.warm_up_time(core::time::Duration::from_millis(500)); + group.measurement_time(core::time::Duration::from_secs(4)); for entity_count in RANGE.map(|i| i * 10_000) { group.bench_function(format!("{}_entities_table", entity_count), |bencher| { @@ -307,8 +307,8 @@ pub fn query_get(criterion: &mut Criterion) { pub fn query_get_many(criterion: &mut Criterion) { let mut group = criterion.benchmark_group(&format!("query_get_many_{N}")); - group.warm_up_time(std::time::Duration::from_millis(500)); - group.measurement_time(std::time::Duration::from_secs(2 * N as u64)); + group.warm_up_time(core::time::Duration::from_millis(500)); + group.measurement_time(core::time::Duration::from_secs(2 * N as u64)); for entity_count in RANGE.map(|i| i * 10_000) { group.bench_function(format!("{}_calls_table", entity_count), |bencher| { diff --git a/benches/benches/bevy_reflect/list.rs b/benches/benches/bevy_reflect/list.rs index 0c366e0540557..e5fffaa3cddf0 100644 --- a/benches/benches/bevy_reflect/list.rs +++ b/benches/benches/bevy_reflect/list.rs @@ -1,4 +1,4 @@ -use std::{iter, time::Duration}; +use core::{iter, time::Duration}; use bevy_reflect::{DynamicList, List}; use criterion::{ diff --git a/benches/benches/bevy_reflect/map.rs b/benches/benches/bevy_reflect/map.rs index b27a096d3d072..ae3894881358e 100644 --- a/benches/benches/bevy_reflect/map.rs +++ b/benches/benches/bevy_reflect/map.rs @@ -1,4 +1,4 @@ -use std::{fmt::Write, iter, time::Duration}; +use core::{fmt::Write, iter, time::Duration}; use bevy_reflect::{DynamicMap, Map}; use bevy_utils::HashMap; diff --git a/benches/benches/bevy_reflect/path.rs b/benches/benches/bevy_reflect/path.rs index bc9af799d44cc..f18885132ac3f 100644 --- a/benches/benches/bevy_reflect/path.rs +++ b/benches/benches/bevy_reflect/path.rs @@ -1,4 +1,4 @@ -use std::{fmt::Write, str, time::Duration}; +use core::{fmt::Write, str, time::Duration}; use bevy_reflect::ParsedPath; use criterion::{ diff --git a/benches/benches/bevy_reflect/struct.rs b/benches/benches/bevy_reflect/struct.rs index 9c6163d24d3a3..0a38088666f84 100644 --- a/benches/benches/bevy_reflect/struct.rs +++ b/benches/benches/bevy_reflect/struct.rs @@ -1,4 +1,4 @@ -use std::time::Duration; +use core::time::Duration; use bevy_reflect::{DynamicStruct, GetField, PartialReflect, Reflect, Struct}; use criterion::{ diff --git a/benches/benches/bevy_tasks/iter.rs b/benches/benches/bevy_tasks/iter.rs index ee1babf4e2f46..3d4410926cf11 100644 --- a/benches/benches/bevy_tasks/iter.rs +++ b/benches/benches/bevy_tasks/iter.rs @@ -1,22 +1,22 @@ use bevy_tasks::{ParallelIterator, TaskPoolBuilder}; use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion}; -struct ParChunks<'a, T>(std::slice::Chunks<'a, T>); -impl<'a, T> ParallelIterator> for ParChunks<'a, T> +struct ParChunks<'a, T>(core::slice::Chunks<'a, T>); +impl<'a, T> ParallelIterator> for ParChunks<'a, T> where T: 'a + Send + Sync, { - fn next_batch(&mut self) -> Option> { + fn next_batch(&mut self) -> Option> { self.0.next().map(|s| s.iter()) } } -struct ParChunksMut<'a, T>(std::slice::ChunksMut<'a, T>); -impl<'a, T> ParallelIterator> for ParChunksMut<'a, T> +struct ParChunksMut<'a, T>(core::slice::ChunksMut<'a, T>); +impl<'a, T> ParallelIterator> for ParChunksMut<'a, T> where T: 'a + Send + Sync, { - fn next_batch(&mut self) -> Option> { + fn next_batch(&mut self) -> Option> { self.0.next().map(|s| s.iter_mut()) } } diff --git a/crates/bevy_a11y/src/lib.rs b/crates/bevy_a11y/src/lib.rs index bb5cbc71cd7d4..f73a529f33e0b 100644 --- a/crates/bevy_a11y/src/lib.rs +++ b/crates/bevy_a11y/src/lib.rs @@ -7,10 +7,10 @@ //! Accessibility for Bevy -use std::sync::{ - atomic::{AtomicBool, Ordering}, - Arc, -}; +extern crate alloc; + +use alloc::sync::Arc; +use core::sync::atomic::{AtomicBool, Ordering}; pub use accesskit; use accesskit::NodeBuilder; diff --git a/crates/bevy_animation/src/graph.rs b/crates/bevy_animation/src/graph.rs index 916cfa26f694d..1ce683409a3f9 100644 --- a/crates/bevy_animation/src/graph.rs +++ b/crates/bevy_animation/src/graph.rs @@ -1,9 +1,7 @@ //! The animation graph, which allows animations to be blended together. -use std::{ - io::{self, Write}, - ops::{Index, IndexMut}, -}; +use core::ops::{Index, IndexMut}; +use std::io::{self, Write}; use bevy_asset::{io::Reader, Asset, AssetId, AssetLoader, AssetPath, Handle, LoadContext}; use bevy_reflect::{Reflect, ReflectSerialize}; diff --git a/crates/bevy_animation/src/keyframes.rs b/crates/bevy_animation/src/keyframes.rs index bed12e1908723..11eca23141c47 100644 --- a/crates/bevy_animation/src/keyframes.rs +++ b/crates/bevy_animation/src/keyframes.rs @@ -1,6 +1,6 @@ //! Keyframes of animation clips. -use std::{ +use core::{ any::TypeId, fmt::{self, Debug, Formatter}, }; diff --git a/crates/bevy_animation/src/lib.rs b/crates/bevy_animation/src/lib.rs index e6d8b3294a773..f334ae7811e1a 100755 --- a/crates/bevy_animation/src/lib.rs +++ b/crates/bevy_animation/src/lib.rs @@ -7,16 +7,18 @@ //! Animation for the game engine Bevy +extern crate alloc; + pub mod animatable; pub mod graph; pub mod keyframes; pub mod transition; mod util; -use std::{ +use alloc::collections::BTreeMap; +use core::{ any::{Any, TypeId}, cell::RefCell, - collections::BTreeMap, fmt::Debug, hash::{Hash, Hasher}, iter, diff --git a/crates/bevy_app/src/app.rs b/crates/bevy_app/src/app.rs index 6cd6d181a611b..0c5950bbb1fdf 100644 --- a/crates/bevy_app/src/app.rs +++ b/crates/bevy_app/src/app.rs @@ -13,10 +13,9 @@ use bevy_ecs::{ #[cfg(feature = "trace")] use bevy_utils::tracing::info_span; use bevy_utils::{tracing::debug, HashMap}; +use core::{fmt::Debug, num::NonZero, panic::AssertUnwindSafe}; use std::{ - fmt::Debug, - num::NonZero, - panic::{catch_unwind, resume_unwind, AssertUnwindSafe}, + panic::{catch_unwind, resume_unwind}, process::{ExitCode, Termination}, }; use thiserror::Error; @@ -77,7 +76,7 @@ pub struct App { } impl Debug for App { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { write!(f, "App {{ sub_apps: ")?; f.debug_map() .entries(self.sub_apps.sub_apps.iter()) @@ -165,8 +164,8 @@ impl App { panic!("App::run() was called while a plugin was building."); } - let runner = std::mem::replace(&mut self.runner, Box::new(run_once)); - let app = std::mem::replace(self, App::empty()); + let runner = core::mem::replace(&mut self.runner, Box::new(run_once)); + let app = core::mem::replace(self, App::empty()); (runner)(app) } @@ -210,7 +209,7 @@ impl App { let mut overall_plugins_state = match self.main_mut().plugins_state { PluginsState::Adding => { let mut state = PluginsState::Ready; - let plugins = std::mem::take(&mut self.main_mut().plugin_registry); + let plugins = core::mem::take(&mut self.main_mut().plugin_registry); for plugin in &plugins { // plugins installed to main need to see all sub-apps if !plugin.ready(self) { @@ -236,7 +235,7 @@ impl App { /// plugins are ready, but can be useful for situations where you want to use [`App::update`]. pub fn finish(&mut self) { // plugins installed to main should see all sub-apps - let plugins = std::mem::take(&mut self.main_mut().plugin_registry); + let plugins = core::mem::take(&mut self.main_mut().plugin_registry); for plugin in &plugins { plugin.finish(self); } @@ -250,7 +249,7 @@ impl App { /// [`App::finish`], but can be useful for situations where you want to use [`App::update`]. pub fn cleanup(&mut self) { // plugins installed to main should see all sub-apps - let plugins = std::mem::take(&mut self.main_mut().plugin_registry); + let plugins = core::mem::take(&mut self.main_mut().plugin_registry); for plugin in &plugins { plugin.cleanup(self); } @@ -744,7 +743,7 @@ impl App { #[cfg(feature = "reflect_functions")] pub fn register_function_with_name( &mut self, - name: impl Into>, + name: impl Into>, function: F, ) -> &mut Self where @@ -1116,7 +1115,8 @@ impl Termination for AppExit { #[cfg(test)] mod tests { - use std::{iter, marker::PhantomData, sync::Mutex}; + use core::{iter, marker::PhantomData}; + use std::sync::Mutex; use bevy_ecs::{ change_detection::{DetectChanges, ResMut}, diff --git a/crates/bevy_app/src/lib.rs b/crates/bevy_app/src/lib.rs index 8ea7c0e767566..830772803bec0 100644 --- a/crates/bevy_app/src/lib.rs +++ b/crates/bevy_app/src/lib.rs @@ -7,6 +7,8 @@ //! This crate is about everything concerning the highest-level, application layer of a Bevy app. +extern crate alloc; + mod app; mod main_schedule; mod panic_handler; diff --git a/crates/bevy_app/src/plugin.rs b/crates/bevy_app/src/plugin.rs index 23b5be13e13d2..0659c6a311884 100644 --- a/crates/bevy_app/src/plugin.rs +++ b/crates/bevy_app/src/plugin.rs @@ -1,7 +1,7 @@ use downcast_rs::{impl_downcast, Downcast}; use crate::App; -use std::any::Any; +use core::any::Any; /// A collection of Bevy app logic and configuration. /// @@ -82,7 +82,7 @@ pub trait Plugin: Downcast + Any + Send + Sync { /// Configures a name for the [`Plugin`] which is primarily used for checking plugin /// uniqueness and debugging. fn name(&self) -> &str { - std::any::type_name::() + core::any::type_name::() } /// If the plugin can be meaningfully instantiated several times in an [`App`], diff --git a/crates/bevy_app/src/plugin_group.rs b/crates/bevy_app/src/plugin_group.rs index be6f2c229a557..2fbff372f784f 100644 --- a/crates/bevy_app/src/plugin_group.rs +++ b/crates/bevy_app/src/plugin_group.rs @@ -3,7 +3,7 @@ use bevy_utils::{ tracing::{debug, warn}, TypeIdMap, }; -use std::any::TypeId; +use core::any::TypeId; /// A macro for generating a well-documented [`PluginGroup`] from a list of [`Plugin`] paths. /// @@ -163,7 +163,7 @@ pub trait PluginGroup: Sized { fn build(self) -> PluginGroupBuilder; /// Configures a name for the [`PluginGroup`] which is primarily used for debugging. fn name() -> String { - std::any::type_name::().to_string() + core::any::type_name::().to_string() } /// Sets the value of the given [`Plugin`], if it exists fn set(self, plugin: T) -> PluginGroupBuilder { @@ -219,7 +219,7 @@ impl PluginGroupBuilder { Some(i) => i, None => panic!( "Plugin does not exist in group: {}.", - std::any::type_name::() + core::any::type_name::() ), } } @@ -273,7 +273,7 @@ impl PluginGroupBuilder { let entry = self.plugins.get_mut(&TypeId::of::()).unwrap_or_else(|| { panic!( "{} does not exist in this PluginGroup", - std::any::type_name::(), + core::any::type_name::(), ) }); entry.plugin = Box::new(plugin); @@ -437,9 +437,9 @@ mod tests { assert_eq!( group.order, vec![ - std::any::TypeId::of::(), - std::any::TypeId::of::(), - std::any::TypeId::of::(), + core::any::TypeId::of::(), + core::any::TypeId::of::(), + core::any::TypeId::of::(), ] ); } @@ -454,9 +454,9 @@ mod tests { assert_eq!( group.order, vec![ - std::any::TypeId::of::(), - std::any::TypeId::of::(), - std::any::TypeId::of::(), + core::any::TypeId::of::(), + core::any::TypeId::of::(), + core::any::TypeId::of::(), ] ); } @@ -471,9 +471,9 @@ mod tests { assert_eq!( group.order, vec![ - std::any::TypeId::of::(), - std::any::TypeId::of::(), - std::any::TypeId::of::(), + core::any::TypeId::of::(), + core::any::TypeId::of::(), + core::any::TypeId::of::(), ] ); } @@ -489,9 +489,9 @@ mod tests { assert_eq!( group.order, vec![ - std::any::TypeId::of::(), - std::any::TypeId::of::(), - std::any::TypeId::of::(), + core::any::TypeId::of::(), + core::any::TypeId::of::(), + core::any::TypeId::of::(), ] ); } @@ -507,9 +507,9 @@ mod tests { assert_eq!( group.order, vec![ - std::any::TypeId::of::(), - std::any::TypeId::of::(), - std::any::TypeId::of::(), + core::any::TypeId::of::(), + core::any::TypeId::of::(), + core::any::TypeId::of::(), ] ); } @@ -525,9 +525,9 @@ mod tests { assert_eq!( group.order, vec![ - std::any::TypeId::of::(), - std::any::TypeId::of::(), - std::any::TypeId::of::(), + core::any::TypeId::of::(), + core::any::TypeId::of::(), + core::any::TypeId::of::(), ] ); } @@ -545,9 +545,9 @@ mod tests { assert_eq!( group_b.order, vec![ - std::any::TypeId::of::(), - std::any::TypeId::of::(), - std::any::TypeId::of::(), + core::any::TypeId::of::(), + core::any::TypeId::of::(), + core::any::TypeId::of::(), ] ); } @@ -569,9 +569,9 @@ mod tests { assert_eq!( group.order, vec![ - std::any::TypeId::of::(), - std::any::TypeId::of::(), - std::any::TypeId::of::(), + core::any::TypeId::of::(), + core::any::TypeId::of::(), + core::any::TypeId::of::(), ] ); } diff --git a/crates/bevy_app/src/schedule_runner.rs b/crates/bevy_app/src/schedule_runner.rs index 1d697ca00eb37..01c43fde6f2ae 100644 --- a/crates/bevy_app/src/schedule_runner.rs +++ b/crates/bevy_app/src/schedule_runner.rs @@ -6,9 +6,11 @@ use crate::{ use bevy_utils::{Duration, Instant}; #[cfg(target_arch = "wasm32")] -use std::{cell::RefCell, rc::Rc}; -#[cfg(target_arch = "wasm32")] -use wasm_bindgen::{prelude::*, JsCast}; +use { + alloc::rc::Rc, + core::cell::RefCell, + wasm_bindgen::{prelude::*, JsCast}, +}; /// Determines the method used to run an [`App`]'s [`Schedule`](bevy_ecs::schedule::Schedule). /// diff --git a/crates/bevy_app/src/sub_app.rs b/crates/bevy_app/src/sub_app.rs index e0d6f86f80650..901ce891a4a62 100644 --- a/crates/bevy_app/src/sub_app.rs +++ b/crates/bevy_app/src/sub_app.rs @@ -9,7 +9,7 @@ use bevy_ecs::{ #[cfg(feature = "trace")] use bevy_utils::tracing::info_span; use bevy_utils::{HashMap, HashSet}; -use std::fmt::Debug; +use core::fmt::Debug; type ExtractFn = Box; @@ -75,7 +75,7 @@ pub struct SubApp { } impl Debug for SubApp { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { write!(f, "SubApp") } } @@ -109,9 +109,9 @@ impl SubApp { F: FnOnce(&mut App), { let mut app = App::empty(); - std::mem::swap(self, &mut app.sub_apps.main); + core::mem::swap(self, &mut app.sub_apps.main); f(&mut app); - std::mem::swap(self, &mut app.sub_apps.main); + core::mem::swap(self, &mut app.sub_apps.main); } /// Returns a reference to the [`World`]. @@ -327,7 +327,7 @@ impl SubApp { where T: Plugin, { - self.plugin_names.contains(std::any::type_name::()) + self.plugin_names.contains(core::any::type_name::()) } /// See [`App::get_added_plugins`]. @@ -352,7 +352,7 @@ impl SubApp { match self.plugins_state { PluginsState::Adding => { let mut state = PluginsState::Ready; - let plugins = std::mem::take(&mut self.plugin_registry); + let plugins = core::mem::take(&mut self.plugin_registry); self.run_as_app(|app| { for plugin in &plugins { if !plugin.ready(app) { @@ -370,7 +370,7 @@ impl SubApp { /// Runs [`Plugin::finish`] for each plugin. pub fn finish(&mut self) { - let plugins = std::mem::take(&mut self.plugin_registry); + let plugins = core::mem::take(&mut self.plugin_registry); self.run_as_app(|app| { for plugin in &plugins { plugin.finish(app); @@ -382,7 +382,7 @@ impl SubApp { /// Runs [`Plugin::cleanup`] for each plugin. pub fn cleanup(&mut self) { - let plugins = std::mem::take(&mut self.plugin_registry); + let plugins = core::mem::take(&mut self.plugin_registry); self.run_as_app(|app| { for plugin in &plugins { plugin.cleanup(app); @@ -428,7 +428,7 @@ impl SubApp { #[cfg(feature = "reflect_functions")] pub fn register_function_with_name( &mut self, - name: impl Into>, + name: impl Into>, function: F, ) -> &mut Self where @@ -472,12 +472,12 @@ impl SubApps { /// Returns an iterator over the sub-apps (starting with the main one). pub fn iter(&self) -> impl Iterator + '_ { - std::iter::once(&self.main).chain(self.sub_apps.values()) + core::iter::once(&self.main).chain(self.sub_apps.values()) } /// Returns a mutable iterator over the sub-apps (starting with the main one). pub fn iter_mut(&mut self) -> impl Iterator + '_ { - std::iter::once(&mut self.main).chain(self.sub_apps.values_mut()) + core::iter::once(&mut self.main).chain(self.sub_apps.values_mut()) } /// Extract data from the main world into the [`SubApp`] with the given label and perform an update if it exists. diff --git a/crates/bevy_app/src/terminal_ctrl_c_handler.rs b/crates/bevy_app/src/terminal_ctrl_c_handler.rs index 8bd90ffaa62b3..b42fb47f6f676 100644 --- a/crates/bevy_app/src/terminal_ctrl_c_handler.rs +++ b/crates/bevy_app/src/terminal_ctrl_c_handler.rs @@ -1,4 +1,4 @@ -use std::sync::atomic::{AtomicBool, Ordering}; +use core::sync::atomic::{AtomicBool, Ordering}; use bevy_ecs::event::EventWriter; diff --git a/crates/bevy_asset/src/assets.rs b/crates/bevy_asset/src/assets.rs index c9cab3af64942..3c33aa43faf91 100644 --- a/crates/bevy_asset/src/assets.rs +++ b/crates/bevy_asset/src/assets.rs @@ -2,20 +2,16 @@ use crate::{ self as bevy_asset, Asset, AssetEvent, AssetHandleProvider, AssetId, AssetServer, Handle, UntypedHandle, }; +use alloc::sync::Arc; use bevy_ecs::{ prelude::EventWriter, system::{Res, ResMut, Resource}, }; use bevy_reflect::{Reflect, TypePath}; use bevy_utils::HashMap; +use core::{any::TypeId, iter::Enumerate, marker::PhantomData, sync::atomic::AtomicU32}; use crossbeam_channel::{Receiver, Sender}; use serde::{Deserialize, Serialize}; -use std::{ - any::TypeId, - iter::Enumerate, - marker::PhantomData, - sync::{atomic::AtomicU32, Arc}, -}; use thiserror::Error; use uuid::Uuid; @@ -83,7 +79,7 @@ impl AssetIndexAllocator { AssetIndex { index: self .next_index - .fetch_add(1, std::sync::atomic::Ordering::Relaxed), + .fetch_add(1, core::sync::atomic::Ordering::Relaxed), generation: 0, } } @@ -238,7 +234,7 @@ impl DenseAssetStorage { let new_len = self .allocator .next_index - .load(std::sync::atomic::Ordering::Relaxed); + .load(core::sync::atomic::Ordering::Relaxed); self.storage.resize_with(new_len as usize, || Entry::Some { value: None, generation: 0, @@ -579,7 +575,7 @@ impl Assets { /// A mutable iterator over [`Assets`]. pub struct AssetsMutIterator<'a, A: Asset> { queued_events: &'a mut Vec>, - dense_storage: Enumerate>>, + dense_storage: Enumerate>>, hash_map: bevy_utils::hashbrown::hash_map::IterMut<'a, Uuid, A>, } diff --git a/crates/bevy_asset/src/event.rs b/crates/bevy_asset/src/event.rs index f049751bb79c3..406d2398ea287 100644 --- a/crates/bevy_asset/src/event.rs +++ b/crates/bevy_asset/src/event.rs @@ -1,6 +1,6 @@ use crate::{Asset, AssetId, AssetLoadError, AssetPath, UntypedAssetId}; use bevy_ecs::event::Event; -use std::fmt::Debug; +use core::fmt::Debug; /// An event emitted when a specific [`Asset`] fails to load. /// @@ -92,7 +92,7 @@ impl Clone for AssetEvent { impl Copy for AssetEvent {} impl Debug for AssetEvent { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { match self { Self::Added { id } => f.debug_struct("Added").field("id", id).finish(), Self::Modified { id } => f.debug_struct("Modified").field("id", id).finish(), diff --git a/crates/bevy_asset/src/handle.rs b/crates/bevy_asset/src/handle.rs index 6371b7e01ba0f..08e10e8e620bf 100644 --- a/crates/bevy_asset/src/handle.rs +++ b/crates/bevy_asset/src/handle.rs @@ -2,15 +2,15 @@ use crate::{ meta::MetaTransform, Asset, AssetId, AssetIndexAllocator, AssetPath, InternalAssetId, UntypedAssetId, }; +use alloc::sync::Arc; use bevy_ecs::prelude::*; use bevy_reflect::{std_traits::ReflectDefault, Reflect, TypePath}; -use crossbeam_channel::{Receiver, Sender}; -use disqualified::ShortName; -use std::{ +use core::{ any::TypeId, hash::{Hash, Hasher}, - sync::Arc, }; +use crossbeam_channel::{Receiver, Sender}; +use disqualified::ShortName; use thiserror::Error; use uuid::Uuid; @@ -103,8 +103,8 @@ impl Drop for StrongHandle { } } -impl std::fmt::Debug for StrongHandle { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl core::fmt::Debug for StrongHandle { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { f.debug_struct("StrongHandle") .field("id", &self.id) .field("asset_server_managed", &self.asset_server_managed) @@ -204,8 +204,8 @@ impl Default for Handle { } } -impl std::fmt::Debug for Handle { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl core::fmt::Debug for Handle { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { let name = ShortName::of::(); match self { Handle::Strong(handle) => { @@ -229,13 +229,13 @@ impl Hash for Handle { } impl PartialOrd for Handle { - fn partial_cmp(&self, other: &Self) -> Option { + fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } impl Ord for Handle { - fn cmp(&self, other: &Self) -> std::cmp::Ordering { + fn cmp(&self, other: &Self) -> core::cmp::Ordering { self.id().cmp(&other.id()) } } @@ -357,7 +357,7 @@ impl UntypedHandle { let Ok(handle) = self.try_typed() else { panic!( "The target Handle<{}>'s TypeId does not match the TypeId of this UntypedHandle", - std::any::type_name::() + core::any::type_name::() ) }; @@ -397,8 +397,8 @@ impl Hash for UntypedHandle { } } -impl std::fmt::Debug for UntypedHandle { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl core::fmt::Debug for UntypedHandle { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { match self { UntypedHandle::Strong(handle) => { write!( @@ -420,7 +420,7 @@ impl std::fmt::Debug for UntypedHandle { } impl PartialOrd for UntypedHandle { - fn partial_cmp(&self, other: &Self) -> Option { + fn partial_cmp(&self, other: &Self) -> Option { if self.type_id() == other.type_id() { self.id().partial_cmp(&other.id()) } else { @@ -454,7 +454,7 @@ impl PartialEq> for UntypedHandle { impl PartialOrd for Handle { #[inline] - fn partial_cmp(&self, other: &UntypedHandle) -> Option { + fn partial_cmp(&self, other: &UntypedHandle) -> Option { if TypeId::of::() != other.type_id() { None } else { @@ -465,7 +465,7 @@ impl PartialOrd for Handle { impl PartialOrd> for UntypedHandle { #[inline] - fn partial_cmp(&self, other: &Handle) -> Option { + fn partial_cmp(&self, other: &Handle) -> Option { Some(other.partial_cmp(self)?.reverse()) } } diff --git a/crates/bevy_asset/src/id.rs b/crates/bevy_asset/src/id.rs index f1a28d7e02f2c..1cca57278eb91 100644 --- a/crates/bevy_asset/src/id.rs +++ b/crates/bevy_asset/src/id.rs @@ -3,7 +3,7 @@ use bevy_reflect::Reflect; use serde::{Deserialize, Serialize}; use uuid::Uuid; -use std::{ +use core::{ any::TypeId, fmt::{Debug, Display}, hash::Hash, @@ -86,19 +86,19 @@ impl Clone for AssetId { impl Copy for AssetId {} impl Display for AssetId { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { Debug::fmt(self, f) } } impl Debug for AssetId { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { match self { AssetId::Index { index, .. } => { write!( f, "AssetId<{}>{{ index: {}, generation: {}}}", - std::any::type_name::(), + core::any::type_name::(), index.index, index.generation ) @@ -107,7 +107,7 @@ impl Debug for AssetId { write!( f, "AssetId<{}>{{uuid: {}}}", - std::any::type_name::(), + core::any::type_name::(), uuid ) } @@ -117,7 +117,7 @@ impl Debug for AssetId { impl Hash for AssetId { #[inline] - fn hash(&self, state: &mut H) { + fn hash(&self, state: &mut H) { self.internal().hash(state); TypeId::of::().hash(state); } @@ -133,13 +133,13 @@ impl PartialEq for AssetId { impl Eq for AssetId {} impl PartialOrd for AssetId { - fn partial_cmp(&self, other: &Self) -> Option { + fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } impl Ord for AssetId { - fn cmp(&self, other: &Self) -> std::cmp::Ordering { + fn cmp(&self, other: &Self) -> core::cmp::Ordering { self.internal().cmp(&other.internal()) } } @@ -206,7 +206,7 @@ impl UntypedAssetId { self.type_id(), TypeId::of::(), "The target AssetId<{}>'s TypeId does not match the TypeId of this UntypedAssetId", - std::any::type_name::() + core::any::type_name::() ); self.typed_unchecked() } @@ -221,7 +221,7 @@ impl UntypedAssetId { let Ok(id) = self.try_typed() else { panic!( "The target AssetId<{}>'s TypeId does not match the TypeId of this UntypedAssetId", - std::any::type_name::() + core::any::type_name::() ) }; @@ -254,7 +254,7 @@ impl UntypedAssetId { } impl Display for UntypedAssetId { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { let mut writer = f.debug_struct("UntypedAssetId"); match self { UntypedAssetId::Index { index, type_id } => { @@ -282,14 +282,14 @@ impl Eq for UntypedAssetId {} impl Hash for UntypedAssetId { #[inline] - fn hash(&self, state: &mut H) { + fn hash(&self, state: &mut H) { self.internal().hash(state); self.type_id().hash(state); } } impl Ord for UntypedAssetId { - fn cmp(&self, other: &Self) -> std::cmp::Ordering { + fn cmp(&self, other: &Self) -> core::cmp::Ordering { self.type_id() .cmp(&other.type_id()) .then_with(|| self.internal().cmp(&other.internal())) @@ -297,7 +297,7 @@ impl Ord for UntypedAssetId { } impl PartialOrd for UntypedAssetId { - fn partial_cmp(&self, other: &Self) -> Option { + fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } @@ -367,7 +367,7 @@ impl PartialEq> for UntypedAssetId { impl PartialOrd for AssetId { #[inline] - fn partial_cmp(&self, other: &UntypedAssetId) -> Option { + fn partial_cmp(&self, other: &UntypedAssetId) -> Option { if TypeId::of::() != other.type_id() { None } else { @@ -378,7 +378,7 @@ impl PartialOrd for AssetId { impl PartialOrd> for UntypedAssetId { #[inline] - fn partial_cmp(&self, other: &AssetId) -> Option { + fn partial_cmp(&self, other: &AssetId) -> Option { Some(other.partial_cmp(self)?.reverse()) } } @@ -436,7 +436,7 @@ mod tests { /// Simple utility to directly hash a value using a fixed hasher fn hash(data: &T) -> u64 { - use std::hash::Hasher; + use core::hash::Hasher; let mut hasher = bevy_utils::AHasher::default(); data.hash(&mut hasher); diff --git a/crates/bevy_asset/src/io/android.rs b/crates/bevy_asset/src/io/android.rs index 1890a943c82b1..aa708f56ba724 100644 --- a/crates/bevy_asset/src/io/android.rs +++ b/crates/bevy_asset/src/io/android.rs @@ -1,8 +1,9 @@ use crate::io::{ get_meta_path, AssetReader, AssetReaderError, EmptyPathStream, PathStream, Reader, VecReader, }; +use alloc::ffi::CString; use bevy_utils::tracing::error; -use std::{ffi::CString, path::Path}; +use std::path::Path; /// [`AssetReader`] implementation for Android devices, built on top of Android's [`AssetManager`]. /// @@ -52,10 +53,7 @@ impl AssetReader for AndroidAssetReader { Ok(stream) } - async fn is_directory<'a>( - &'a self, - _path: &'a Path, - ) -> std::result::Result { + async fn is_directory<'a>(&'a self, _path: &'a Path) -> Result { error!("Reading directories is not supported with the AndroidAssetReader"); Ok(false) } diff --git a/crates/bevy_asset/src/io/embedded/embedded_watcher.rs b/crates/bevy_asset/src/io/embedded/embedded_watcher.rs index 9a432977a733c..dd863d7cf9285 100644 --- a/crates/bevy_asset/src/io/embedded/embedded_watcher.rs +++ b/crates/bevy_asset/src/io/embedded/embedded_watcher.rs @@ -3,6 +3,7 @@ use crate::io::{ memory::Dir, AssetSourceEvent, AssetWatcher, }; +use alloc::sync::Arc; use bevy_utils::{tracing::warn, Duration, HashMap}; use notify_debouncer_full::{notify::RecommendedWatcher, Debouncer, FileIdMap}; use parking_lot::RwLock; @@ -10,7 +11,6 @@ use std::{ fs::File, io::{BufReader, Read}, path::{Path, PathBuf}, - sync::Arc, }; /// A watcher for assets stored in the `embedded` asset source. Embedded assets are assets whose diff --git a/crates/bevy_asset/src/io/embedded/mod.rs b/crates/bevy_asset/src/io/embedded/mod.rs index b521d3737be5c..af8176d5a0d79 100644 --- a/crates/bevy_asset/src/io/embedded/mod.rs +++ b/crates/bevy_asset/src/io/embedded/mod.rs @@ -22,7 +22,7 @@ pub const EMBEDDED: &str = "embedded"; pub struct EmbeddedAssetRegistry { dir: Dir, #[cfg(feature = "embedded_watcher")] - root_paths: std::sync::Arc, PathBuf>>>, + root_paths: alloc::sync::Arc, PathBuf>>>, } impl EmbeddedAssetRegistry { @@ -107,7 +107,7 @@ impl EmbeddedAssetRegistry { dir.clone(), root_paths.clone(), sender, - std::time::Duration::from_millis(300), + core::time::Duration::from_millis(300), ))) }) .with_processed_watcher(move |sender| { @@ -115,7 +115,7 @@ impl EmbeddedAssetRegistry { processed_dir.clone(), processed_root_paths.clone(), sender, - std::time::Duration::from_millis(300), + core::time::Duration::from_millis(300), ))) }); } diff --git a/crates/bevy_asset/src/io/file/mod.rs b/crates/bevy_asset/src/io/file/mod.rs index 92f99af42e185..387924001f5fd 100644 --- a/crates/bevy_asset/src/io/file/mod.rs +++ b/crates/bevy_asset/src/io/file/mod.rs @@ -73,7 +73,7 @@ impl FileAssetWriter { /// watching for changes. /// /// See `get_base_path` below. - pub fn new + std::fmt::Debug>(path: P, create_root: bool) -> Self { + pub fn new + core::fmt::Debug>(path: P, create_root: bool) -> Self { let root_path = get_base_path().join(path.as_ref()); if create_root { if let Err(e) = std::fs::create_dir_all(&root_path) { diff --git a/crates/bevy_asset/src/io/file/sync_file_asset.rs b/crates/bevy_asset/src/io/file/sync_file_asset.rs index 2ac547e9b7136..188257ddc1006 100644 --- a/crates/bevy_asset/src/io/file/sync_file_asset.rs +++ b/crates/bevy_asset/src/io/file/sync_file_asset.rs @@ -6,12 +6,11 @@ use crate::io::{ Reader, Writer, }; +use core::{pin::Pin, task::Poll}; use std::{ fs::{read_dir, File}, io::{Read, Seek, Write}, path::{Path, PathBuf}, - pin::Pin, - task::Poll, }; use super::{FileAssetReader, FileAssetWriter}; @@ -21,7 +20,7 @@ struct FileReader(File); impl AsyncRead for FileReader { fn poll_read( self: Pin<&mut Self>, - _cx: &mut std::task::Context<'_>, + _cx: &mut core::task::Context<'_>, buf: &mut [u8], ) -> Poll> { let this = self.get_mut(); @@ -33,7 +32,7 @@ impl AsyncRead for FileReader { impl AsyncSeek for FileReader { fn poll_seek( self: Pin<&mut Self>, - _cx: &mut std::task::Context<'_>, + _cx: &mut core::task::Context<'_>, pos: std::io::SeekFrom, ) -> Poll> { let this = self.get_mut(); @@ -57,7 +56,7 @@ struct FileWriter(File); impl AsyncWrite for FileWriter { fn poll_write( self: Pin<&mut Self>, - _cx: &mut std::task::Context<'_>, + _cx: &mut core::task::Context<'_>, buf: &[u8], ) -> Poll> { let this = self.get_mut(); @@ -67,7 +66,7 @@ impl AsyncWrite for FileWriter { fn poll_flush( self: Pin<&mut Self>, - _cx: &mut std::task::Context<'_>, + _cx: &mut core::task::Context<'_>, ) -> Poll> { let this = self.get_mut(); let flushed = this.0.flush(); @@ -76,7 +75,7 @@ impl AsyncWrite for FileWriter { fn poll_close( self: Pin<&mut Self>, - _cx: &mut std::task::Context<'_>, + _cx: &mut core::task::Context<'_>, ) -> Poll> { Poll::Ready(Ok(())) } @@ -89,7 +88,7 @@ impl Stream for DirReader { fn poll_next( self: Pin<&mut Self>, - _cx: &mut std::task::Context<'_>, + _cx: &mut core::task::Context<'_>, ) -> Poll> { let this = self.get_mut(); Poll::Ready(this.0.pop()) diff --git a/crates/bevy_asset/src/io/gated.rs b/crates/bevy_asset/src/io/gated.rs index 1f6e783ce8fbd..cb205f12a81bd 100644 --- a/crates/bevy_asset/src/io/gated.rs +++ b/crates/bevy_asset/src/io/gated.rs @@ -1,8 +1,9 @@ use crate::io::{AssetReader, AssetReaderError, PathStream, Reader}; +use alloc::sync::Arc; use bevy_utils::HashMap; use crossbeam_channel::{Receiver, Sender}; use parking_lot::RwLock; -use std::{path::Path, sync::Arc}; +use std::path::Path; /// A "gated" reader that will prevent asset reads from returning until /// a given path has been "opened" using [`GateOpener`]. diff --git a/crates/bevy_asset/src/io/memory.rs b/crates/bevy_asset/src/io/memory.rs index 082b64b8dc7fd..4164d9bbe906b 100644 --- a/crates/bevy_asset/src/io/memory.rs +++ b/crates/bevy_asset/src/io/memory.rs @@ -1,14 +1,13 @@ use crate::io::{AssetReader, AssetReaderError, PathStream, Reader}; +use alloc::sync::Arc; use bevy_utils::HashMap; +use core::{pin::Pin, task::Poll}; use futures_io::{AsyncRead, AsyncSeek}; use futures_lite::{ready, Stream}; use parking_lot::RwLock; use std::{ io::SeekFrom, path::{Path, PathBuf}, - pin::Pin, - sync::Arc, - task::Poll, }; #[derive(Default, Debug)] @@ -153,7 +152,7 @@ impl Stream for DirStream { fn poll_next( self: Pin<&mut Self>, - _cx: &mut std::task::Context<'_>, + _cx: &mut core::task::Context<'_>, ) -> Poll> { let this = self.get_mut(); let dir = this.dir.0.read(); @@ -234,7 +233,7 @@ struct DataReader { impl AsyncRead for DataReader { fn poll_read( mut self: Pin<&mut Self>, - cx: &mut std::task::Context<'_>, + cx: &mut core::task::Context<'_>, buf: &mut [u8], ) -> Poll> { if self.bytes_read >= self.data.value().len() { @@ -251,7 +250,7 @@ impl AsyncRead for DataReader { impl AsyncSeek for DataReader { fn poll_seek( mut self: Pin<&mut Self>, - _cx: &mut std::task::Context<'_>, + _cx: &mut core::task::Context<'_>, pos: SeekFrom, ) -> Poll> { let result = match pos { diff --git a/crates/bevy_asset/src/io/mod.rs b/crates/bevy_asset/src/io/mod.rs index 4a8815c4012c2..aafa4f1f04990 100644 --- a/crates/bevy_asset/src/io/mod.rs +++ b/crates/bevy_asset/src/io/mod.rs @@ -21,15 +21,18 @@ mod source; pub use futures_lite::AsyncWriteExt; pub use source::*; +use alloc::sync::Arc; use bevy_utils::{BoxedFuture, ConditionalSendFuture}; +use core::{ + mem::size_of, + pin::Pin, + task::{Context, Poll}, +}; use futures_io::{AsyncRead, AsyncSeek, AsyncWrite}; use futures_lite::{ready, Stream}; use std::{ io::SeekFrom, path::{Path, PathBuf}, - pin::Pin, - sync::Arc, - task::{Context, Poll}, }; use thiserror::Error; @@ -713,7 +716,7 @@ impl Stream for EmptyPathStream { fn poll_next( self: Pin<&mut Self>, - _cx: &mut std::task::Context<'_>, + _cx: &mut core::task::Context<'_>, ) -> Poll> { Poll::Ready(None) } diff --git a/crates/bevy_asset/src/io/processor_gated.rs b/crates/bevy_asset/src/io/processor_gated.rs index 4e079e4088134..963af9fd51556 100644 --- a/crates/bevy_asset/src/io/processor_gated.rs +++ b/crates/bevy_asset/src/io/processor_gated.rs @@ -3,10 +3,12 @@ use crate::{ processor::{AssetProcessorData, ProcessStatus}, AssetPath, }; +use alloc::sync::Arc; use async_lock::RwLockReadGuardArc; use bevy_utils::tracing::trace; +use core::{pin::Pin, task::Poll}; use futures_io::{AsyncRead, AsyncSeek}; -use std::{io::SeekFrom, path::Path, pin::Pin, sync::Arc, task::Poll}; +use std::{io::SeekFrom, path::Path}; use super::ErasedAssetReader; @@ -133,7 +135,7 @@ impl<'a> TransactionLockedReader<'a> { impl AsyncRead for TransactionLockedReader<'_> { fn poll_read( mut self: Pin<&mut Self>, - cx: &mut std::task::Context<'_>, + cx: &mut core::task::Context<'_>, buf: &mut [u8], ) -> Poll> { Pin::new(&mut self.reader).poll_read(cx, buf) @@ -143,7 +145,7 @@ impl AsyncRead for TransactionLockedReader<'_> { impl AsyncSeek for TransactionLockedReader<'_> { fn poll_seek( mut self: Pin<&mut Self>, - cx: &mut std::task::Context<'_>, + cx: &mut core::task::Context<'_>, pos: SeekFrom, ) -> Poll> { Pin::new(&mut self.reader).poll_seek(cx, pos) diff --git a/crates/bevy_asset/src/io/source.rs b/crates/bevy_asset/src/io/source.rs index 650537c96fc50..4af5b377d28c8 100644 --- a/crates/bevy_asset/src/io/source.rs +++ b/crates/bevy_asset/src/io/source.rs @@ -2,13 +2,14 @@ use crate::{ io::{processor_gated::ProcessorGatedReader, AssetSourceEvent, AssetWatcher}, processor::AssetProcessorData, }; +use alloc::sync::Arc; use atomicow::CowArc; use bevy_ecs::system::Resource; use bevy_utils::{ tracing::{error, warn}, Duration, HashMap, }; -use std::{fmt::Display, hash::Hash, sync::Arc}; +use core::{fmt::Display, hash::Hash}; use thiserror::Error; use super::{ErasedAssetReader, ErasedAssetWriter}; @@ -27,7 +28,7 @@ pub enum AssetSourceId<'a> { } impl<'a> Display for AssetSourceId<'a> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { match self.as_str() { None => write!(f, "AssetSourceId::Default"), Some(v) => write!(f, "AssetSourceId::Name({v})"), @@ -114,7 +115,7 @@ impl From for AssetSourceId<'static> { } impl<'a> Hash for AssetSourceId<'a> { - fn hash(&self, state: &mut H) { + fn hash(&self, state: &mut H) { self.as_str().hash(state); } } diff --git a/crates/bevy_asset/src/io/wasm.rs b/crates/bevy_asset/src/io/wasm.rs index 6378556fe0e1c..65eb852c257a2 100644 --- a/crates/bevy_asset/src/io/wasm.rs +++ b/crates/bevy_asset/src/io/wasm.rs @@ -106,10 +106,7 @@ impl AssetReader for HttpWasmAssetReader { Ok(stream) } - async fn is_directory<'a>( - &'a self, - _path: &'a Path, - ) -> std::result::Result { + async fn is_directory<'a>(&'a self, _path: &'a Path) -> Result { error!("Reading directories is not supported with the HttpWasmAssetReader"); Ok(false) } diff --git a/crates/bevy_asset/src/lib.rs b/crates/bevy_asset/src/lib.rs index 9e5c24df8407e..df5879609d676 100644 --- a/crates/bevy_asset/src/lib.rs +++ b/crates/bevy_asset/src/lib.rs @@ -147,6 +147,8 @@ html_favicon_url = "https://bevyengine.org/assets/icon.png" )] +extern crate alloc; + pub mod io; pub mod meta; pub mod processor; @@ -199,6 +201,7 @@ use crate::{ io::{embedded::EmbeddedAssetRegistry, AssetSourceBuilder, AssetSourceBuilders, AssetSourceId}, processor::{AssetProcessor, Process}, }; +use alloc::sync::Arc; use bevy_app::{App, Last, Plugin, PreUpdate}; use bevy_ecs::{ reflect::AppTypeRegistry, @@ -207,7 +210,7 @@ use bevy_ecs::{ }; use bevy_reflect::{FromReflect, GetTypeRegistration, Reflect, TypePath}; use bevy_utils::{tracing::error, HashSet}; -use std::{any::TypeId, sync::Arc}; +use core::any::TypeId; #[cfg(all(feature = "file_watcher", not(feature = "multi_threaded")))] compile_error!( @@ -615,6 +618,7 @@ mod tests { AssetPlugin, AssetServer, Assets, DependencyLoadState, LoadState, RecursiveDependencyLoadState, }; + use alloc::sync::Arc; use bevy_app::{App, Update}; use bevy_core::TaskPoolPlugin; use bevy_ecs::{ @@ -626,7 +630,7 @@ mod tests { use bevy_reflect::TypePath; use bevy_utils::{Duration, HashMap}; use serde::{Deserialize, Serialize}; - use std::{path::Path, sync::Arc}; + use std::path::Path; use thiserror::Error; #[derive(Asset, TypePath, Debug, Default)] @@ -1487,7 +1491,7 @@ mod tests { ); // remove event is emitted app.update(); - let events = std::mem::take(&mut app.world_mut().resource_mut::().0); + let events = core::mem::take(&mut app.world_mut().resource_mut::().0); let expected_events = vec![ AssetEvent::Added { id }, AssetEvent::Unused { id }, @@ -1508,14 +1512,14 @@ mod tests { // TODO: ideally it doesn't take two updates for the added event to emit app.update(); - let events = std::mem::take(&mut app.world_mut().resource_mut::().0); + let events = core::mem::take(&mut app.world_mut().resource_mut::().0); let expected_events = vec![AssetEvent::Added { id: a_handle.id() }]; assert_eq!(events, expected_events); gate_opener.open(dep_path); loop { app.update(); - let events = std::mem::take(&mut app.world_mut().resource_mut::().0); + let events = core::mem::take(&mut app.world_mut().resource_mut::().0); if events.is_empty() { continue; } @@ -1529,7 +1533,7 @@ mod tests { break; } app.update(); - let events = std::mem::take(&mut app.world_mut().resource_mut::().0); + let events = core::mem::take(&mut app.world_mut().resource_mut::().0); let expected_events = vec![AssetEvent::Added { id: dep_handle.id(), }]; diff --git a/crates/bevy_asset/src/loader.rs b/crates/bevy_asset/src/loader.rs index 7e2e7cc56cb54..2160b5bf99233 100644 --- a/crates/bevy_asset/src/loader.rs +++ b/crates/bevy_asset/src/loader.rs @@ -9,13 +9,11 @@ use crate::{ use atomicow::CowArc; use bevy_ecs::world::World; use bevy_utils::{BoxedFuture, ConditionalSendFuture, HashMap, HashSet}; +use core::any::{Any, TypeId}; use downcast_rs::{impl_downcast, Downcast}; use ron::error::SpannedError; use serde::{Deserialize, Serialize}; -use std::{ - any::{Any, TypeId}, - path::{Path, PathBuf}, -}; +use std::path::{Path, PathBuf}; use thiserror::Error; /// Loads an [`Asset`] from a given byte [`Reader`]. This can accept [`AssetLoader::Settings`], which configure how the [`Asset`] @@ -30,7 +28,7 @@ pub trait AssetLoader: Send + Sync + 'static { /// The settings type used by this [`AssetLoader`]. type Settings: Settings + Default + Serialize + for<'a> Deserialize<'a>; /// The type of [error](`std::error::Error`) which could be encountered by this loader. - type Error: Into>; + type Error: Into>; /// Asynchronously loads [`AssetLoader::Asset`] (and any other labeled assets) from the bytes provided by [`Reader`]. fn load<'a>( &'a self, @@ -56,7 +54,7 @@ pub trait ErasedAssetLoader: Send + Sync + 'static { load_context: LoadContext<'a>, ) -> BoxedFuture< 'a, - Result>, + Result>, >; /// Returns a list of extensions supported by this asset loader, without the preceding dot. @@ -87,7 +85,7 @@ where mut load_context: LoadContext<'a>, ) -> BoxedFuture< 'a, - Result>, + Result>, > { Box::pin(async move { let settings = meta @@ -119,7 +117,7 @@ where } fn type_name(&self) -> &'static str { - std::any::type_name::() + core::any::type_name::() } fn type_id(&self) -> TypeId { @@ -127,7 +125,7 @@ where } fn asset_type_name(&self) -> &'static str { - std::any::type_name::() + core::any::type_name::() } fn asset_type_id(&self) -> TypeId { @@ -288,7 +286,7 @@ impl AssetContainer for A { } fn asset_type_name(&self) -> &'static str { - std::any::type_name::() + core::any::type_name::() } } diff --git a/crates/bevy_asset/src/loader_builders.rs b/crates/bevy_asset/src/loader_builders.rs index 8bebe9f0bdae5..23cf722803546 100644 --- a/crates/bevy_asset/src/loader_builders.rs +++ b/crates/bevy_asset/src/loader_builders.rs @@ -7,7 +7,8 @@ use crate::{ Asset, AssetLoadError, AssetPath, ErasedAssetLoader, ErasedLoadedAsset, Handle, LoadContext, LoadDirectError, LoadedAsset, LoadedUntypedAsset, }; -use std::{any::TypeId, sync::Arc}; +use alloc::sync::Arc; +use core::any::TypeId; // Utility type for handling the sources of reader references enum ReaderRef<'a> { diff --git a/crates/bevy_asset/src/meta.rs b/crates/bevy_asset/src/meta.rs index 7b65eb8f48db7..53c1db824d578 100644 --- a/crates/bevy_asset/src/meta.rs +++ b/crates/bevy_asset/src/meta.rs @@ -220,7 +220,7 @@ pub(crate) fn meta_transform_settings( } else { error!( "Configured settings type {} does not match AssetLoader settings type", - std::any::type_name::(), + core::any::type_name::(), ); } } diff --git a/crates/bevy_asset/src/path.rs b/crates/bevy_asset/src/path.rs index d52bdc02dd6e0..3bbb643650b6f 100644 --- a/crates/bevy_asset/src/path.rs +++ b/crates/bevy_asset/src/path.rs @@ -1,13 +1,13 @@ use crate::io::AssetSourceId; use atomicow::CowArc; use bevy_reflect::{Reflect, ReflectDeserialize, ReflectSerialize}; -use serde::{de::Visitor, Deserialize, Serialize}; -use std::{ +use core::{ fmt::{Debug, Display}, hash::Hash, ops::Deref, - path::{Path, PathBuf}, }; +use serde::{de::Visitor, Deserialize, Serialize}; +use std::path::{Path, PathBuf}; use thiserror::Error; /// Represents a path to an asset in a "virtual filesystem". @@ -57,13 +57,13 @@ pub struct AssetPath<'a> { } impl<'a> Debug for AssetPath<'a> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { Display::fmt(self, f) } } impl<'a> Display for AssetPath<'a> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { if let AssetSourceId::Name(name) = self.source() { write!(f, "{name}://")?; } @@ -588,7 +588,7 @@ struct AssetPathVisitor; impl<'de> Visitor<'de> for AssetPathVisitor { type Value = AssetPath<'static>; - fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result { formatter.write_str("string AssetPath") } diff --git a/crates/bevy_asset/src/processor/mod.rs b/crates/bevy_asset/src/processor/mod.rs index c93ee65dc2db3..f9fd23f0b71b7 100644 --- a/crates/bevy_asset/src/processor/mod.rs +++ b/crates/bevy_asset/src/processor/mod.rs @@ -56,6 +56,7 @@ use crate::{ AssetLoadError, AssetMetaCheck, AssetPath, AssetServer, AssetServerMode, DeserializeMetaError, MissingAssetLoaderForExtensionError, }; +use alloc::{collections::VecDeque, sync::Arc}; use bevy_ecs::prelude::*; use bevy_tasks::IoTaskPool; use bevy_utils::{ @@ -70,11 +71,7 @@ use bevy_utils::{ use futures_io::ErrorKind; use futures_lite::{AsyncReadExt, AsyncWriteExt, StreamExt}; use parking_lot::RwLock; -use std::{ - collections::VecDeque, - path::{Path, PathBuf}, - sync::Arc, -}; +use std::path::{Path, PathBuf}; use thiserror::Error; /// A "background" asset processor that reads asset values from a source [`AssetSource`] (which corresponds to an [`AssetReader`](crate::io::AssetReader) / [`AssetWriter`](crate::io::AssetWriter) pair), @@ -507,7 +504,7 @@ impl AssetProcessor { async fn try_reprocessing_queued(&self) { loop { let mut check_reprocess_queue = - std::mem::take(&mut self.data.asset_infos.write().await.check_reprocess_queue); + core::mem::take(&mut self.data.asset_infos.write().await.check_reprocess_queue); IoTaskPool::get().scope(|scope| { for path in check_reprocess_queue.drain(..) { let processor = self.clone(); @@ -529,13 +526,13 @@ impl AssetProcessor { let mut process_plans = self.data.processors.write(); #[cfg(feature = "trace")] let processor = InstrumentedAssetProcessor(processor); - process_plans.insert(std::any::type_name::

(), Arc::new(processor)); + process_plans.insert(core::any::type_name::

(), Arc::new(processor)); } /// Set the default processor for the given `extension`. Make sure `P` is registered with [`AssetProcessor::register_processor`]. pub fn set_default_processor(&self, extension: &str) { let mut default_processors = self.data.default_processors.write(); - default_processors.insert(extension.into(), std::any::type_name::

()); + default_processors.insert(extension.into(), core::any::type_name::

()); } /// Returns the default processor for the given `extension`, if it exists. @@ -946,7 +943,7 @@ impl AssetProcessor { } LogEntryError::UnfinishedTransaction(path) => { debug!("Asset {path:?} did not finish processing. Clearing state for that asset"); - let mut unrecoverable_err = |message: &dyn std::fmt::Display| { + let mut unrecoverable_err = |message: &dyn core::fmt::Display| { error!("Failed to remove asset {path:?}: {message}"); state_is_valid = false; }; @@ -1112,7 +1109,7 @@ impl Process for InstrumentedAssetProcessor { }; let span = info_span!( "asset processing", - processor = std::any::type_name::(), + processor = core::any::type_name::(), asset = context.path().to_string(), ); self.0.process(context, meta, writer).instrument(span) @@ -1350,7 +1347,7 @@ impl ProcessorAssetInfos { info.dependants ); self.non_existent_dependants - .insert(old.clone(), std::mem::take(&mut info.dependants)); + .insert(old.clone(), core::mem::take(&mut info.dependants)); } if let Some(processed_info) = &info.processed_info { // Update "dependant" lists for this asset's "process dependencies" to use new path. diff --git a/crates/bevy_asset/src/processor/process.rs b/crates/bevy_asset/src/processor/process.rs index c77ac3848a2b1..108b7ffc8d2e6 100644 --- a/crates/bevy_asset/src/processor/process.rs +++ b/crates/bevy_asset/src/processor/process.rs @@ -11,8 +11,8 @@ use crate::{ MissingAssetLoaderForExtensionError, MissingAssetLoaderForTypeNameError, }; use bevy_utils::{BoxedFuture, ConditionalSendFuture}; +use core::marker::PhantomData; use serde::{Deserialize, Serialize}; -use std::marker::PhantomData; use thiserror::Error; /// Asset "processor" logic that reads input asset bytes (stored on [`ProcessContext`]), processes the value in some way, @@ -162,9 +162,9 @@ pub enum ProcessError { #[error("The wrong meta type was passed into a processor. This is probably an internal implementation error.")] WrongMetaType, #[error("Encountered an error while saving the asset: {0}")] - AssetSaveError(#[from] Box), + AssetSaveError(#[from] Box), #[error("Encountered an error while transforming the asset: {0}")] - AssetTransformError(Box), + AssetTransformError(Box), #[error("Assets without extensions are not supported.")] ExtensionRequired, } @@ -189,7 +189,7 @@ where return Err(ProcessError::WrongMetaType); }; let loader_meta = AssetMeta::::new(AssetAction::Load { - loader: std::any::type_name::().to_string(), + loader: core::any::type_name::().to_string(), settings: settings.loader_settings, }); let pre_transformed_asset = TransformedAsset::::from_loaded( @@ -246,7 +246,7 @@ impl ErasedProcessor for P { let loader_settings =

::process(self, context, *meta, writer).await?; let output_meta: Box = Box::new(AssetMeta::::new(AssetAction::Load { - loader: std::any::type_name::().to_string(), + loader: core::any::type_name::().to_string(), settings: loader_settings, })); Ok(output_meta) @@ -260,7 +260,7 @@ impl ErasedProcessor for P { fn default_meta(&self) -> Box { Box::new(AssetMeta::<(), P>::new(AssetAction::Process { - processor: std::any::type_name::

().to_string(), + processor: core::any::type_name::

().to_string(), settings: P::Settings::default(), })) } @@ -316,7 +316,7 @@ impl<'a> ProcessContext<'a> { meta: AssetMeta, ) -> Result { let server = &self.processor.server; - let loader_name = std::any::type_name::(); + let loader_name = core::any::type_name::(); let loader = server.get_asset_loader_with_type_name(loader_name).await?; let mut reader = SliceReader::new(self.asset_bytes); let loaded_asset = server diff --git a/crates/bevy_asset/src/reflect.rs b/crates/bevy_asset/src/reflect.rs index 468300887bfbe..3aaa1580bb110 100644 --- a/crates/bevy_asset/src/reflect.rs +++ b/crates/bevy_asset/src/reflect.rs @@ -1,4 +1,4 @@ -use std::any::{Any, TypeId}; +use core::any::{Any, TypeId}; use bevy_ecs::world::{unsafe_world_cell::UnsafeWorldCell, World}; use bevy_reflect::{FromReflect, FromType, PartialReflect, Reflect}; @@ -243,7 +243,7 @@ impl FromType> for ReflectHandle { #[cfg(test)] mod tests { - use std::any::TypeId; + use core::any::TypeId; use crate as bevy_asset; use crate::{Asset, AssetApp, AssetPlugin, ReflectAsset, UntypedHandle}; diff --git a/crates/bevy_asset/src/saver.rs b/crates/bevy_asset/src/saver.rs index 0234c9210bf8e..19955cd62f397 100644 --- a/crates/bevy_asset/src/saver.rs +++ b/crates/bevy_asset/src/saver.rs @@ -4,8 +4,8 @@ use crate::{ }; use atomicow::CowArc; use bevy_utils::{BoxedFuture, ConditionalSendFuture, HashMap}; +use core::{borrow::Borrow, hash::Hash, ops::Deref}; use serde::{Deserialize, Serialize}; -use std::{borrow::Borrow, hash::Hash, ops::Deref}; /// Saves an [`Asset`] of a given [`AssetSaver::Asset`] type. [`AssetSaver::OutputLoader`] will then be used to load the saved asset /// in the final deployed application. The saver should produce asset bytes in a format that [`AssetSaver::OutputLoader`] can read. @@ -21,7 +21,7 @@ pub trait AssetSaver: Send + Sync + 'static { /// The type of [`AssetLoader`] used to load this [`Asset`] type OutputLoader: AssetLoader; /// The type of [error](`std::error::Error`) which could be encountered by this saver. - type Error: Into>; + type Error: Into>; /// Saves the given runtime [`Asset`] by writing it to a byte format using `writer`. The passed in `settings` can influence how the /// `asset` is saved. @@ -44,7 +44,7 @@ pub trait ErasedAssetSaver: Send + Sync + 'static { writer: &'a mut Writer, asset: &'a ErasedLoadedAsset, settings: &'a dyn Settings, - ) -> BoxedFuture<'a, Result<(), Box>>; + ) -> BoxedFuture<'a, Result<(), Box>>; /// The type name of the [`AssetSaver`]. fn type_name(&self) -> &'static str; @@ -56,7 +56,7 @@ impl ErasedAssetSaver for S { writer: &'a mut Writer, asset: &'a ErasedLoadedAsset, settings: &'a dyn Settings, - ) -> BoxedFuture<'a, Result<(), Box>> { + ) -> BoxedFuture<'a, Result<(), Box>> { Box::pin(async move { let settings = settings .downcast_ref::() @@ -69,7 +69,7 @@ impl ErasedAssetSaver for S { }) } fn type_name(&self) -> &'static str { - std::any::type_name::() + core::any::type_name::() } } diff --git a/crates/bevy_asset/src/server/info.rs b/crates/bevy_asset/src/server/info.rs index ace0df54c3525..1371d0fe02837 100644 --- a/crates/bevy_asset/src/server/info.rs +++ b/crates/bevy_asset/src/server/info.rs @@ -4,14 +4,12 @@ use crate::{ Handle, InternalAssetEvent, LoadState, RecursiveDependencyLoadState, StrongHandle, UntypedAssetId, UntypedHandle, }; +use alloc::sync::{Arc, Weak}; use bevy_ecs::world::World; use bevy_tasks::Task; use bevy_utils::{tracing::warn, Entry, HashMap, HashSet, TypeIdMap}; +use core::any::TypeId; use crossbeam_channel::Sender; -use std::{ - any::TypeId, - sync::{Arc, Weak}, -}; use thiserror::Error; #[derive(Debug)] @@ -79,8 +77,8 @@ pub(crate) struct AssetInfos { pub(crate) pending_tasks: HashMap>, } -impl std::fmt::Debug for AssetInfos { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl core::fmt::Debug for AssetInfos { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { f.debug_struct("AssetInfos") .field("path_to_id", &self.path_to_id) .field("infos", &self.infos) @@ -164,7 +162,7 @@ impl AssetInfos { ); // it is ok to unwrap because TypeId was specified above let (handle, should_load) = - unwrap_with_context(result, std::any::type_name::()).unwrap(); + unwrap_with_context(result, core::any::type_name::()).unwrap(); (handle.typed_unchecked(), should_load) } @@ -499,7 +497,7 @@ impl AssetInfos { rec_dep_load_state, RecursiveDependencyLoadState::Loaded | RecursiveDependencyLoadState::Failed(_) ) { - Some(std::mem::take( + Some(core::mem::take( &mut info.dependants_waiting_on_recursive_dep_load, )) } else { @@ -507,7 +505,7 @@ impl AssetInfos { }; ( - std::mem::take(&mut info.dependants_waiting_on_load), + core::mem::take(&mut info.dependants_waiting_on_load), dependants_waiting_on_rec_load, ) }; @@ -560,7 +558,7 @@ impl AssetInfos { .send(InternalAssetEvent::LoadedWithDependencies { id: waiting_id }) .unwrap(); } - Some(std::mem::take( + Some(core::mem::take( &mut info.dependants_waiting_on_recursive_dep_load, )) } else { @@ -588,7 +586,7 @@ impl AssetInfos { info.loading_rec_dependencies.remove(&failed_id); info.failed_rec_dependencies.insert(failed_id); info.rec_dep_load_state = RecursiveDependencyLoadState::Failed(error.clone()); - Some(std::mem::take( + Some(core::mem::take( &mut info.dependants_waiting_on_recursive_dep_load, )) } else { @@ -618,8 +616,8 @@ impl AssetInfos { info.dep_load_state = DependencyLoadState::Failed(error.clone()); info.rec_dep_load_state = RecursiveDependencyLoadState::Failed(error.clone()); ( - std::mem::take(&mut info.dependants_waiting_on_load), - std::mem::take(&mut info.dependants_waiting_on_recursive_dep_load), + core::mem::take(&mut info.dependants_waiting_on_load), + core::mem::take(&mut info.dependants_waiting_on_recursive_dep_load), ) }; diff --git a/crates/bevy_asset/src/server/loaders.rs b/crates/bevy_asset/src/server/loaders.rs index 307918b75b16f..64d26d43951bb 100644 --- a/crates/bevy_asset/src/server/loaders.rs +++ b/crates/bevy_asset/src/server/loaders.rs @@ -2,6 +2,7 @@ use crate::{ loader::{AssetLoader, ErasedAssetLoader}, path::AssetPath, }; +use alloc::sync::Arc; use async_broadcast::RecvError; use bevy_tasks::IoTaskPool; use bevy_utils::{ @@ -13,7 +14,7 @@ use bevy_utils::{ tracing::{info_span, instrument::Instrument}, ConditionalSendFuture, }; -use std::{any::TypeId, sync::Arc}; +use core::any::TypeId; use thiserror::Error; #[derive(Default)] @@ -33,9 +34,9 @@ impl AssetLoaders { /// Registers a new [`AssetLoader`]. [`AssetLoader`]s must be registered before they can be used. pub(crate) fn push(&mut self, loader: L) { - let type_name = std::any::type_name::(); + let type_name = core::any::type_name::(); let loader_asset_type = TypeId::of::(); - let loader_asset_type_name = std::any::type_name::(); + let loader_asset_type_name = core::any::type_name::(); #[cfg(feature = "trace")] let loader = InstrumentedAssetLoader(loader); @@ -80,7 +81,7 @@ impl AssetLoaders { self.loaders.push(MaybeAssetLoader::Ready(loader)); } else { - let maybe_loader = std::mem::replace( + let maybe_loader = core::mem::replace( self.loaders.get_mut(loader_index).unwrap(), MaybeAssetLoader::Ready(loader.clone()), ); @@ -103,8 +104,8 @@ impl AssetLoaders { /// real loader is added. pub(crate) fn reserve(&mut self, extensions: &[&str]) { let loader_asset_type = TypeId::of::(); - let loader_asset_type_name = std::any::type_name::(); - let type_name = std::any::type_name::(); + let loader_asset_type_name = core::any::type_name::(); + let type_name = core::any::type_name::(); let loader_index = self.loaders.len(); @@ -268,7 +269,7 @@ impl AssetLoaders { pub(crate) fn get_by_path(&self, path: &AssetPath<'_>) -> Option { let extension = path.get_full_extension()?; - let result = std::iter::once(extension.as_str()) + let result = core::iter::once(extension.as_str()) .chain(AssetPath::iter_secondary_extensions(&extension)) .filter_map(|extension| self.extension_to_loaders.get(extension)?.last().copied()) .find_map(|index| self.get_by_index(index))?; @@ -318,7 +319,7 @@ impl AssetLoader for InstrumentedAssetLoader { ) -> impl ConditionalSendFuture> { let span = info_span!( "asset loading", - loader = std::any::type_name::(), + loader = core::any::type_name::(), asset = load_context.asset_path().to_string(), ); self.0.load(reader, settings, load_context).instrument(span) @@ -331,8 +332,8 @@ impl AssetLoader for InstrumentedAssetLoader { #[cfg(test)] mod tests { + use core::marker::PhantomData; use std::{ - marker::PhantomData, path::Path, sync::mpsc::{channel, Receiver, Sender}, }; @@ -392,7 +393,7 @@ mod tests { Err(format!( "Loaded {}:{}", - std::any::type_name::(), + core::any::type_name::(), N )) } @@ -426,7 +427,7 @@ mod tests { let loader = block_on( loaders - .get_by_name(std::any::type_name::>()) + .get_by_name(core::any::type_name::>()) .unwrap() .get(), ) diff --git a/crates/bevy_asset/src/server/mod.rs b/crates/bevy_asset/src/server/mod.rs index 90f618f865cf1..f5f424c2dccd9 100644 --- a/crates/bevy_asset/src/server/mod.rs +++ b/crates/bevy_asset/src/server/mod.rs @@ -17,6 +17,7 @@ use crate::{ DeserializeMetaError, ErasedLoadedAsset, Handle, LoadedUntypedAsset, UntypedAssetId, UntypedAssetLoadFailedEvent, UntypedHandle, }; +use alloc::sync::Arc; use atomicow::CowArc; use bevy_ecs::prelude::*; use bevy_tasks::IoTaskPool; @@ -24,18 +25,17 @@ use bevy_utils::{ tracing::{error, info}, HashSet, }; +use core::{ + any::{Any, TypeId}, + future::Future, + panic::AssertUnwindSafe, +}; use crossbeam_channel::{Receiver, Sender}; use futures_lite::{FutureExt, StreamExt}; use info::*; use loaders::*; use parking_lot::RwLock; -use std::{ - any::{Any, TypeId}, - future::Future, - panic::AssertUnwindSafe, - path::{Path, PathBuf}, - sync::Arc, -}; +use std::path::{Path, PathBuf}; use thiserror::Error; /// Loads and tracks the state of [`Asset`] values from a configured [`AssetReader`](crate::io::AssetReader). This can be used to kick off new asset loads and @@ -733,13 +733,13 @@ impl AssetServer { /// /// After the asset has been fully loaded, it will show up in the relevant [`Assets`] storage. #[must_use = "not using the returned strong handle may result in the unexpected release of the asset"] - pub fn add_async( + pub fn add_async( &self, future: impl Future> + Send + 'static, ) -> Handle { let mut infos = self.data.infos.write(); let handle = - infos.create_loading_handle_untyped(TypeId::of::(), std::any::type_name::()); + infos.create_loading_handle_untyped(TypeId::of::(), core::any::type_name::()); let id = handle.id(); let event_sender = self.data.asset_event_sender.clone(); @@ -1523,7 +1523,7 @@ pub enum AssetLoadError { pub struct AssetLoaderError { path: AssetPath<'static>, loader_name: &'static str, - error: Arc, + error: Arc, } impl PartialEq for AssetLoaderError { @@ -1547,7 +1547,7 @@ impl AssetLoaderError { #[derive(Error, Debug, Clone)] #[error("An error occurred while resolving an asset added by `add_async`: {error}")] pub struct AddAsyncError { - error: Arc, + error: Arc, } impl PartialEq for AddAsyncError { @@ -1593,8 +1593,8 @@ fn format_missing_asset_ext(exts: &[String]) -> String { } } -impl std::fmt::Debug for AssetServer { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl core::fmt::Debug for AssetServer { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { f.debug_struct("AssetServer") .field("info", &self.data.infos.read()) .finish() diff --git a/crates/bevy_asset/src/transformer.rs b/crates/bevy_asset/src/transformer.rs index f13d81ca67346..484e02003f644 100644 --- a/crates/bevy_asset/src/transformer.rs +++ b/crates/bevy_asset/src/transformer.rs @@ -1,14 +1,14 @@ use crate::{meta::Settings, Asset, ErasedLoadedAsset, Handle, LabeledAsset, UntypedHandle}; use atomicow::CowArc; use bevy_utils::{ConditionalSendFuture, HashMap}; -use serde::{Deserialize, Serialize}; -use std::{ +use core::{ borrow::Borrow, convert::Infallible, hash::Hash, marker::PhantomData, ops::{Deref, DerefMut}, }; +use serde::{Deserialize, Serialize}; /// Transforms an [`Asset`] of a given [`AssetTransformer::AssetInput`] type to an [`Asset`] of [`AssetTransformer::AssetOutput`] type. /// @@ -21,7 +21,7 @@ pub trait AssetTransformer: Send + Sync + 'static { /// The settings type used by this [`AssetTransformer`]. type Settings: Settings + Default + Serialize + for<'a> Deserialize<'a>; /// The type of [error](`std::error::Error`) which could be encountered by this transformer. - type Error: Into>; + type Error: Into>; /// Transforms the given [`TransformedAsset`] to [`AssetTransformer::AssetOutput`]. /// The [`TransformedAsset`]'s `labeled_assets` can be altered to add new Labeled Sub-Assets diff --git a/crates/bevy_audio/src/audio_output.rs b/crates/bevy_audio/src/audio_output.rs index cfe344c1cebe0..69a31acff1878 100644 --- a/crates/bevy_audio/src/audio_output.rs +++ b/crates/bevy_audio/src/audio_output.rs @@ -33,7 +33,7 @@ impl Default for AudioOutput { fn default() -> Self { if let Ok((stream, stream_handle)) = OutputStream::try_default() { // We leak `OutputStream` to prevent the audio from stopping. - std::mem::forget(stream); + core::mem::forget(stream); Self { stream_handle: Some(stream_handle), } diff --git a/crates/bevy_audio/src/audio_source.rs b/crates/bevy_audio/src/audio_source.rs index ae1e42606d4b0..7462ddf8a491e 100644 --- a/crates/bevy_audio/src/audio_source.rs +++ b/crates/bevy_audio/src/audio_source.rs @@ -1,6 +1,7 @@ +use alloc::sync::Arc; use bevy_asset::{io::Reader, Asset, AssetLoader, LoadContext}; use bevy_reflect::TypePath; -use std::{io::Cursor, sync::Arc}; +use std::io::Cursor; /// A source of audio data #[derive(Asset, Debug, Clone, TypePath)] diff --git a/crates/bevy_audio/src/lib.rs b/crates/bevy_audio/src/lib.rs index 0683dfa858b0d..6fae1e835d972 100644 --- a/crates/bevy_audio/src/lib.rs +++ b/crates/bevy_audio/src/lib.rs @@ -27,6 +27,8 @@ //! } //! ``` +extern crate alloc; + mod audio; mod audio_output; mod audio_source; diff --git a/crates/bevy_audio/src/pitch.rs b/crates/bevy_audio/src/pitch.rs index 442a758f08989..1f4c406a5d967 100644 --- a/crates/bevy_audio/src/pitch.rs +++ b/crates/bevy_audio/src/pitch.rs @@ -12,12 +12,12 @@ pub struct Pitch { /// Frequency at which sound will be played pub frequency: f32, /// Duration for which sound will be played - pub duration: std::time::Duration, + pub duration: core::time::Duration, } impl Pitch { /// Creates a new note - pub fn new(frequency: f32, duration: std::time::Duration) -> Self { + pub fn new(frequency: f32, duration: core::time::Duration) -> Self { Pitch { frequency, duration, diff --git a/crates/bevy_color/crates/gen_tests/src/main.rs b/crates/bevy_color/crates/gen_tests/src/main.rs index 80aa88b288683..7cd614f966fea 100644 --- a/crates/bevy_color/crates/gen_tests/src/main.rs +++ b/crates/bevy_color/crates/gen_tests/src/main.rs @@ -110,8 +110,8 @@ pub struct TestColor {{ struct VariablePrecision(f32); -impl std::fmt::Display for VariablePrecision { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl core::fmt::Display for VariablePrecision { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { if self.0.fract() == 0.0 { return write!(f, "{}.0", self.0); } diff --git a/crates/bevy_color/src/color_ops.rs b/crates/bevy_color/src/color_ops.rs index ffba9467f6170..4fda6eb4e43b2 100644 --- a/crates/bevy_color/src/color_ops.rs +++ b/crates/bevy_color/src/color_ops.rs @@ -137,7 +137,7 @@ pub(crate) fn lerp_hue(a: f32, b: f32, t: f32) -> f32 { #[cfg(test)] mod tests { - use std::fmt::Debug; + use core::fmt::Debug; use super::*; use crate::{testing::assert_approx_eq, Hsla}; diff --git a/crates/bevy_color/src/color_range.rs b/crates/bevy_color/src/color_range.rs index 1661923355331..48afa5418225d 100644 --- a/crates/bevy_color/src/color_range.rs +++ b/crates/bevy_color/src/color_range.rs @@ -1,4 +1,4 @@ -use std::ops::Range; +use core::ops::Range; use crate::Mix; diff --git a/crates/bevy_color/src/lib.rs b/crates/bevy_color/src/lib.rs index d9ff34ae910d7..f91080e389acb 100644 --- a/crates/bevy_color/src/lib.rs +++ b/crates/bevy_color/src/lib.rs @@ -160,7 +160,7 @@ where macro_rules! impl_componentwise_vector_space { ($ty: ident, [$($element: ident),+]) => { - impl std::ops::Add for $ty { + impl core::ops::Add for $ty { type Output = Self; fn add(self, rhs: Self) -> Self::Output { @@ -170,13 +170,13 @@ macro_rules! impl_componentwise_vector_space { } } - impl std::ops::AddAssign for $ty { + impl core::ops::AddAssign for $ty { fn add_assign(&mut self, rhs: Self) { *self = *self + rhs; } } - impl std::ops::Neg for $ty { + impl core::ops::Neg for $ty { type Output = Self; fn neg(self) -> Self::Output { @@ -186,7 +186,7 @@ macro_rules! impl_componentwise_vector_space { } } - impl std::ops::Sub for $ty { + impl core::ops::Sub for $ty { type Output = Self; fn sub(self, rhs: Self) -> Self::Output { @@ -196,13 +196,13 @@ macro_rules! impl_componentwise_vector_space { } } - impl std::ops::SubAssign for $ty { + impl core::ops::SubAssign for $ty { fn sub_assign(&mut self, rhs: Self) { *self = *self - rhs; } } - impl std::ops::Mul for $ty { + impl core::ops::Mul for $ty { type Output = Self; fn mul(self, rhs: f32) -> Self::Output { @@ -212,7 +212,7 @@ macro_rules! impl_componentwise_vector_space { } } - impl std::ops::Mul<$ty> for f32 { + impl core::ops::Mul<$ty> for f32 { type Output = $ty; fn mul(self, rhs: $ty) -> Self::Output { @@ -222,13 +222,13 @@ macro_rules! impl_componentwise_vector_space { } } - impl std::ops::MulAssign for $ty { + impl core::ops::MulAssign for $ty { fn mul_assign(&mut self, rhs: f32) { *self = *self * rhs; } } - impl std::ops::Div for $ty { + impl core::ops::Div for $ty { type Output = Self; fn div(self, rhs: f32) -> Self::Output { @@ -238,7 +238,7 @@ macro_rules! impl_componentwise_vector_space { } } - impl std::ops::DivAssign for $ty { + impl core::ops::DivAssign for $ty { fn div_assign(&mut self, rhs: f32) { *self = *self / rhs; } diff --git a/crates/bevy_color/src/srgba.rs b/crates/bevy_color/src/srgba.rs index fac9fd18dd71a..53c66a0975396 100644 --- a/crates/bevy_color/src/srgba.rs +++ b/crates/bevy_color/src/srgba.rs @@ -425,7 +425,7 @@ impl From for Xyza { pub enum HexColorError { /// Parsing error. #[error("Invalid hex string")] - Parse(#[from] std::num::ParseIntError), + Parse(#[from] core::num::ParseIntError), /// Invalid length. #[error("Unexpected length of hex string")] Length, diff --git a/crates/bevy_core/src/lib.rs b/crates/bevy_core/src/lib.rs index 94a8b3a541f88..748e26109984e 100644 --- a/crates/bevy_core/src/lib.rs +++ b/crates/bevy_core/src/lib.rs @@ -7,6 +7,8 @@ //! This crate provides core functionality for Bevy Engine. +extern crate alloc; + mod name; #[cfg(feature = "serialize")] mod serde; @@ -29,7 +31,7 @@ pub mod prelude { use bevy_app::prelude::*; use bevy_ecs::prelude::*; -use std::marker::PhantomData; +use core::marker::PhantomData; #[cfg(not(target_arch = "wasm32"))] use bevy_tasks::tick_global_task_pools_on_main_thread; diff --git a/crates/bevy_core/src/name.rs b/crates/bevy_core/src/name.rs index 9985f6d1e65d7..8c00762199dfa 100644 --- a/crates/bevy_core/src/name.rs +++ b/crates/bevy_core/src/name.rs @@ -2,13 +2,13 @@ use bevy_ecs::reflect::ReflectComponent; use bevy_ecs::{component::Component, entity::Entity, query::QueryData}; +use alloc::borrow::Cow; #[cfg(feature = "bevy_reflect")] use bevy_reflect::std_traits::ReflectDefault; #[cfg(feature = "bevy_reflect")] use bevy_reflect::Reflect; use bevy_utils::AHasher; -use std::{ - borrow::Cow, +use core::{ hash::{Hash, Hasher}, ops::Deref, }; @@ -86,17 +86,17 @@ impl Name { } } -impl std::fmt::Display for Name { +impl core::fmt::Display for Name { #[inline(always)] - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - std::fmt::Display::fmt(&self.name, f) + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + core::fmt::Display::fmt(&self.name, f) } } -impl std::fmt::Debug for Name { +impl core::fmt::Debug for Name { #[inline(always)] - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - std::fmt::Debug::fmt(&self.name, f) + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + core::fmt::Debug::fmt(&self.name, f) } } @@ -130,12 +130,12 @@ pub struct NameOrEntity { pub entity: Entity, } -impl<'a> std::fmt::Display for NameOrEntityItem<'a> { +impl<'a> core::fmt::Display for NameOrEntityItem<'a> { #[inline(always)] - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { match self.name { - Some(name) => std::fmt::Display::fmt(name, f), - None => std::fmt::Display::fmt(&self.entity, f), + Some(name) => core::fmt::Display::fmt(name, f), + None => core::fmt::Display::fmt(&self.entity, f), } } } @@ -196,13 +196,13 @@ impl PartialEq for Name { impl Eq for Name {} impl PartialOrd for Name { - fn partial_cmp(&self, other: &Self) -> Option { + fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } impl Ord for Name { - fn cmp(&self, other: &Self) -> std::cmp::Ordering { + fn cmp(&self, other: &Self) -> core::cmp::Ordering { self.name.cmp(&other.name) } } diff --git a/crates/bevy_core/src/serde.rs b/crates/bevy_core/src/serde.rs index b3e3b8709880a..d618ba179492a 100644 --- a/crates/bevy_core/src/serde.rs +++ b/crates/bevy_core/src/serde.rs @@ -1,4 +1,4 @@ -use std::{ +use core::{ any, fmt::{self, Formatter}, }; diff --git a/crates/bevy_core_pipeline/src/auto_exposure/pipeline.rs b/crates/bevy_core_pipeline/src/auto_exposure/pipeline.rs index 684c8dd9e200a..410b7deb6d47e 100644 --- a/crates/bevy_core_pipeline/src/auto_exposure/pipeline.rs +++ b/crates/bevy_core_pipeline/src/auto_exposure/pipeline.rs @@ -10,7 +10,7 @@ use bevy_render::{ texture::Image, view::ViewUniform, }; -use std::num::NonZero; +use core::num::NonZero; #[derive(Resource)] pub struct AutoExposurePipeline { diff --git a/crates/bevy_core_pipeline/src/auto_exposure/settings.rs b/crates/bevy_core_pipeline/src/auto_exposure/settings.rs index 14c7b551bc282..066e8d3c8867b 100644 --- a/crates/bevy_core_pipeline/src/auto_exposure/settings.rs +++ b/crates/bevy_core_pipeline/src/auto_exposure/settings.rs @@ -1,4 +1,4 @@ -use std::ops::RangeInclusive; +use core::ops::RangeInclusive; use super::compensation_curve::AutoExposureCompensationCurve; use bevy_asset::Handle; diff --git a/crates/bevy_core_pipeline/src/core_2d/mod.rs b/crates/bevy_core_pipeline/src/core_2d/mod.rs index 7bd6bea38cb58..6bd3b3e324bcd 100644 --- a/crates/bevy_core_pipeline/src/core_2d/mod.rs +++ b/crates/bevy_core_pipeline/src/core_2d/mod.rs @@ -30,7 +30,7 @@ pub mod graph { } } -use std::ops::Range; +use core::ops::Range; use bevy_asset::UntypedAssetId; use bevy_utils::HashMap; diff --git a/crates/bevy_core_pipeline/src/core_3d/main_transmissive_pass_3d_node.rs b/crates/bevy_core_pipeline/src/core_3d/main_transmissive_pass_3d_node.rs index f78083afb3816..225ce81da6c3a 100644 --- a/crates/bevy_core_pipeline/src/core_3d/main_transmissive_pass_3d_node.rs +++ b/crates/bevy_core_pipeline/src/core_3d/main_transmissive_pass_3d_node.rs @@ -12,7 +12,7 @@ use bevy_render::{ use bevy_utils::tracing::error; #[cfg(feature = "trace")] use bevy_utils::tracing::info_span; -use std::ops::Range; +use core::ops::Range; /// A [`bevy_render::render_graph::Node`] that runs the [`Transmissive3d`] /// [`ViewSortedRenderPhases`]. diff --git a/crates/bevy_core_pipeline/src/core_3d/mod.rs b/crates/bevy_core_pipeline/src/core_3d/mod.rs index c539c10fa71ce..fc066e2d9ea7f 100644 --- a/crates/bevy_core_pipeline/src/core_3d/mod.rs +++ b/crates/bevy_core_pipeline/src/core_3d/mod.rs @@ -63,7 +63,7 @@ pub const DEPTH_TEXTURE_SAMPLING_SUPPORTED: bool = false; #[cfg(any(feature = "webgpu", not(target_arch = "wasm32")))] pub const DEPTH_TEXTURE_SAMPLING_SUPPORTED: bool = true; -use std::ops::Range; +use core::ops::Range; use bevy_asset::{AssetId, UntypedAssetId}; use bevy_color::LinearRgba; diff --git a/crates/bevy_core_pipeline/src/deferred/mod.rs b/crates/bevy_core_pipeline/src/deferred/mod.rs index 1372731820224..ef20bf7ee59d6 100644 --- a/crates/bevy_core_pipeline/src/deferred/mod.rs +++ b/crates/bevy_core_pipeline/src/deferred/mod.rs @@ -1,7 +1,7 @@ pub mod copy_lighting_id; pub mod node; -use std::ops::Range; +use core::ops::Range; use bevy_ecs::prelude::*; use bevy_render::{ diff --git a/crates/bevy_core_pipeline/src/prepass/mod.rs b/crates/bevy_core_pipeline/src/prepass/mod.rs index 3f408e544f809..4829c76ee7653 100644 --- a/crates/bevy_core_pipeline/src/prepass/mod.rs +++ b/crates/bevy_core_pipeline/src/prepass/mod.rs @@ -27,7 +27,7 @@ pub mod node; -use std::ops::Range; +use core::ops::Range; use bevy_asset::UntypedAssetId; use bevy_ecs::prelude::*; diff --git a/crates/bevy_derive/compile_fail/tests/deref_mut_derive/invalid_attribute_fail.rs b/crates/bevy_derive/compile_fail/tests/deref_mut_derive/invalid_attribute_fail.rs index aa39ac923e6fe..d3efd7c902ac9 100644 --- a/crates/bevy_derive/compile_fail/tests/deref_mut_derive/invalid_attribute_fail.rs +++ b/crates/bevy_derive/compile_fail/tests/deref_mut_derive/invalid_attribute_fail.rs @@ -1,5 +1,5 @@ use bevy_derive::DerefMut; -use std::ops::Deref; +use core::ops::Deref; // Reason: `#[deref]` doesn't take any arguments diff --git a/crates/bevy_derive/compile_fail/tests/deref_mut_derive/mismatched_target_type_fail.rs b/crates/bevy_derive/compile_fail/tests/deref_mut_derive/mismatched_target_type_fail.rs index 253c59e734aa9..224a53e709e73 100644 --- a/crates/bevy_derive/compile_fail/tests/deref_mut_derive/mismatched_target_type_fail.rs +++ b/crates/bevy_derive/compile_fail/tests/deref_mut_derive/mismatched_target_type_fail.rs @@ -1,5 +1,5 @@ use bevy_derive::DerefMut; -use std::ops::Deref; +use core::ops::Deref; #[derive(DerefMut)] //~^ E0308 diff --git a/crates/bevy_derive/compile_fail/tests/deref_mut_derive/missing_attribute_fail.rs b/crates/bevy_derive/compile_fail/tests/deref_mut_derive/missing_attribute_fail.rs index f2568bb698fc2..0415516d135d6 100644 --- a/crates/bevy_derive/compile_fail/tests/deref_mut_derive/missing_attribute_fail.rs +++ b/crates/bevy_derive/compile_fail/tests/deref_mut_derive/missing_attribute_fail.rs @@ -1,5 +1,5 @@ use bevy_derive::DerefMut; -use std::ops::Deref; +use core::ops::Deref; #[derive(DerefMut)] //~^ ERROR: requires one field to have diff --git a/crates/bevy_derive/compile_fail/tests/deref_mut_derive/multiple_attributes_fail.rs b/crates/bevy_derive/compile_fail/tests/deref_mut_derive/multiple_attributes_fail.rs index 449720934e084..b855f9f4f4bb3 100644 --- a/crates/bevy_derive/compile_fail/tests/deref_mut_derive/multiple_attributes_fail.rs +++ b/crates/bevy_derive/compile_fail/tests/deref_mut_derive/multiple_attributes_fail.rs @@ -1,5 +1,5 @@ use bevy_derive::DerefMut; -use std::ops::Deref; +use core::ops::Deref; #[derive(DerefMut)] struct TupleStruct( diff --git a/crates/bevy_derive/compile_fail/tests/deref_mut_derive/multiple_fields_pass.rs b/crates/bevy_derive/compile_fail/tests/deref_mut_derive/multiple_fields_pass.rs index bc65df7baf796..86d0bceb1e1ed 100644 --- a/crates/bevy_derive/compile_fail/tests/deref_mut_derive/multiple_fields_pass.rs +++ b/crates/bevy_derive/compile_fail/tests/deref_mut_derive/multiple_fields_pass.rs @@ -1,7 +1,7 @@ //@check-pass use bevy_derive::DerefMut; -use std::ops::Deref; +use core::ops::Deref; #[derive(DerefMut)] // The first field is never read, but we want it there to check that the derive skips it. diff --git a/crates/bevy_derive/compile_fail/tests/deref_mut_derive/single_field_pass.rs b/crates/bevy_derive/compile_fail/tests/deref_mut_derive/single_field_pass.rs index 803ed3ba5cc21..e63200ccc7971 100644 --- a/crates/bevy_derive/compile_fail/tests/deref_mut_derive/single_field_pass.rs +++ b/crates/bevy_derive/compile_fail/tests/deref_mut_derive/single_field_pass.rs @@ -1,6 +1,6 @@ //@check-pass use bevy_derive::DerefMut; -use std::ops::Deref; +use core::ops::Deref; #[derive(DerefMut)] struct TupleStruct(#[deref] String); diff --git a/crates/bevy_derive/src/derefs.rs b/crates/bevy_derive/src/derefs.rs index 90b00f7b71c33..0dd3b152bfda5 100644 --- a/crates/bevy_derive/src/derefs.rs +++ b/crates/bevy_derive/src/derefs.rs @@ -19,7 +19,7 @@ pub fn derive_deref(input: TokenStream) -> TokenStream { let (impl_generics, ty_generics, where_clause) = ast.generics.split_for_impl(); TokenStream::from(quote! { - impl #impl_generics ::std::ops::Deref for #ident #ty_generics #where_clause { + impl #impl_generics ::core::ops::Deref for #ident #ty_generics #where_clause { type Target = #field_type; fn deref(&self) -> &Self::Target { @@ -42,7 +42,7 @@ pub fn derive_deref_mut(input: TokenStream) -> TokenStream { let (impl_generics, ty_generics, where_clause) = ast.generics.split_for_impl(); TokenStream::from(quote! { - impl #impl_generics ::std::ops::DerefMut for #ident #ty_generics #where_clause { + impl #impl_generics ::core::ops::DerefMut for #ident #ty_generics #where_clause { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.#field_member } diff --git a/crates/bevy_dev_tools/src/ci_testing/mod.rs b/crates/bevy_dev_tools/src/ci_testing/mod.rs index 39b9bee6da7e6..5c85aeff48340 100644 --- a/crates/bevy_dev_tools/src/ci_testing/mod.rs +++ b/crates/bevy_dev_tools/src/ci_testing/mod.rs @@ -9,7 +9,7 @@ use bevy_app::prelude::*; use bevy_ecs::prelude::*; use bevy_render::view::screenshot::trigger_screenshots; use bevy_time::TimeUpdateStrategy; -use std::time::Duration; +use core::time::Duration; /// A plugin that instruments continuous integration testing by automatically executing user-defined actions. /// diff --git a/crates/bevy_dev_tools/src/ci_testing/systems.rs b/crates/bevy_dev_tools/src/ci_testing/systems.rs index 2b652abf96db6..20c758a91cdfc 100644 --- a/crates/bevy_dev_tools/src/ci_testing/systems.rs +++ b/crates/bevy_dev_tools/src/ci_testing/systems.rs @@ -8,7 +8,7 @@ pub(crate) fn send_events(world: &mut World, mut current_frame: Local) { let mut config = world.resource_mut::(); // Take all events for the current frame, leaving all the remaining alone. - let events = std::mem::take(&mut config.events); + let events = core::mem::take(&mut config.events); let (to_run, remaining): (Vec<_>, _) = events .into_iter() .partition(|event| event.0 == *current_frame); diff --git a/crates/bevy_dev_tools/src/states.rs b/crates/bevy_dev_tools/src/states.rs index 7e3aa237c60cf..21d5aedc03232 100644 --- a/crates/bevy_dev_tools/src/states.rs +++ b/crates/bevy_dev_tools/src/states.rs @@ -12,7 +12,7 @@ pub fn log_transitions(mut transitions: EventReader(); + let name = core::any::type_name::(); let StateTransitionEvent { exited, entered } = transition; info!("{} transition: {:?} => {:?}", name, exited, entered); } diff --git a/crates/bevy_dev_tools/src/ui_debug_overlay/mod.rs b/crates/bevy_dev_tools/src/ui_debug_overlay/mod.rs index 88af56210a9e3..d84143943c973 100644 --- a/crates/bevy_dev_tools/src/ui_debug_overlay/mod.rs +++ b/crates/bevy_dev_tools/src/ui_debug_overlay/mod.rs @@ -1,5 +1,5 @@ //! A visual representation of UI node sizes. -use std::any::{Any, TypeId}; +use core::any::{Any, TypeId}; use bevy_app::{App, Plugin, PostUpdate}; use bevy_color::Hsla; diff --git a/crates/bevy_diagnostic/src/diagnostic.rs b/crates/bevy_diagnostic/src/diagnostic.rs index 5cd0956f9462a..ccd6e17df175d 100644 --- a/crates/bevy_diagnostic/src/diagnostic.rs +++ b/crates/bevy_diagnostic/src/diagnostic.rs @@ -1,8 +1,5 @@ -use std::{ - borrow::Cow, - collections::VecDeque, - hash::{Hash, Hasher}, -}; +use alloc::{borrow::Cow, collections::VecDeque}; +use core::hash::{Hash, Hasher}; use bevy_app::{App, SubApp}; use bevy_ecs::system::{Deferred, Res, Resource, SystemBuffer, SystemParam}; @@ -103,8 +100,8 @@ impl Hash for DiagnosticPath { } } -impl std::fmt::Display for DiagnosticPath { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl core::fmt::Display for DiagnosticPath { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { self.path.fmt(f) } } diff --git a/crates/bevy_diagnostic/src/lib.rs b/crates/bevy_diagnostic/src/lib.rs index 88fdac61035e0..5db2c188b8666 100644 --- a/crates/bevy_diagnostic/src/lib.rs +++ b/crates/bevy_diagnostic/src/lib.rs @@ -11,6 +11,8 @@ //! It allows users to easily add diagnostic functionality to their Bevy applications, enhancing //! their ability to monitor and optimize their game's. +extern crate alloc; + mod diagnostic; mod entity_count_diagnostics_plugin; mod frame_time_diagnostics_plugin; diff --git a/crates/bevy_ecs/examples/change_detection.rs b/crates/bevy_ecs/examples/change_detection.rs index 0f49c5e709f7d..41300653ba6fb 100644 --- a/crates/bevy_ecs/examples/change_detection.rs +++ b/crates/bevy_ecs/examples/change_detection.rs @@ -6,6 +6,8 @@ //! To demonstrate change detection, there are some console outputs based on changes in //! the `EntityCounter` resource and updated Age components +#![expect(clippy::std_instead_of_core)] + use bevy_ecs::prelude::*; use rand::Rng; use std::ops::Deref; diff --git a/crates/bevy_ecs/examples/resources.rs b/crates/bevy_ecs/examples/resources.rs index ff266fdd45234..f5de6f7b3d30e 100644 --- a/crates/bevy_ecs/examples/resources.rs +++ b/crates/bevy_ecs/examples/resources.rs @@ -1,6 +1,8 @@ //! In this example we add a counter resource and increase its value in one system, //! while a different system prints the current count to the console. +#![expect(clippy::std_instead_of_core)] + use bevy_ecs::prelude::*; use rand::Rng; use std::ops::Deref; diff --git a/crates/bevy_ecs/macros/src/lib.rs b/crates/bevy_ecs/macros/src/lib.rs index 291e9d116d93d..fc15c5c6c7979 100644 --- a/crates/bevy_ecs/macros/src/lib.rs +++ b/crates/bevy_ecs/macros/src/lib.rs @@ -118,7 +118,7 @@ pub fn derive_bundle(input: TokenStream) -> TokenStream { BundleFieldKind::Ignore => { field_from_components.push(quote! { - #field: ::std::default::Default::default(), + #field: ::core::default::Default::default(), }); } } diff --git a/crates/bevy_ecs/src/archetype.rs b/crates/bevy_ecs/src/archetype.rs index 7df84b87c4a79..3f5456370258c 100644 --- a/crates/bevy_ecs/src/archetype.rs +++ b/crates/bevy_ecs/src/archetype.rs @@ -27,7 +27,7 @@ use crate::{ storage::{ImmutableSparseSet, SparseArray, SparseSet, SparseSetIndex, TableId, TableRow}, }; use bevy_utils::HashMap; -use std::{ +use core::{ hash::Hash, ops::{Index, IndexMut, RangeFrom}, }; diff --git a/crates/bevy_ecs/src/batching.rs b/crates/bevy_ecs/src/batching.rs index 192305c5519c7..4253d8af34c29 100644 --- a/crates/bevy_ecs/src/batching.rs +++ b/crates/bevy_ecs/src/batching.rs @@ -1,6 +1,6 @@ //! Types for controlling batching behavior during parallel processing. -use std::ops::Range; +use core::ops::Range; /// Dictates how a parallel operation chunks up large quantities /// during iteration. diff --git a/crates/bevy_ecs/src/bundle.rs b/crates/bevy_ecs/src/bundle.rs index f1afd03fafc97..bbe114a2fee87 100644 --- a/crates/bevy_ecs/src/bundle.rs +++ b/crates/bevy_ecs/src/bundle.rs @@ -23,8 +23,8 @@ use crate::{ use bevy_ptr::{ConstNonNull, OwningPtr}; use bevy_utils::{all_tuples, HashMap, HashSet, TypeIdMap}; #[cfg(feature = "track_change_detection")] -use std::panic::Location; -use std::{any::TypeId, ptr::NonNull}; +use core::panic::Location; +use core::{any::TypeId, ptr::NonNull}; /// The `Bundle` trait enables insertion and removal of [`Component`]s from an entity. /// @@ -1336,7 +1336,7 @@ impl Bundles { // - its info was created // - appropriate storage for it has been initialized. // - it was created in the same order as the components in T - unsafe { BundleInfo::new(std::any::type_name::(), components, component_ids, id) }; + unsafe { BundleInfo::new(core::any::type_name::(), components, component_ids, id) }; bundle_infos.push(bundle_info); id }); diff --git a/crates/bevy_ecs/src/change_detection.rs b/crates/bevy_ecs/src/change_detection.rs index 2dcaedfaeefd4..2c7c6615fce4c 100644 --- a/crates/bevy_ecs/src/change_detection.rs +++ b/crates/bevy_ecs/src/change_detection.rs @@ -5,15 +5,16 @@ use crate::{ ptr::PtrMut, system::Resource, }; -#[cfg(feature = "track_change_detection")] -use bevy_ptr::ThinSlicePtr; use bevy_ptr::{Ptr, UnsafeCellDeref}; -#[cfg(feature = "track_change_detection")] -use std::{cell::UnsafeCell, panic::Location}; -use std::{ +use core::{ mem, ops::{Deref, DerefMut}, }; +#[cfg(feature = "track_change_detection")] +use { + bevy_ptr::ThinSlicePtr, + core::{cell::UnsafeCell, panic::Location}, +}; /// The (arbitrarily chosen) minimum number of world tick increments between `check_tick` scans. /// @@ -457,10 +458,10 @@ macro_rules! impl_methods { macro_rules! impl_debug { ($name:ident < $( $generics:tt ),+ >, $($traits:ident)?) => { - impl<$($generics),* : ?Sized $(+ $traits)?> std::fmt::Debug for $name<$($generics),*> - where T: std::fmt::Debug + impl<$($generics),* : ?Sized $(+ $traits)?> core::fmt::Debug for $name<$($generics),*> + where T: core::fmt::Debug { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { f.debug_tuple(stringify!($name)) .field(&self.value) .finish() @@ -1123,8 +1124,8 @@ impl<'w> DetectChangesMut for MutUntyped<'w> { } } -impl std::fmt::Debug for MutUntyped<'_> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl core::fmt::Debug for MutUntyped<'_> { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { f.debug_tuple("MutUntyped") .field(&self.value.as_ptr()) .finish() @@ -1198,9 +1199,9 @@ mod tests { use bevy_ecs_macros::Resource; use bevy_ptr::PtrMut; use bevy_reflect::{FromType, ReflectFromPtr}; - use std::ops::{Deref, DerefMut}; + use core::ops::{Deref, DerefMut}; #[cfg(feature = "track_change_detection")] - use std::panic::Location; + use core::panic::Location; use crate::{ self as bevy_ecs, diff --git a/crates/bevy_ecs/src/component.rs b/crates/bevy_ecs/src/component.rs index a1215d01e6046..c3599842031d3 100644 --- a/crates/bevy_ecs/src/component.rs +++ b/crates/bevy_ecs/src/component.rs @@ -10,22 +10,21 @@ use crate::{ system::{Local, Resource, SystemParam}, world::{DeferredWorld, FromWorld, World}, }; +use alloc::{borrow::Cow, sync::Arc}; pub use bevy_ecs_macros::Component; use bevy_ptr::{OwningPtr, UnsafeCellDeref}; #[cfg(feature = "bevy_reflect")] use bevy_reflect::Reflect; use bevy_utils::{HashMap, TypeIdMap}; #[cfg(feature = "track_change_detection")] -use std::panic::Location; -use std::{ +use core::panic::Location; +use core::{ alloc::Layout, any::{Any, TypeId}, - borrow::Cow, cell::UnsafeCell, fmt::Debug, marker::PhantomData, mem::needs_drop, - sync::Arc, }; /// A data type that can be used to store data for an [entity]. @@ -726,7 +725,7 @@ pub struct ComponentDescriptor { // We need to ignore the `drop` field in our `Debug` impl impl Debug for ComponentDescriptor { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { f.debug_struct("ComponentDescriptor") .field("name", &self.name) .field("storage_type", &self.storage_type) @@ -751,7 +750,7 @@ impl ComponentDescriptor { /// Create a new `ComponentDescriptor` for the type `T`. pub fn new() -> Self { Self { - name: Cow::Borrowed(std::any::type_name::()), + name: Cow::Borrowed(core::any::type_name::()), storage_type: T::STORAGE_TYPE, is_send_and_sync: true, type_id: Some(TypeId::of::()), @@ -786,7 +785,7 @@ impl ComponentDescriptor { /// The [`StorageType`] for resources is always [`StorageType::Table`]. pub fn new_resource() -> Self { Self { - name: Cow::Borrowed(std::any::type_name::()), + name: Cow::Borrowed(core::any::type_name::()), // PERF: `SparseStorage` may actually be a more // reasonable choice as `storage_type` for resources. storage_type: StorageType::Table, @@ -799,7 +798,7 @@ impl ComponentDescriptor { fn new_non_send(storage_type: StorageType) -> Self { Self { - name: Cow::Borrowed(std::any::type_name::()), + name: Cow::Borrowed(core::any::type_name::()), storage_type, is_send_and_sync: false, type_id: Some(TypeId::of::()), @@ -1270,7 +1269,7 @@ impl ComponentIdFor<'_, T> { } } -impl std::ops::Deref for ComponentIdFor<'_, T> { +impl core::ops::Deref for ComponentIdFor<'_, T> { type Target = ComponentId; fn deref(&self) -> &Self::Target { &self.0.component_id @@ -1351,7 +1350,7 @@ impl RequiredComponentConstructor { pub struct RequiredComponents(pub(crate) HashMap); impl Debug for RequiredComponents { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { f.debug_tuple("RequiredComponents") .field(&self.0.keys()) .finish() diff --git a/crates/bevy_ecs/src/entity/hash.rs b/crates/bevy_ecs/src/entity/hash.rs index fac4ad12d8055..1b1ff531ffeb4 100644 --- a/crates/bevy_ecs/src/entity/hash.rs +++ b/crates/bevy_ecs/src/entity/hash.rs @@ -1,4 +1,4 @@ -use std::hash::{BuildHasher, Hasher}; +use core::hash::{BuildHasher, Hasher}; #[cfg(feature = "bevy_reflect")] use bevy_reflect::Reflect; diff --git a/crates/bevy_ecs/src/entity/mod.rs b/crates/bevy_ecs/src/entity/mod.rs index 3ad78f73a21af..6df7f3603a1eb 100644 --- a/crates/bevy_ecs/src/entity/mod.rs +++ b/crates/bevy_ecs/src/entity/mod.rs @@ -57,12 +57,12 @@ use crate::{ }, storage::{SparseSetIndex, TableId, TableRow}, }; +use core::{fmt, hash::Hash, mem, num::NonZero, sync::atomic::Ordering}; #[cfg(feature = "serialize")] use serde::{Deserialize, Serialize}; -use std::{fmt, hash::Hash, mem, num::NonZero, sync::atomic::Ordering}; #[cfg(target_has_atomic = "64")] -use std::sync::atomic::AtomicI64 as AtomicIdCursor; +use core::sync::atomic::AtomicI64 as AtomicIdCursor; #[cfg(target_has_atomic = "64")] type IdCursor = i64; @@ -70,7 +70,7 @@ type IdCursor = i64; /// do not. This fallback allows compilation using a 32-bit cursor instead, with /// the caveat that some conversions may fail (and panic) at runtime. #[cfg(not(target_has_atomic = "64"))] -use std::sync::atomic::AtomicIsize as AtomicIdCursor; +use core::sync::atomic::AtomicIsize as AtomicIdCursor; #[cfg(not(target_has_atomic = "64"))] type IdCursor = isize; @@ -185,7 +185,7 @@ impl Eq for Entity {} // See impl PartialOrd for Entity { #[inline] - fn partial_cmp(&self, other: &Self) -> Option { + fn partial_cmp(&self, other: &Self) -> Option { // Make use of our `Ord` impl to ensure optimal codegen output Some(self.cmp(other)) } @@ -199,7 +199,7 @@ impl PartialOrd for Entity { // See impl Ord for Entity { #[inline] - fn cmp(&self, other: &Self) -> std::cmp::Ordering { + fn cmp(&self, other: &Self) -> core::cmp::Ordering { // This will result in better codegen for ordering comparisons, plus // avoids pitfalls with regards to macro codegen relying on property // position when we want to compare against the bit representation. @@ -209,7 +209,7 @@ impl Ord for Entity { impl Hash for Entity { #[inline] - fn hash(&self, state: &mut H) { + fn hash(&self, state: &mut H) { self.to_bits().hash(state); } } @@ -451,10 +451,10 @@ pub struct ReserveEntitiesIterator<'a> { meta: &'a [EntityMeta], // Reserved indices formerly in the freelist to hand out. - freelist_indices: std::slice::Iter<'a, u32>, + freelist_indices: core::slice::Iter<'a, u32>, // New Entity indices to hand out, outside the range of meta.len(). - new_indices: std::ops::Range, + new_indices: core::ops::Range, } impl<'a> Iterator for ReserveEntitiesIterator<'a> { @@ -1160,7 +1160,7 @@ mod tests { // part of the best-case performance changes in PR#9903. #[test] fn entity_hash_keeps_similar_ids_together() { - use std::hash::BuildHasher; + use core::hash::BuildHasher; let hash = EntityHash; let first_id = 0xC0FFEE << 8; @@ -1175,7 +1175,7 @@ mod tests { #[test] fn entity_hash_id_bitflip_affects_high_7_bits() { - use std::hash::BuildHasher; + use core::hash::BuildHasher; let hash = EntityHash; diff --git a/crates/bevy_ecs/src/event/base.rs b/crates/bevy_ecs/src/event/base.rs index ab56ac58ae5b4..ca26a0abee2e6 100644 --- a/crates/bevy_ecs/src/event/base.rs +++ b/crates/bevy_ecs/src/event/base.rs @@ -1,7 +1,7 @@ use crate::{component::Component, traversal::Traversal}; #[cfg(feature = "bevy_reflect")] use bevy_reflect::Reflect; -use std::{ +use core::{ cmp::Ordering, fmt, hash::{Hash, Hasher}, @@ -82,7 +82,7 @@ impl fmt::Debug for EventId { write!( f, "event<{}>#{}", - std::any::type_name::().split("::").last().unwrap(), + core::any::type_name::().split("::").last().unwrap(), self.id, ) } diff --git a/crates/bevy_ecs/src/event/collections.rs b/crates/bevy_ecs/src/event/collections.rs index f9e813096c6b1..4c9bc1996f8da 100644 --- a/crates/bevy_ecs/src/event/collections.rs +++ b/crates/bevy_ecs/src/event/collections.rs @@ -1,17 +1,18 @@ use crate as bevy_ecs; -#[cfg(feature = "bevy_reflect")] -use bevy_ecs::reflect::ReflectResource; use bevy_ecs::{ event::{Event, EventCursor, EventId, EventInstance}, system::Resource, }; -#[cfg(feature = "bevy_reflect")] -use bevy_reflect::{std_traits::ReflectDefault, Reflect}; use bevy_utils::detailed_trace; -use std::{ +use core::{ marker::PhantomData, ops::{Deref, DerefMut}, }; +#[cfg(feature = "bevy_reflect")] +use { + bevy_ecs::reflect::ReflectResource, + bevy_reflect::{std_traits::ReflectDefault, Reflect}, +}; /// An event collection that represents the events that occurred within the last two /// [`Events::update`] calls. @@ -201,7 +202,7 @@ impl Events { /// /// If you need access to the events that were removed, consider using [`Events::update_drain`]. pub fn update(&mut self) { - std::mem::swap(&mut self.events_a, &mut self.events_b); + core::mem::swap(&mut self.events_a, &mut self.events_b); self.events_b.clear(); self.events_b.start_event_count = self.event_count; debug_assert_eq!( @@ -216,7 +217,7 @@ impl Events { /// If you do not need to take ownership of the removed events, use [`Events::update`] instead. #[must_use = "If you do not need the returned events, call .update() instead."] pub fn update_drain(&mut self) -> impl Iterator + '_ { - std::mem::swap(&mut self.events_a, &mut self.events_b); + core::mem::swap(&mut self.events_a, &mut self.events_b); let iter = self.events_b.events.drain(..); self.events_b.start_event_count = self.event_count; debug_assert_eq!( diff --git a/crates/bevy_ecs/src/event/event_cursor.rs b/crates/bevy_ecs/src/event/event_cursor.rs index 4868197712a6e..8fdcea8d244c5 100644 --- a/crates/bevy_ecs/src/event/event_cursor.rs +++ b/crates/bevy_ecs/src/event/event_cursor.rs @@ -4,7 +4,7 @@ use bevy_ecs::event::{ }; #[cfg(feature = "multi_threaded")] use bevy_ecs::event::{EventMutParIter, EventParIter}; -use std::marker::PhantomData; +use core::marker::PhantomData; // Deprecated in favor of `EventCursor`, there is no nice way to deprecate this // because generic constraints are not allowed in type aliases, so this will always diff --git a/crates/bevy_ecs/src/event/iterators.rs b/crates/bevy_ecs/src/event/iterators.rs index df1f9aae621d9..28c671fe947db 100644 --- a/crates/bevy_ecs/src/event/iterators.rs +++ b/crates/bevy_ecs/src/event/iterators.rs @@ -3,7 +3,7 @@ use crate as bevy_ecs; use bevy_ecs::batching::BatchingStrategy; use bevy_ecs::event::{Event, EventCursor, EventId, EventInstance, Events}; use bevy_utils::detailed_trace; -use std::{iter::Chain, slice::Iter}; +use core::{iter::Chain, slice::Iter}; /// An iterator that yields any unread events from an [`EventReader`](super::EventReader) or [`EventCursor`]. #[derive(Debug)] @@ -224,7 +224,7 @@ impl<'a, E: Event> EventParIter<'a, E> { .batching_strategy .calc_batch_size(|| self.len(), thread_count); let chunks = self.slices.map(|s| s.chunks_exact(batch_size)); - let remainders = chunks.each_ref().map(std::slice::ChunksExact::remainder); + let remainders = chunks.each_ref().map(core::slice::ChunksExact::remainder); pool.scope(|scope| { for batch in chunks.into_iter().flatten().chain(remainders) { diff --git a/crates/bevy_ecs/src/event/mod.rs b/crates/bevy_ecs/src/event/mod.rs index a570be5cab16e..f7f46af258a3c 100644 --- a/crates/bevy_ecs/src/event/mod.rs +++ b/crates/bevy_ecs/src/event/mod.rs @@ -423,7 +423,7 @@ mod tests { #[test] fn test_event_cursor_par_read() { use crate::prelude::*; - use std::sync::atomic::{AtomicUsize, Ordering}; + use core::sync::atomic::{AtomicUsize, Ordering}; #[derive(Resource)] struct Counter(AtomicUsize); @@ -465,7 +465,7 @@ mod tests { #[test] fn test_event_cursor_par_read_mut() { use crate::prelude::*; - use std::sync::atomic::{AtomicUsize, Ordering}; + use core::sync::atomic::{AtomicUsize, Ordering}; #[derive(Resource)] struct Counter(AtomicUsize); diff --git a/crates/bevy_ecs/src/event/mut_iterators.rs b/crates/bevy_ecs/src/event/mut_iterators.rs index 490503af7eb53..5f70875a31702 100644 --- a/crates/bevy_ecs/src/event/mut_iterators.rs +++ b/crates/bevy_ecs/src/event/mut_iterators.rs @@ -3,7 +3,7 @@ use crate as bevy_ecs; use bevy_ecs::batching::BatchingStrategy; use bevy_ecs::event::{Event, EventCursor, EventId, EventInstance, Events}; use bevy_utils::detailed_trace; -use std::{iter::Chain, slice::IterMut}; +use core::{iter::Chain, slice::IterMut}; /// An iterator that yields any unread events from an [`EventMutator`] or [`EventCursor`]. /// diff --git a/crates/bevy_ecs/src/event/update.rs b/crates/bevy_ecs/src/event/update.rs index 09bdc49ae1237..bf3c07de4d3c8 100644 --- a/crates/bevy_ecs/src/event/update.rs +++ b/crates/bevy_ecs/src/event/update.rs @@ -8,7 +8,7 @@ use bevy_ecs::{ }; use bevy_ecs_macros::SystemSet; #[cfg(feature = "bevy_reflect")] -use std::hash::Hash; +use core::hash::Hash; use super::registry::ShouldUpdateEvents; diff --git a/crates/bevy_ecs/src/identifier/error.rs b/crates/bevy_ecs/src/identifier/error.rs index 6f0ee8a972706..8d278528ab99c 100644 --- a/crates/bevy_ecs/src/identifier/error.rs +++ b/crates/bevy_ecs/src/identifier/error.rs @@ -1,7 +1,7 @@ //! Error types for [`super::Identifier`] conversions. An ID can be converted //! to various kinds, but these can fail if they are not valid forms of those //! kinds. The error type in this module encapsulates the various failure modes. -use std::fmt; +use core::fmt; /// An Error type for [`super::Identifier`], mostly for providing error /// handling for conversions of an ID to a type abstracting over the ID bits. @@ -26,4 +26,4 @@ impl fmt::Display for IdentifierError { } } -impl std::error::Error for IdentifierError {} +impl core::error::Error for IdentifierError {} diff --git a/crates/bevy_ecs/src/identifier/masks.rs b/crates/bevy_ecs/src/identifier/masks.rs index 85fb393cb6f13..30ece9d8e3eec 100644 --- a/crates/bevy_ecs/src/identifier/masks.rs +++ b/crates/bevy_ecs/src/identifier/masks.rs @@ -1,4 +1,4 @@ -use std::num::NonZero; +use core::num::NonZero; use super::kinds::IdKind; diff --git a/crates/bevy_ecs/src/identifier/mod.rs b/crates/bevy_ecs/src/identifier/mod.rs index 6018a9f85fca7..3774ea5b3fef5 100644 --- a/crates/bevy_ecs/src/identifier/mod.rs +++ b/crates/bevy_ecs/src/identifier/mod.rs @@ -7,7 +7,7 @@ use bevy_reflect::Reflect; use self::{error::IdentifierError, kinds::IdKind, masks::IdentifierMask}; -use std::{hash::Hash, num::NonZero}; +use core::{hash::Hash, num::NonZero}; pub mod error; pub(crate) mod kinds; @@ -150,7 +150,7 @@ impl Eq for Identifier {} // See impl PartialOrd for Identifier { #[inline] - fn partial_cmp(&self, other: &Self) -> Option { + fn partial_cmp(&self, other: &Self) -> Option { // Make use of our `Ord` impl to ensure optimal codegen output Some(self.cmp(other)) } @@ -164,7 +164,7 @@ impl PartialOrd for Identifier { // See impl Ord for Identifier { #[inline] - fn cmp(&self, other: &Self) -> std::cmp::Ordering { + fn cmp(&self, other: &Self) -> core::cmp::Ordering { // This will result in better codegen for ordering comparisons, plus // avoids pitfalls with regards to macro codegen relying on property // position when we want to compare against the bit representation. @@ -174,7 +174,7 @@ impl Ord for Identifier { impl Hash for Identifier { #[inline] - fn hash(&self, state: &mut H) { + fn hash(&self, state: &mut H) { self.to_bits().hash(state); } } diff --git a/crates/bevy_ecs/src/intern.rs b/crates/bevy_ecs/src/intern.rs index 84ade580246c1..179fdc8b82ad9 100644 --- a/crates/bevy_ecs/src/intern.rs +++ b/crates/bevy_ecs/src/intern.rs @@ -4,12 +4,8 @@ //! speed up code by shrinking the stack size of large types, //! and make comparisons for any type as fast as integers. -use std::{ - fmt::Debug, - hash::Hash, - ops::Deref, - sync::{OnceLock, PoisonError, RwLock}, -}; +use core::{fmt::Debug, hash::Hash, ops::Deref}; +use std::sync::{OnceLock, PoisonError, RwLock}; use bevy_utils::HashSet; @@ -70,13 +66,13 @@ impl Eq for Interned {} // Important: This must be kept in sync with the PartialEq/Eq implementation impl Hash for Interned { - fn hash(&self, state: &mut H) { + fn hash(&self, state: &mut H) { self.0.ref_hash(state); } } impl Debug for Interned { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { self.0.fmt(f) } } @@ -98,7 +94,7 @@ pub trait Internable: Hash + Eq { fn ref_eq(&self, other: &Self) -> bool; /// Feeds the reference to the hasher. - fn ref_hash(&self, state: &mut H); + fn ref_hash(&self, state: &mut H); } impl Internable for str { @@ -111,7 +107,7 @@ impl Internable for str { self.as_ptr() == other.as_ptr() && self.len() == other.len() } - fn ref_hash(&self, state: &mut H) { + fn ref_hash(&self, state: &mut H) { self.len().hash(state); self.as_ptr().hash(state); } @@ -168,10 +164,8 @@ impl Default for Interner { #[cfg(test)] mod tests { - use std::{ - collections::hash_map::DefaultHasher, - hash::{Hash, Hasher}, - }; + use core::hash::{Hash, Hasher}; + use std::collections::hash_map::DefaultHasher; use crate::intern::{Internable, Interned, Interner}; @@ -186,11 +180,11 @@ mod tests { } fn ref_eq(&self, other: &Self) -> bool { - std::ptr::eq(self, other) + core::ptr::eq(self, other) } fn ref_hash(&self, state: &mut H) { - std::ptr::hash(self, state); + core::ptr::hash(self, state); } } @@ -217,11 +211,11 @@ mod tests { } fn ref_eq(&self, other: &Self) -> bool { - std::ptr::eq(self, other) + core::ptr::eq(self, other) } fn ref_hash(&self, state: &mut H) { - std::ptr::hash(self, state); + core::ptr::hash(self, state); } } diff --git a/crates/bevy_ecs/src/label.rs b/crates/bevy_ecs/src/label.rs index 519171eded9ef..e3f5078b22f71 100644 --- a/crates/bevy_ecs/src/label.rs +++ b/crates/bevy_ecs/src/label.rs @@ -1,10 +1,14 @@ //! Traits used by label implementations -use std::{ +use core::{ any::Any, hash::{Hash, Hasher}, }; +// Re-exported for use within `define_label!` +#[doc(hidden)] +pub use alloc::boxed::Box; + /// An object safe version of [`Eq`]. This trait is automatically implemented /// for any `'static` type that implements `Eq`. pub trait DynEq: Any { @@ -110,20 +114,20 @@ macro_rules! define_label { ) => { $(#[$label_attr])* - pub trait $label_trait_name: 'static + Send + Sync + ::std::fmt::Debug { + pub trait $label_trait_name: 'static + Send + Sync + ::core::fmt::Debug { $($trait_extra_methods)* /// Clones this ` #[doc = stringify!($label_trait_name)] ///`. - fn dyn_clone(&self) -> ::std::boxed::Box; + fn dyn_clone(&self) -> $crate::label::Box; /// Casts this value to a form where it can be compared with other type-erased values. fn as_dyn_eq(&self) -> &dyn $crate::label::DynEq; /// Feeds this value into the given [`Hasher`]. - fn dyn_hash(&self, state: &mut dyn ::std::hash::Hasher); + fn dyn_hash(&self, state: &mut dyn ::core::hash::Hasher); /// Returns an [`Interned`] value corresponding to `self`. fn intern(&self) -> $crate::intern::Interned @@ -136,7 +140,7 @@ macro_rules! define_label { $($interned_extra_methods_impl)* - fn dyn_clone(&self) -> ::std::boxed::Box { + fn dyn_clone(&self) -> $crate::label::Box { (**self).dyn_clone() } @@ -145,7 +149,7 @@ macro_rules! define_label { (**self).as_dyn_eq() } - fn dyn_hash(&self, state: &mut dyn ::std::hash::Hasher) { + fn dyn_hash(&self, state: &mut dyn ::core::hash::Hasher) { (**self).dyn_hash(state); } @@ -162,8 +166,8 @@ macro_rules! define_label { impl Eq for dyn $label_trait_name {} - impl ::std::hash::Hash for dyn $label_trait_name { - fn hash(&self, state: &mut H) { + impl ::core::hash::Hash for dyn $label_trait_name { + fn hash(&self, state: &mut H) { self.dyn_hash(state); } } @@ -174,15 +178,15 @@ macro_rules! define_label { } fn ref_eq(&self, other: &Self) -> bool { - use ::std::ptr; + use ::core::ptr; // Test that both the type id and pointer address are equivalent. self.as_dyn_eq().type_id() == other.as_dyn_eq().type_id() && ptr::addr_eq(ptr::from_ref::(self), ptr::from_ref::(other)) } - fn ref_hash(&self, state: &mut H) { - use ::std::{hash::Hash, ptr}; + fn ref_hash(&self, state: &mut H) { + use ::core::{hash::Hash, ptr}; // Hash the type id... self.as_dyn_eq().type_id().hash(state); diff --git a/crates/bevy_ecs/src/lib.rs b/crates/bevy_ecs/src/lib.rs index cf0a04e5b6353..69dfea19f5bda 100644 --- a/crates/bevy_ecs/src/lib.rs +++ b/crates/bevy_ecs/src/lib.rs @@ -13,6 +13,8 @@ #[cfg(target_pointer_width = "16")] compile_error!("bevy_ecs cannot safely compile for a 16-bit platform."); +extern crate alloc; + pub mod archetype; pub mod batching; pub mod bundle; @@ -40,14 +42,6 @@ pub use bevy_ptr as ptr; /// /// This includes the most common types in this crate, re-exported for your convenience. pub mod prelude { - #[doc(hidden)] - #[cfg(feature = "reflect_functions")] - pub use crate::reflect::AppFunctionRegistry; - #[doc(hidden)] - #[cfg(feature = "bevy_reflect")] - pub use crate::reflect::{ - AppTypeRegistry, ReflectComponent, ReflectFromWorld, ReflectResource, - }; #[doc(hidden)] pub use crate::{ bundle::Bundle, @@ -72,6 +66,16 @@ pub mod prelude { OnReplace, World, }, }; + + #[doc(hidden)] + #[cfg(feature = "bevy_reflect")] + pub use crate::reflect::{ + AppTypeRegistry, ReflectComponent, ReflectFromWorld, ReflectResource, + }; + + #[doc(hidden)] + #[cfg(feature = "reflect_functions")] + pub use crate::reflect::AppFunctionRegistry; } #[cfg(test)] @@ -87,17 +91,16 @@ mod tests { system::Resource, world::{EntityMut, EntityRef, Mut, World}, }; + use alloc::sync::Arc; use bevy_tasks::{ComputeTaskPool, TaskPool}; use bevy_utils::HashSet; - use std::{ + use core::{ any::TypeId, marker::PhantomData, num::NonZero, - sync::{ - atomic::{AtomicUsize, Ordering}, - Arc, Mutex, - }, + sync::atomic::{AtomicUsize, Ordering}, }; + use std::sync::Mutex; #[derive(Component, Resource, Debug, PartialEq, Eq, Hash, Clone, Copy)] struct A(usize); diff --git a/crates/bevy_ecs/src/observer/entity_observer.rs b/crates/bevy_ecs/src/observer/entity_observer.rs index ce30201785758..0f9baba760a85 100644 --- a/crates/bevy_ecs/src/observer/entity_observer.rs +++ b/crates/bevy_ecs/src/observer/entity_observer.rs @@ -15,7 +15,7 @@ impl Component for ObservedBy { hooks.on_remove(|mut world, entity, _| { let observed_by = { let mut component = world.get_mut::(entity).unwrap(); - std::mem::take(&mut component.0) + core::mem::take(&mut component.0) }; for e in observed_by { let (total_entities, despawned_watched_entities) = { diff --git a/crates/bevy_ecs/src/observer/mod.rs b/crates/bevy_ecs/src/observer/mod.rs index 50ce3b7fdedef..fe0154b7a4289 100644 --- a/crates/bevy_ecs/src/observer/mod.rs +++ b/crates/bevy_ecs/src/observer/mod.rs @@ -18,7 +18,7 @@ use crate::{ }; use bevy_ptr::Ptr; use bevy_utils::HashMap; -use std::{ +use core::{ fmt::Debug, marker::PhantomData, ops::{Deref, DerefMut}, @@ -121,7 +121,7 @@ impl<'w, E, B: Bundle> Trigger<'w, E, B> { } impl<'w, E: Debug, B: Bundle> Debug for Trigger<'w, E, B> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { f.debug_struct("Trigger") .field("event", &self.event) .field("propagate", &self.propagate) @@ -528,7 +528,7 @@ impl World { #[cfg(test)] mod tests { - use std::vec; + use alloc::vec; use bevy_ptr::OwningPtr; diff --git a/crates/bevy_ecs/src/observer/runner.rs b/crates/bevy_ecs/src/observer/runner.rs index 024d46b3c93a6..e45eb763146c1 100644 --- a/crates/bevy_ecs/src/observer/runner.rs +++ b/crates/bevy_ecs/src/observer/runner.rs @@ -1,4 +1,4 @@ -use std::any::Any; +use core::any::Any; use crate::{ component::{ComponentHook, ComponentHooks, ComponentId, StorageType}, @@ -70,7 +70,7 @@ impl Component for ObserverState { }); }); hooks.on_remove(|mut world, entity, _| { - let descriptor = std::mem::take( + let descriptor = core::mem::take( &mut world .entity_mut(entity) .get_mut::() diff --git a/crates/bevy_ecs/src/observer/trigger_event.rs b/crates/bevy_ecs/src/observer/trigger_event.rs index 95d404a3985ff..5221aff070e2e 100644 --- a/crates/bevy_ecs/src/observer/trigger_event.rs +++ b/crates/bevy_ecs/src/observer/trigger_event.rs @@ -130,7 +130,7 @@ impl TriggerTargets for Entity { } fn entities(&self) -> &[Entity] { - std::slice::from_ref(self) + core::slice::from_ref(self) } } @@ -156,7 +156,7 @@ impl TriggerTargets for [Entity; N] { impl TriggerTargets for ComponentId { fn components(&self) -> &[ComponentId] { - std::slice::from_ref(self) + core::slice::from_ref(self) } fn entities(&self) -> &[Entity] { diff --git a/crates/bevy_ecs/src/query/access.rs b/crates/bevy_ecs/src/query/access.rs index 75b2b09deaac2..cf504c2606635 100644 --- a/crates/bevy_ecs/src/query/access.rs +++ b/crates/bevy_ecs/src/query/access.rs @@ -1,7 +1,6 @@ use crate::storage::SparseSetIndex; -use core::fmt; +use core::{fmt, fmt::Debug, marker::PhantomData}; use fixedbitset::FixedBitSet; -use std::{fmt::Debug, marker::PhantomData}; /// A wrapper struct to make Debug representations of [`FixedBitSet`] easier /// to read, when used to store [`SparseSetIndex`]. @@ -1279,8 +1278,8 @@ mod tests { use crate::query::{ access::AccessFilters, Access, AccessConflicts, FilteredAccess, FilteredAccessSet, }; + use core::marker::PhantomData; use fixedbitset::FixedBitSet; - use std::marker::PhantomData; fn create_sample_access() -> Access { let mut access = Access::::default(); diff --git a/crates/bevy_ecs/src/query/builder.rs b/crates/bevy_ecs/src/query/builder.rs index d2d007196e4ad..af1af7749e89b 100644 --- a/crates/bevy_ecs/src/query/builder.rs +++ b/crates/bevy_ecs/src/query/builder.rs @@ -1,4 +1,4 @@ -use std::marker::PhantomData; +use core::marker::PhantomData; use crate::{ component::{ComponentId, StorageType}, @@ -262,7 +262,7 @@ impl<'w, D: QueryData, F: QueryFilter> QueryBuilder<'w, D, F> { // SAFETY: // - We have included all required accesses for NewQ and NewF // - The layout of all QueryBuilder instances is the same - unsafe { std::mem::transmute(self) } + unsafe { core::mem::transmute(self) } } /// Create a [`QueryState`] with the accesses of the builder. diff --git a/crates/bevy_ecs/src/query/error.rs b/crates/bevy_ecs/src/query/error.rs index bdf503b32cf41..6778a75856249 100644 --- a/crates/bevy_ecs/src/query/error.rs +++ b/crates/bevy_ecs/src/query/error.rs @@ -18,10 +18,10 @@ pub enum QueryEntityError<'w> { AliasedMutability(Entity), } -impl<'w> std::error::Error for QueryEntityError<'w> {} +impl<'w> core::error::Error for QueryEntityError<'w> {} -impl<'w> std::fmt::Display for QueryEntityError<'w> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl<'w> core::fmt::Display for QueryEntityError<'w> { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { match *self { Self::QueryDoesNotMatch(entity, world) => { write!( @@ -39,8 +39,8 @@ impl<'w> std::fmt::Display for QueryEntityError<'w> { } } -impl<'w> std::fmt::Debug for QueryEntityError<'w> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl<'w> core::fmt::Debug for QueryEntityError<'w> { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { match *self { Self::QueryDoesNotMatch(entity, world) => { write!(f, "QueryDoesNotMatch({entity} with components ")?; @@ -54,10 +54,10 @@ impl<'w> std::fmt::Debug for QueryEntityError<'w> { } fn format_archetype( - f: &mut std::fmt::Formatter<'_>, + f: &mut core::fmt::Formatter<'_>, world: UnsafeWorldCell<'_>, entity: Entity, -) -> std::fmt::Result { +) -> core::fmt::Result { // We know entity is still alive let entity = world .get_entity(entity) diff --git a/crates/bevy_ecs/src/query/fetch.rs b/crates/bevy_ecs/src/query/fetch.rs index 57ff7e39f1a00..e2140a36912ff 100644 --- a/crates/bevy_ecs/src/query/fetch.rs +++ b/crates/bevy_ecs/src/query/fetch.rs @@ -13,8 +13,8 @@ use crate::{ }; use bevy_ptr::{ThinSlicePtr, UnsafeCellDeref}; use bevy_utils::all_tuples; +use core::{cell::UnsafeCell, marker::PhantomData}; use smallvec::SmallVec; -use std::{cell::UnsafeCell, marker::PhantomData}; /// Types that can be fetched from a [`World`] using a [`Query`]. /// @@ -846,7 +846,7 @@ where assert!( access.is_compatible(&my_access), "`EntityRefExcept<{}>` conflicts with a previous access in this query.", - std::any::type_name::(), + core::any::type_name::(), ); access.extend(&my_access); } @@ -945,7 +945,7 @@ where assert!( access.is_compatible(&my_access), "`EntityMutExcept<{}>` conflicts with a previous access in this query.", - std::any::type_name::() + core::any::type_name::() ); access.extend(&my_access); } @@ -1182,7 +1182,7 @@ unsafe impl WorldQuery for &T { assert!( !access.access().has_component_write(component_id), "&{} conflicts with a previous access in this query. Shared access cannot coincide with exclusive access.", - std::any::type_name::(), + core::any::type_name::(), ); access.add_component_read(component_id); } @@ -1381,7 +1381,7 @@ unsafe impl<'__w, T: Component> WorldQuery for Ref<'__w, T> { assert!( !access.access().has_component_write(component_id), "&{} conflicts with a previous access in this query. Shared access cannot coincide with exclusive access.", - std::any::type_name::(), + core::any::type_name::(), ); access.add_component_read(component_id); } @@ -1580,7 +1580,7 @@ unsafe impl<'__w, T: Component> WorldQuery for &'__w mut T { assert!( !access.access().has_component_read(component_id), "&mut {} conflicts with a previous access in this query. Mutable component access must be unique.", - std::any::type_name::(), + core::any::type_name::(), ); access.add_component_write(component_id); } @@ -1682,7 +1682,7 @@ unsafe impl<'__w, T: Component> WorldQuery for Mut<'__w, T> { assert!( !access.access().has_component_read(component_id), "Mut<{}> conflicts with a previous access in this query. Mutable component access mut be unique.", - std::any::type_name::(), + core::any::type_name::(), ); access.add_component_write(component_id); } @@ -1905,9 +1905,9 @@ unsafe impl ReadOnlyQueryData for Option {} /// ``` pub struct Has(PhantomData); -impl std::fmt::Debug for Has { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { - write!(f, "Has<{}>", std::any::type_name::()) +impl core::fmt::Debug for Has { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> { + write!(f, "Has<{}>", core::any::type_name::()) } } diff --git a/crates/bevy_ecs/src/query/filter.rs b/crates/bevy_ecs/src/query/filter.rs index 0c0cffb656948..8395d548989ef 100644 --- a/crates/bevy_ecs/src/query/filter.rs +++ b/crates/bevy_ecs/src/query/filter.rs @@ -8,7 +8,7 @@ use crate::{ }; use bevy_ptr::{ThinSlicePtr, UnsafeCellDeref}; use bevy_utils::all_tuples; -use std::{cell::UnsafeCell, marker::PhantomData}; +use core::{cell::UnsafeCell, marker::PhantomData}; /// Types that filter the results of a [`Query`]. /// @@ -478,7 +478,7 @@ macro_rules! impl_or_query_filter { )* // The required components remain the same as the original `access`. - _new_access.required = std::mem::take(&mut access.required); + _new_access.required = core::mem::take(&mut access.required); *access = _new_access; } @@ -724,7 +724,7 @@ unsafe impl WorldQuery for Added { #[inline] fn update_component_access(&id: &ComponentId, access: &mut FilteredAccess) { if access.access().has_component_write(id) { - panic!("$state_name<{}> conflicts with a previous access in this query. Shared access cannot coincide with exclusive access.",std::any::type_name::()); + panic!("$state_name<{}> conflicts with a previous access in this query. Shared access cannot coincide with exclusive access.",core::any::type_name::()); } access.add_component_read(id); } @@ -942,7 +942,7 @@ unsafe impl WorldQuery for Changed { #[inline] fn update_component_access(&id: &ComponentId, access: &mut FilteredAccess) { if access.access().has_component_write(id) { - panic!("$state_name<{}> conflicts with a previous access in this query. Shared access cannot coincide with exclusive access.",std::any::type_name::()); + panic!("$state_name<{}> conflicts with a previous access in this query. Shared access cannot coincide with exclusive access.",core::any::type_name::()); } access.add_component_read(id); } diff --git a/crates/bevy_ecs/src/query/iter.rs b/crates/bevy_ecs/src/query/iter.rs index 836c496796c9a..bf4c5432546f9 100644 --- a/crates/bevy_ecs/src/query/iter.rs +++ b/crates/bevy_ecs/src/query/iter.rs @@ -6,7 +6,7 @@ use crate::{ storage::{Table, TableRow, Tables}, world::unsafe_world_cell::UnsafeWorldCell, }; -use std::{ +use core::{ borrow::Borrow, cmp::Ordering, fmt::{self, Debug, Formatter}, @@ -1705,7 +1705,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter, const K: usize> Debug struct QueryIterationCursor<'w, 's, D: QueryData, F: QueryFilter> { // whether the query iteration is dense or not. Mirrors QueryState's `is_dense` field. is_dense: bool, - storage_id_iter: std::slice::Iter<'s, StorageId>, + storage_id_iter: core::slice::Iter<'s, StorageId>, table_entities: &'w [Entity], archetype_entities: &'w [ArchetypeEntity], fetch: D::Fetch<'w>, @@ -1982,7 +1982,13 @@ impl Ord for NeutralOrd { #[cfg(test)] mod tests { #[allow(unused_imports)] - use crate::{self as bevy_ecs, component::Component, entity::Entity, prelude::World}; + use crate::component::Component; + #[allow(unused_imports)] + use crate::entity::Entity; + #[allow(unused_imports)] + use crate::prelude::World; + #[allow(unused_imports)] + use crate::{self as bevy_ecs}; #[derive(Component, Debug, PartialEq, PartialOrd, Clone, Copy)] struct A(f32); diff --git a/crates/bevy_ecs/src/query/mod.rs b/crates/bevy_ecs/src/query/mod.rs index 13689c6a8c328..0a9f664fb50ba 100644 --- a/crates/bevy_ecs/src/query/mod.rs +++ b/crates/bevy_ecs/src/query/mod.rs @@ -82,7 +82,7 @@ impl DebugCheckedUnwrap for Result { if let Ok(inner) = self { inner } else { - std::hint::unreachable_unchecked() + core::hint::unreachable_unchecked() } } } @@ -96,7 +96,7 @@ impl DebugCheckedUnwrap for Option { if let Some(inner) = self { inner } else { - std::hint::unreachable_unchecked() + core::hint::unreachable_unchecked() } } } @@ -113,7 +113,8 @@ mod tests { world::World, }; use bevy_ecs_macros::{QueryData, QueryFilter}; - use std::{any::type_name, collections::HashSet, fmt::Debug, hash::Hash}; + use core::{any::type_name, fmt::Debug, hash::Hash}; + use std::collections::HashSet; #[derive(Component, Debug, Hash, Eq, PartialEq, Clone, Copy, PartialOrd, Ord)] struct A(usize); diff --git a/crates/bevy_ecs/src/query/state.rs b/crates/bevy_ecs/src/query/state.rs index 1049a41934cc5..69b67368fe4f3 100644 --- a/crates/bevy_ecs/src/query/state.rs +++ b/crates/bevy_ecs/src/query/state.rs @@ -13,8 +13,8 @@ use crate::{ use bevy_utils::tracing::warn; #[cfg(feature = "trace")] use bevy_utils::tracing::Span; +use core::{borrow::Borrow, fmt, mem::MaybeUninit, ptr}; use fixedbitset::FixedBitSet; -use std::{borrow::Borrow, fmt, mem::MaybeUninit, ptr}; use super::{ NopWorldQuery, QueryBuilder, QueryData, QueryEntityError, QueryFilter, QueryManyIter, @@ -217,8 +217,8 @@ impl QueryState { #[cfg(feature = "trace")] par_iter_span: bevy_utils::tracing::info_span!( "par_for_each", - query = std::any::type_name::(), - filter = std::any::type_name::(), + query = core::any::type_name::(), + filter = core::any::type_name::(), ), } } @@ -243,8 +243,8 @@ impl QueryState { #[cfg(feature = "trace")] par_iter_span: bevy_utils::tracing::info_span!( "par_for_each", - data = std::any::type_name::(), - filter = std::any::type_name::(), + data = core::any::type_name::(), + filter = core::any::type_name::(), ), }; state.update_archetypes(builder.world()); @@ -357,7 +357,7 @@ impl QueryState { if self.component_access.required.is_empty() { let archetypes = world.archetypes(); let old_generation = - std::mem::replace(&mut self.archetype_generation, archetypes.generation()); + core::mem::replace(&mut self.archetype_generation, archetypes.generation()); for archetype in &archetypes[old_generation..] { // SAFETY: The validate_world call ensures that the world is the same the QueryState @@ -590,7 +590,7 @@ impl QueryState { assert!( component_access.is_subset(&self.component_access), "Transmuted state for {} attempts to access terms that are not allowed by original state {}.", - std::any::type_name::<(NewD, NewF)>(), std::any::type_name::<(D, F)>() + core::any::type_name::<(NewD, NewF)>(), core::any::type_name::<(D, F)>() ); QueryState { @@ -606,8 +606,8 @@ impl QueryState { #[cfg(feature = "trace")] par_iter_span: bevy_utils::tracing::info_span!( "par_for_each", - query = std::any::type_name::(), - filter = std::any::type_name::(), + query = core::any::type_name::(), + filter = core::any::type_name::(), ), } } @@ -684,7 +684,7 @@ impl QueryState { assert!( component_access.is_subset(&joined_component_access), "Joined state for {} attempts to access terms that are not allowed by state {} joined with {}.", - std::any::type_name::<(NewD, NewF)>(), std::any::type_name::<(D, F)>(), std::any::type_name::<(OtherD, OtherF)>() + core::any::type_name::<(NewD, NewF)>(), core::any::type_name::<(D, F)>(), core::any::type_name::<(OtherD, OtherF)>() ); if self.archetype_generation != other.archetype_generation { @@ -728,8 +728,8 @@ impl QueryState { #[cfg(feature = "trace")] par_iter_span: bevy_utils::tracing::info_span!( "par_for_each", - query = std::any::type_name::(), - filter = std::any::type_name::(), + query = core::any::type_name::(), + filter = core::any::type_name::(), ), } } @@ -1011,7 +1011,7 @@ impl QueryState { ) -> Result<[ROQueryItem<'w, D>; N], QueryEntityError<'w>> { let mut values = [(); N].map(|_| MaybeUninit::uninit()); - for (value, entity) in std::iter::zip(&mut values, entities) { + for (value, entity) in core::iter::zip(&mut values, entities) { // SAFETY: fetch is read-only and world must be validated let item = unsafe { self.as_readonly() @@ -1054,7 +1054,7 @@ impl QueryState { let mut values = [(); N].map(|_| MaybeUninit::uninit()); - for (value, entity) in std::iter::zip(&mut values, entities) { + for (value, entity) in core::iter::zip(&mut values, entities) { let item = self.get_unchecked_manual(world, entity, last_run, this_run)?; *value = MaybeUninit::new(item); } @@ -1511,7 +1511,7 @@ impl QueryState { if queue.is_empty() { return; } - let queue = std::mem::take(queue); + let queue = core::mem::take(queue); let mut func = func.clone(); let init_accum = init_accum.clone(); scope.spawn(async move { @@ -1702,8 +1702,8 @@ impl QueryState { match (first, extra) { (Some(r), false) => Ok(r), - (None, _) => Err(QuerySingleError::NoEntities(std::any::type_name::())), - (Some(_), _) => Err(QuerySingleError::MultipleEntities(std::any::type_name::< + (None, _) => Err(QuerySingleError::NoEntities(core::any::type_name::())), + (Some(_), _) => Err(QuerySingleError::MultipleEntities(core::any::type_name::< Self, >())), } diff --git a/crates/bevy_ecs/src/reflect/bundle.rs b/crates/bevy_ecs/src/reflect/bundle.rs index b594506c7a824..771af49319700 100644 --- a/crates/bevy_ecs/src/reflect/bundle.rs +++ b/crates/bevy_ecs/src/reflect/bundle.rs @@ -4,7 +4,7 @@ //! This module exports two types: [`ReflectBundleFns`] and [`ReflectBundle`]. //! //! Same as [`super::component`], but for bundles. -use std::any::{Any, TypeId}; +use core::any::{Any, TypeId}; use crate::{ prelude::Bundle, @@ -149,7 +149,7 @@ impl FromType for ReflectBundle { _ => panic!( "expected bundle `{}` to be named struct or tuple", // FIXME: once we have unique reflect, use `TypePath`. - std::any::type_name::(), + core::any::type_name::(), ), } } @@ -170,7 +170,7 @@ impl FromType for ReflectBundle { _ => panic!( "expected bundle `{}` to be named struct or tuple", // FIXME: once we have unique reflect, use `TypePath`. - std::any::type_name::(), + core::any::type_name::(), ), } } diff --git a/crates/bevy_ecs/src/reflect/entity_commands.rs b/crates/bevy_ecs/src/reflect/entity_commands.rs index 6d08141aa7647..3979eee22903f 100644 --- a/crates/bevy_ecs/src/reflect/entity_commands.rs +++ b/crates/bevy_ecs/src/reflect/entity_commands.rs @@ -5,8 +5,9 @@ use crate::{ system::{EntityCommands, Resource}, world::{Command, World}, }; +use alloc::borrow::Cow; use bevy_reflect::{PartialReflect, TypeRegistry}; -use std::{borrow::Cow, marker::PhantomData}; +use core::marker::PhantomData; /// An extension trait for [`EntityCommands`] for reflection related functions pub trait ReflectCommandExt { diff --git a/crates/bevy_ecs/src/reflect/mod.rs b/crates/bevy_ecs/src/reflect/mod.rs index c87b7f6ae192b..5508f87af4871 100644 --- a/crates/bevy_ecs/src/reflect/mod.rs +++ b/crates/bevy_ecs/src/reflect/mod.rs @@ -1,6 +1,6 @@ //! Types that enable reflection support. -use std::{ +use core::{ any::TypeId, ops::{Deref, DerefMut}, }; @@ -137,7 +137,7 @@ pub fn from_reflect_with_fallback( `Default` or `FromWorld` traits. Are you perhaps missing a `#[reflect(Default)]` \ or `#[reflect(FromWorld)]`?", // FIXME: once we have unique reflect, use `TypePath`. - std::any::type_name::(), + core::any::type_name::(), ); }; diff --git a/crates/bevy_ecs/src/removal_detection.rs b/crates/bevy_ecs/src/removal_detection.rs index f55af1f5c6c5e..e4ecaad7431a8 100644 --- a/crates/bevy_ecs/src/removal_detection.rs +++ b/crates/bevy_ecs/src/removal_detection.rs @@ -11,7 +11,7 @@ use crate::{ world::{unsafe_world_cell::UnsafeWorldCell, World}, }; -use std::{ +use core::{ fmt::Debug, iter, marker::PhantomData, diff --git a/crates/bevy_ecs/src/schedule/condition.rs b/crates/bevy_ecs/src/schedule/condition.rs index e41fcd7230971..6956d2715069f 100644 --- a/crates/bevy_ecs/src/schedule/condition.rs +++ b/crates/bevy_ecs/src/schedule/condition.rs @@ -1,4 +1,5 @@ -use std::{borrow::Cow, ops::Not}; +use alloc::borrow::Cow; +use core::ops::Not; use crate::system::{ Adapt, AdapterSystem, CombinatorSystem, Combine, IntoSystem, ReadOnlySystem, System, SystemIn, @@ -1064,7 +1065,7 @@ pub mod common_conditions { /// ``` pub fn not(condition: T) -> NotSystem where - TOut: std::ops::Not, + TOut: core::ops::Not, T: IntoSystem<(), TOut, Marker>, { let condition = IntoSystem::into_system(condition); diff --git a/crates/bevy_ecs/src/schedule/executor/mod.rs b/crates/bevy_ecs/src/schedule/executor/mod.rs index 7213ee8d722d3..24113aee2bee0 100644 --- a/crates/bevy_ecs/src/schedule/executor/mod.rs +++ b/crates/bevy_ecs/src/schedule/executor/mod.rs @@ -137,7 +137,7 @@ pub(super) fn is_apply_deferred(system: &BoxedSystem) -> bool { /// This is reliant on undocumented behavior in Rust's default panic handler, which checks the call stack for symbols /// containing the string `__rust_begin_short_backtrace` in their mangled name. mod __rust_begin_short_backtrace { - use std::hint::black_box; + use core::hint::black_box; use crate::{ system::{ReadOnlySystem, System}, diff --git a/crates/bevy_ecs/src/schedule/executor/multi_threaded.rs b/crates/bevy_ecs/src/schedule/executor/multi_threaded.rs index 141573f6f55af..8782793e32f71 100644 --- a/crates/bevy_ecs/src/schedule/executor/multi_threaded.rs +++ b/crates/bevy_ecs/src/schedule/executor/multi_threaded.rs @@ -1,13 +1,14 @@ -use std::{ - any::Any, - sync::{Arc, Mutex, MutexGuard}, -}; +use alloc::sync::Arc; +use core::any::Any; +use std::sync::{Mutex, MutexGuard}; use bevy_tasks::{ComputeTaskPool, Scope, TaskPool, ThreadExecutor}; #[cfg(feature = "trace")] -use bevy_utils::tracing::{info_span, Span}; +use bevy_utils::tracing::info_span; +#[cfg(feature = "trace")] +use bevy_utils::tracing::Span; use bevy_utils::{default, syncunsafecell::SyncUnsafeCell}; -use std::panic::AssertUnwindSafe; +use core::panic::AssertUnwindSafe; use concurrent_queue::ConcurrentQueue; use fixedbitset::FixedBitSet; @@ -381,7 +382,7 @@ impl ExecutorState { } // can't borrow since loop mutably borrows `self` - let mut ready_systems = std::mem::take(&mut self.ready_systems_copy); + let mut ready_systems = core::mem::take(&mut self.ready_systems_copy); // Skipping systems may cause their dependents to become ready immediately. // If that happens, we need to run again immediately or we may fail to spawn those dependents. diff --git a/crates/bevy_ecs/src/schedule/executor/simple.rs b/crates/bevy_ecs/src/schedule/executor/simple.rs index 3a7dd05397342..171125342cd78 100644 --- a/crates/bevy_ecs/src/schedule/executor/simple.rs +++ b/crates/bevy_ecs/src/schedule/executor/simple.rs @@ -1,7 +1,7 @@ #[cfg(feature = "trace")] use bevy_utils::tracing::info_span; +use core::panic::AssertUnwindSafe; use fixedbitset::FixedBitSet; -use std::panic::AssertUnwindSafe; use crate::{ schedule::{ diff --git a/crates/bevy_ecs/src/schedule/executor/single_threaded.rs b/crates/bevy_ecs/src/schedule/executor/single_threaded.rs index 3ae907c4f5f26..93d814d3b2f83 100644 --- a/crates/bevy_ecs/src/schedule/executor/single_threaded.rs +++ b/crates/bevy_ecs/src/schedule/executor/single_threaded.rs @@ -1,7 +1,7 @@ #[cfg(feature = "trace")] use bevy_utils::tracing::info_span; +use core::panic::AssertUnwindSafe; use fixedbitset::FixedBitSet; -use std::panic::AssertUnwindSafe; use crate::{ schedule::{is_apply_deferred, BoxedCondition, ExecutorKind, SystemExecutor, SystemSchedule}, diff --git a/crates/bevy_ecs/src/schedule/graph_utils.rs b/crates/bevy_ecs/src/schedule/graph_utils.rs index 2fcbb6df90f2b..a92579ca58293 100644 --- a/crates/bevy_ecs/src/schedule/graph_utils.rs +++ b/crates/bevy_ecs/src/schedule/graph_utils.rs @@ -1,4 +1,4 @@ -use std::fmt::Debug; +use core::fmt::Debug; use bevy_utils::{HashMap, HashSet}; use fixedbitset::FixedBitSet; diff --git a/crates/bevy_ecs/src/schedule/mod.rs b/crates/bevy_ecs/src/schedule/mod.rs index 6bf8276f81290..73689d57ce57b 100644 --- a/crates/bevy_ecs/src/schedule/mod.rs +++ b/crates/bevy_ecs/src/schedule/mod.rs @@ -17,7 +17,7 @@ pub use self::graph_utils::NodeId; #[cfg(test)] mod tests { use super::*; - use std::sync::atomic::{AtomicU32, Ordering}; + use core::sync::atomic::{AtomicU32, Ordering}; pub use crate as bevy_ecs; pub use crate::{ @@ -96,8 +96,9 @@ mod tests { #[test] #[cfg(not(miri))] fn parallel_execution() { + use alloc::sync::Arc; use bevy_tasks::{ComputeTaskPool, TaskPool}; - use std::sync::{Arc, Barrier}; + use std::sync::Barrier; let mut world = World::default(); let mut schedule = Schedule::default(); @@ -715,7 +716,7 @@ mod tests { } mod system_ambiguity { - use std::collections::BTreeSet; + use alloc::collections::BTreeSet; use super::*; // Required to make the derive macro behave diff --git a/crates/bevy_ecs/src/schedule/schedule.rs b/crates/bevy_ecs/src/schedule/schedule.rs index 3cb6d6ea02746..65e62b0b9eb1b 100644 --- a/crates/bevy_ecs/src/schedule/schedule.rs +++ b/crates/bevy_ecs/src/schedule/schedule.rs @@ -1,7 +1,5 @@ -use std::{ - collections::BTreeSet, - fmt::{Debug, Write}, -}; +use alloc::collections::BTreeSet; +use core::fmt::{Debug, Write}; #[cfg(feature = "trace")] use bevy_utils::tracing::info_span; @@ -1525,13 +1523,13 @@ impl ScheduleGraph { // move systems into new schedule for &id in &schedule.system_ids { let system = self.systems[id.index()].inner.take().unwrap(); - let conditions = std::mem::take(&mut self.system_conditions[id.index()]); + let conditions = core::mem::take(&mut self.system_conditions[id.index()]); schedule.systems.push(system); schedule.system_conditions.push(conditions); } for &id in &schedule.set_ids { - let conditions = std::mem::take(&mut self.system_set_conditions[id.index()]); + let conditions = core::mem::take(&mut self.system_set_conditions[id.index()]); schedule.set_conditions.push(conditions); } @@ -1743,7 +1741,7 @@ impl ScheduleGraph { ) .unwrap(); writeln!(message, "set `{first_name}`").unwrap(); - for name in names.chain(std::iter::once(first_name)) { + for name in names.chain(core::iter::once(first_name)) { writeln!(message, " ... which contains set `{name}`").unwrap(); } writeln!(message).unwrap(); @@ -1767,7 +1765,7 @@ impl ScheduleGraph { ) .unwrap(); writeln!(message, "{first_kind} `{first_name}`").unwrap(); - for (kind, name) in names.chain(std::iter::once((first_kind, first_name))) { + for (kind, name) in names.chain(core::iter::once((first_kind, first_name))) { writeln!(message, " ... which must run before {kind} `{name}`").unwrap(); } writeln!(message).unwrap(); @@ -1881,7 +1879,7 @@ impl ScheduleGraph { writeln!(message, " conflict on: {conflicts:?}").unwrap(); } else { // one or both systems must be exclusive - let world = std::any::type_name::(); + let world = core::any::type_name::(); writeln!(message, " conflict on: {world}").unwrap(); } } diff --git a/crates/bevy_ecs/src/schedule/set.rs b/crates/bevy_ecs/src/schedule/set.rs index 0a408551d2293..244dd436351ec 100644 --- a/crates/bevy_ecs/src/schedule/set.rs +++ b/crates/bevy_ecs/src/schedule/set.rs @@ -1,4 +1,4 @@ -use std::{ +use core::{ any::TypeId, fmt::Debug, hash::{Hash, Hasher}, @@ -69,9 +69,9 @@ impl SystemTypeSet { } impl Debug for SystemTypeSet { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { f.debug_tuple("SystemTypeSet") - .field(&format_args!("fn {}()", &std::any::type_name::())) + .field(&format_args!("fn {}()", &core::any::type_name::())) .finish() } } diff --git a/crates/bevy_ecs/src/schedule/stepping.rs b/crates/bevy_ecs/src/schedule/stepping.rs index 878ec01317153..622ec6ea03e45 100644 --- a/crates/bevy_ecs/src/schedule/stepping.rs +++ b/crates/bevy_ecs/src/schedule/stepping.rs @@ -1,5 +1,6 @@ +use core::any::TypeId; use fixedbitset::FixedBitSet; -use std::{any::TypeId, collections::HashMap}; +use std::collections::HashMap; use crate::{ schedule::{InternedScheduleLabel, NodeId, Schedule, ScheduleLabel}, @@ -112,8 +113,8 @@ pub struct Stepping { updates: Vec, } -impl std::fmt::Debug for Stepping { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl core::fmt::Debug for Stepping { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { write!( f, "Stepping {{ action: {:?}, schedules: {:?}, order: {:?}", @@ -690,7 +691,7 @@ impl ScheduleState { start: usize, mut action: Action, ) -> (FixedBitSet, Option) { - use std::cmp::Ordering; + use core::cmp::Ordering; // if our NodeId list hasn't been populated, copy it over from the // schedule @@ -866,7 +867,7 @@ mod tests { let systems: &Vec<&str> = $system_names; if (actual != expected) { - use std::fmt::Write as _; + use core::fmt::Write as _; // mismatch, let's construct a human-readable message of what // was returned @@ -898,7 +899,7 @@ mod tests { ($schedule:expr, $skipped_systems:expr, $($system:expr),*) => { // pull an ordered list of systems in the schedule, and save the // system TypeId, and name. - let systems: Vec<(TypeId, std::borrow::Cow<'static, str>)> = $schedule.systems().unwrap() + let systems: Vec<(TypeId, alloc::borrow::Cow<'static, str>)> = $schedule.systems().unwrap() .map(|(_, system)| { (system.type_id(), system.name()) }) diff --git a/crates/bevy_ecs/src/storage/blob_array.rs b/crates/bevy_ecs/src/storage/blob_array.rs index 9970d82e75ea5..e6aefdb4b7dd4 100644 --- a/crates/bevy_ecs/src/storage/blob_array.rs +++ b/crates/bevy_ecs/src/storage/blob_array.rs @@ -1,13 +1,9 @@ use super::blob_vec::array_layout; use crate::storage::blob_vec::array_layout_unchecked; +use alloc::alloc::handle_alloc_error; use bevy_ptr::{OwningPtr, Ptr, PtrMut}; use bevy_utils::OnDrop; -use std::{ - alloc::{handle_alloc_error, Layout}, - cell::UnsafeCell, - num::NonZeroUsize, - ptr::NonNull, -}; +use core::{alloc::Layout, cell::UnsafeCell, num::NonZeroUsize, ptr::NonNull}; /// A flat, type-erased data storage type similar to a [`BlobVec`](super::blob_vec::BlobVec), but with the length and capacity cut out /// for performance reasons. This type is reliant on its owning type to store the capacity and length information. @@ -38,7 +34,7 @@ impl BlobArray { /// `drop` should be safe to call with an [`OwningPtr`] pointing to any item that's been placed into this [`BlobArray`]. /// If `drop` is `None`, the items will be leaked. This should generally be set as None based on [`needs_drop`]. /// - /// [`needs_drop`]: core::mem::needs_drop + /// [`needs_drop`]: std::mem::needs_drop pub unsafe fn with_capacity( item_layout: Layout, drop_fn: Option)>, @@ -142,7 +138,9 @@ impl BlobArray { #[cfg(debug_assertions)] debug_assert!(slice_len <= self.capacity); // SAFETY: the inner data will remain valid for as long as 'self. - unsafe { std::slice::from_raw_parts(self.data.as_ptr() as *const UnsafeCell, slice_len) } + unsafe { + core::slice::from_raw_parts(self.data.as_ptr() as *const UnsafeCell, slice_len) + } } /// Clears the array, i.e. removing (and dropping) all of the elements. @@ -189,7 +187,7 @@ impl BlobArray { if !self.is_zst() { let layout = array_layout(&self.item_layout, cap).expect("array layout should be valid"); - std::alloc::dealloc(self.data.as_ptr().cast(), layout); + alloc::alloc::dealloc(self.data.as_ptr().cast(), layout); } #[cfg(debug_assertions)] { @@ -228,7 +226,7 @@ impl BlobArray { let new_layout = array_layout(&self.item_layout, capacity.get()) .expect("array layout should be valid"); // SAFETY: layout has non-zero size because capacity > 0, and the blob isn't ZST (`self.is_zst` == false) - let new_data = unsafe { std::alloc::alloc(new_layout) }; + let new_data = unsafe { alloc::alloc::alloc(new_layout) }; self.data = NonNull::new(new_data).unwrap_or_else(|| handle_alloc_error(new_layout)); } #[cfg(debug_assertions)] @@ -263,7 +261,7 @@ impl BlobArray { // since the item size is always a multiple of its align, the rounding cannot happen // here and the overflow is handled in `array_layout` let new_data = unsafe { - std::alloc::realloc( + alloc::alloc::realloc( self.get_ptr_mut().as_ptr(), // SAFETY: This is the Layout of the current array, it must be valid, if it hadn't have been, there would have been a panic on a previous allocation array_layout_unchecked(&self.item_layout, current_capacity.get()), @@ -291,7 +289,7 @@ impl BlobArray { debug_assert!(self.capacity > index); let size = self.item_layout.size(); let dst = self.get_unchecked_mut(index); - std::ptr::copy::(value.as_ptr(), dst.as_ptr(), size); + core::ptr::copy::(value.as_ptr(), dst.as_ptr(), size); } /// Replaces the value at `index` with `value`. This function does not do any bounds checking. @@ -345,7 +343,7 @@ impl BlobArray { // - `source` and `destination` were obtained from different memory locations, // both of which we have exclusive access to, so they are guaranteed not to overlap. unsafe { - std::ptr::copy_nonoverlapping::( + core::ptr::copy_nonoverlapping::( source, destination.as_ptr(), self.item_layout.size(), @@ -405,7 +403,7 @@ impl BlobArray { debug_assert_ne!(index_to_keep, index_to_remove); } debug_assert_ne!(index_to_keep, index_to_remove); - std::ptr::swap_nonoverlapping::( + core::ptr::swap_nonoverlapping::( self.get_unchecked_mut(index_to_keep).as_ptr(), self.get_unchecked_mut(index_to_remove).as_ptr(), self.item_layout.size(), diff --git a/crates/bevy_ecs/src/storage/blob_vec.rs b/crates/bevy_ecs/src/storage/blob_vec.rs index 9d268944e956b..d42c63a6f1605 100644 --- a/crates/bevy_ecs/src/storage/blob_vec.rs +++ b/crates/bevy_ecs/src/storage/blob_vec.rs @@ -1,11 +1,7 @@ +use alloc::alloc::handle_alloc_error; use bevy_ptr::{OwningPtr, Ptr, PtrMut}; use bevy_utils::OnDrop; -use std::{ - alloc::{handle_alloc_error, Layout}, - cell::UnsafeCell, - num::NonZero, - ptr::NonNull, -}; +use core::{alloc::Layout, cell::UnsafeCell, num::NonZero, ptr::NonNull}; /// A flat, type-erased data storage type /// @@ -24,8 +20,8 @@ pub(super) struct BlobVec { } // We want to ignore the `drop` field in our `Debug` impl -impl std::fmt::Debug for BlobVec { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl core::fmt::Debug for BlobVec { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { f.debug_struct("BlobVec") .field("item_layout", &self.item_layout) .field("capacity", &self.capacity) @@ -49,7 +45,7 @@ impl BlobVec { /// /// If `drop` is `None`, the items will be leaked. This should generally be set as None based on [`needs_drop`]. /// - /// [`needs_drop`]: core::mem::needs_drop + /// [`needs_drop`]: std::mem::needs_drop pub unsafe fn new( item_layout: Layout, drop: Option)>, @@ -152,7 +148,7 @@ impl BlobVec { let new_data = if self.capacity == 0 { // SAFETY: // - layout has non-zero size as per safety requirement - unsafe { std::alloc::alloc(new_layout) } + unsafe { alloc::alloc::alloc(new_layout) } } else { // SAFETY: // - ptr was be allocated via this allocator @@ -162,7 +158,7 @@ impl BlobVec { // since the item size is always a multiple of its alignment, the rounding cannot happen // here and the overflow is handled in `array_layout` unsafe { - std::alloc::realloc( + alloc::alloc::realloc( self.get_ptr_mut().as_ptr(), array_layout(&self.item_layout, self.capacity) .expect("array layout should be valid"), @@ -185,7 +181,7 @@ impl BlobVec { pub unsafe fn initialize_unchecked(&mut self, index: usize, value: OwningPtr<'_>) { debug_assert!(index < self.len()); let ptr = self.get_unchecked_mut(index); - std::ptr::copy_nonoverlapping::(value.as_ptr(), ptr.as_ptr(), self.item_layout.size()); + core::ptr::copy_nonoverlapping::(value.as_ptr(), ptr.as_ptr(), self.item_layout.size()); } /// Replaces the value at `index` with `value`. This function does not do any bounds checking. @@ -244,7 +240,7 @@ impl BlobVec { // - `source` and `destination` were obtained from different memory locations, // both of which we have exclusive access to, so they are guaranteed not to overlap. unsafe { - std::ptr::copy_nonoverlapping::( + core::ptr::copy_nonoverlapping::( source, destination.as_ptr(), self.item_layout.size(), @@ -278,7 +274,7 @@ impl BlobVec { let new_len = self.len - 1; let size = self.item_layout.size(); if index != new_len { - std::ptr::swap_nonoverlapping::( + core::ptr::swap_nonoverlapping::( self.get_unchecked_mut(index).as_ptr(), self.get_unchecked_mut(new_len).as_ptr(), size, @@ -367,7 +363,7 @@ impl BlobVec { /// The type `T` must be the type of the items in this [`BlobVec`]. pub unsafe fn get_slice(&self) -> &[UnsafeCell] { // SAFETY: the inner data will remain valid for as long as 'self. - unsafe { std::slice::from_raw_parts(self.data.as_ptr() as *const UnsafeCell, self.len) } + unsafe { core::slice::from_raw_parts(self.data.as_ptr() as *const UnsafeCell, self.len) } } /// Clears the vector, removing (and dropping) all values. @@ -405,7 +401,7 @@ impl Drop for BlobVec { if array_layout.size() > 0 { // SAFETY: data ptr layout is correct, swap_scratch ptr layout is correct unsafe { - std::alloc::dealloc(self.get_ptr_mut().as_ptr(), array_layout); + alloc::alloc::dealloc(self.get_ptr_mut().as_ptr(), array_layout); } } } @@ -505,7 +501,8 @@ mod tests { use crate::{component::Component, ptr::OwningPtr, world::World}; use super::BlobVec; - use std::{alloc::Layout, cell::RefCell, rc::Rc}; + use alloc::rc::Rc; + use core::{alloc::Layout, cell::RefCell}; /// # Safety /// @@ -708,7 +705,7 @@ mod tests { for zst in q.iter(&world) { // Ensure that the references returned are properly aligned. assert_eq!( - std::ptr::from_ref::(zst) as usize % align_of::(), + core::ptr::from_ref::(zst) as usize % align_of::(), 0 ); count += 1; diff --git a/crates/bevy_ecs/src/storage/resource.rs b/crates/bevy_ecs/src/storage/resource.rs index edbcf325f049f..ed8700e1c74e2 100644 --- a/crates/bevy_ecs/src/storage/resource.rs +++ b/crates/bevy_ecs/src/storage/resource.rs @@ -6,8 +6,9 @@ use crate::{ }; use bevy_ptr::{OwningPtr, Ptr, UnsafeCellDeref}; #[cfg(feature = "track_change_detection")] -use std::panic::Location; -use std::{cell::UnsafeCell, mem::ManuallyDrop, thread::ThreadId}; +use core::panic::Location; +use core::{cell::UnsafeCell, mem::ManuallyDrop}; +use std::thread::ThreadId; /// The type-erased backing storage and metadata for a single resource within a [`World`]. /// diff --git a/crates/bevy_ecs/src/storage/sparse_set.rs b/crates/bevy_ecs/src/storage/sparse_set.rs index 6a7b2460a2b4d..ff740d755b20f 100644 --- a/crates/bevy_ecs/src/storage/sparse_set.rs +++ b/crates/bevy_ecs/src/storage/sparse_set.rs @@ -5,10 +5,10 @@ use crate::{ storage::{Column, TableRow}, }; use bevy_ptr::{OwningPtr, Ptr}; -use nonmax::NonMaxUsize; #[cfg(feature = "track_change_detection")] -use std::panic::Location; -use std::{cell::UnsafeCell, hash::Hash, marker::PhantomData}; +use core::panic::Location; +use core::{cell::UnsafeCell, hash::Hash, marker::PhantomData}; +use nonmax::NonMaxUsize; type EntityIndex = u32; diff --git a/crates/bevy_ecs/src/storage/table/column.rs b/crates/bevy_ecs/src/storage/table/column.rs index 81535b6d48876..e2c16613b476f 100644 --- a/crates/bevy_ecs/src/storage/table/column.rs +++ b/crates/bevy_ecs/src/storage/table/column.rs @@ -282,10 +282,10 @@ impl ThinColumn { /// - `last_element_index` is indeed the index of the last element /// - the data stored in `last_element_index` will never be used unless properly initialized again. pub(crate) unsafe fn drop_last_component(&mut self, last_element_index: usize) { - std::ptr::drop_in_place(self.added_ticks.get_unchecked_raw(last_element_index)); - std::ptr::drop_in_place(self.changed_ticks.get_unchecked_raw(last_element_index)); + core::ptr::drop_in_place(self.added_ticks.get_unchecked_raw(last_element_index)); + core::ptr::drop_in_place(self.changed_ticks.get_unchecked_raw(last_element_index)); #[cfg(feature = "track_change_detection")] - std::ptr::drop_in_place(self.changed_by.get_unchecked_raw(last_element_index)); + core::ptr::drop_in_place(self.changed_by.get_unchecked_raw(last_element_index)); self.data.drop_last_element(last_element_index); } diff --git a/crates/bevy_ecs/src/storage/table/mod.rs b/crates/bevy_ecs/src/storage/table/mod.rs index a255d1ff71c06..cabcbdc3782c4 100644 --- a/crates/bevy_ecs/src/storage/table/mod.rs +++ b/crates/bevy_ecs/src/storage/table/mod.rs @@ -9,8 +9,8 @@ use bevy_ptr::{OwningPtr, Ptr, UnsafeCellDeref}; use bevy_utils::HashMap; pub use column::*; #[cfg(feature = "track_change_detection")] -use std::panic::Location; -use std::{ +use core::panic::Location; +use core::{ alloc::Layout, cell::UnsafeCell, num::NonZeroUsize, @@ -764,7 +764,7 @@ impl Tables { } /// Iterates through all of the tables stored within in [`TableId`] order. - pub fn iter(&self) -> std::slice::Iter<'_, Table> { + pub fn iter(&self) -> core::slice::Iter<'_, Table> { self.tables.iter() } @@ -822,7 +822,7 @@ mod tests { storage::{Storages, TableBuilder, TableRow}, }; #[cfg(feature = "track_change_detection")] - use std::panic::Location; + use core::panic::Location; #[derive(Component)] struct W(T); diff --git a/crates/bevy_ecs/src/storage/thin_array_ptr.rs b/crates/bevy_ecs/src/storage/thin_array_ptr.rs index 888cd65b5b640..a4d25265e0066 100644 --- a/crates/bevy_ecs/src/storage/thin_array_ptr.rs +++ b/crates/bevy_ecs/src/storage/thin_array_ptr.rs @@ -1,6 +1,7 @@ use crate::query::DebugCheckedUnwrap; -use std::{ - alloc::{alloc, handle_alloc_error, realloc, Layout}, +use alloc::alloc::{alloc, handle_alloc_error, realloc}; +use core::{ + alloc::Layout, mem::{needs_drop, size_of}, num::NonZeroUsize, ptr::{self, NonNull}, @@ -281,7 +282,7 @@ impl ThinArrayPtr { if current_capacity != 0 { self.clear_elements(current_len); let layout = Layout::array::(current_capacity).expect("layout should be valid"); - std::alloc::dealloc(self.data.as_ptr().cast(), layout); + alloc::alloc::dealloc(self.data.as_ptr().cast(), layout); } self.set_capacity(0); } @@ -296,7 +297,7 @@ impl ThinArrayPtr { // - the data is valid - allocated with the same allocater // - non-null and well-aligned // - we have a shared reference to self - the data will not be mutated during 'a - unsafe { std::slice::from_raw_parts(self.data.as_ptr(), slice_len) } + unsafe { core::slice::from_raw_parts(self.data.as_ptr(), slice_len) } } } diff --git a/crates/bevy_ecs/src/system/adapter_system.rs b/crates/bevy_ecs/src/system/adapter_system.rs index 8c4badd995e68..8c25e57bbd91e 100644 --- a/crates/bevy_ecs/src/system/adapter_system.rs +++ b/crates/bevy_ecs/src/system/adapter_system.rs @@ -1,4 +1,4 @@ -use std::borrow::Cow; +use alloc::borrow::Cow; use super::{IntoSystem, ReadOnlySystem, System}; use crate::{ diff --git a/crates/bevy_ecs/src/system/builder.rs b/crates/bevy_ecs/src/system/builder.rs index 51b587512c7f8..279cc41381af5 100644 --- a/crates/bevy_ecs/src/system/builder.rs +++ b/crates/bevy_ecs/src/system/builder.rs @@ -9,7 +9,7 @@ use crate::{ }, world::{FromWorld, World}, }; -use std::fmt::Debug; +use core::fmt::Debug; use super::{init_query_param, Res, ResMut, Resource, SystemState}; diff --git a/crates/bevy_ecs/src/system/combinator.rs b/crates/bevy_ecs/src/system/combinator.rs index f7bc133129bf3..ce4c8785feb05 100644 --- a/crates/bevy_ecs/src/system/combinator.rs +++ b/crates/bevy_ecs/src/system/combinator.rs @@ -1,4 +1,5 @@ -use std::{borrow::Cow, marker::PhantomData}; +use alloc::borrow::Cow; +use core::marker::PhantomData; use crate::{ archetype::ArchetypeComponentId, diff --git a/crates/bevy_ecs/src/system/commands/mod.rs b/crates/bevy_ecs/src/system/commands/mod.rs index 07be635ec6184..1476f32db1972 100644 --- a/crates/bevy_ecs/src/system/commands/mod.rs +++ b/crates/bevy_ecs/src/system/commands/mod.rs @@ -1,7 +1,6 @@ mod parallel_scope; -use core::panic::Location; -use std::marker::PhantomData; +use core::{marker::PhantomData, panic::Location}; use super::{ Deferred, IntoObserverSystem, IntoSystem, RegisterSystem, Resource, RunSystemCachedWith, @@ -1152,7 +1151,7 @@ impl EntityCommands<'_> { let caller = Location::caller(); // SAFETY: same invariants as parent call self.queue(unsafe {insert_by_id(component_id, value, move |entity| { - panic!("error[B0003]: {caller}: Could not insert a component {component_id:?} (with type {}) for entity {entity:?} because it doesn't exist in this World. See: https://bevyengine.org/learn/errors/b0003", std::any::type_name::()); + panic!("error[B0003]: {caller}: Could not insert a component {component_id:?} (with type {}) for entity {entity:?} because it doesn't exist in this World. See: https://bevyengine.org/learn/errors/b0003", core::any::type_name::()); })}) } @@ -1677,7 +1676,7 @@ where ) { error!( "Failed to 'insert or spawn' bundle of type {} into the following invalid entities: {:?}", - std::any::type_name::(), + core::any::type_name::(), invalid_entities ); } @@ -1712,7 +1711,7 @@ fn insert(bundle: T, mode: InsertMode) -> impl EntityCommand { caller, ); } else { - panic!("error[B0003]: {caller}: Could not insert a bundle (of type `{}`) for entity {:?} because it doesn't exist in this World. See: https://bevyengine.org/learn/errors/b0003", std::any::type_name::(), entity); + panic!("error[B0003]: {caller}: Could not insert a bundle (of type `{}`) for entity {:?} because it doesn't exist in this World. See: https://bevyengine.org/learn/errors/b0003", core::any::type_name::(), entity); } } } @@ -1731,7 +1730,7 @@ fn insert_from_world(mode: InsertMode) -> impl EntityC caller, ); } else { - panic!("error[B0003]: {caller}: Could not insert a bundle (of type `{}`) for entity {:?} because it doesn't exist in this World. See: https://bevyengine.org/learn/errors/b0003", std::any::type_name::(), entity); + panic!("error[B0003]: {caller}: Could not insert a bundle (of type `{}`) for entity {:?} because it doesn't exist in this World. See: https://bevyengine.org/learn/errors/b0003", core::any::type_name::(), entity); } } } @@ -1875,12 +1874,10 @@ mod tests { system::{Commands, Resource}, world::{CommandQueue, FromWorld, World}, }; - use std::{ + use alloc::sync::Arc; + use core::{ any::TypeId, - sync::{ - atomic::{AtomicUsize, Ordering}, - Arc, - }, + sync::atomic::{AtomicUsize, Ordering}, }; #[allow(dead_code)] diff --git a/crates/bevy_ecs/src/system/exclusive_function_system.rs b/crates/bevy_ecs/src/system/exclusive_function_system.rs index 9019a920a2e67..3075f3c55772e 100644 --- a/crates/bevy_ecs/src/system/exclusive_function_system.rs +++ b/crates/bevy_ecs/src/system/exclusive_function_system.rs @@ -10,8 +10,9 @@ use crate::{ world::{unsafe_world_cell::UnsafeWorldCell, World}, }; +use alloc::borrow::Cow; use bevy_utils::all_tuples; -use std::{borrow::Cow, marker::PhantomData}; +use core::marker::PhantomData; /// A function system that runs with exclusive [`World`] access. /// @@ -298,7 +299,7 @@ mod tests { { fn reference_system(_world: &mut World) {} - use std::any::TypeId; + use core::any::TypeId; let system = IntoSystem::into_system(function); diff --git a/crates/bevy_ecs/src/system/exclusive_system_param.rs b/crates/bevy_ecs/src/system/exclusive_system_param.rs index 786fd1311dfb2..9d3279e3e053a 100644 --- a/crates/bevy_ecs/src/system/exclusive_system_param.rs +++ b/crates/bevy_ecs/src/system/exclusive_system_param.rs @@ -5,7 +5,7 @@ use crate::{ world::World, }; use bevy_utils::{all_tuples, synccell::SyncCell}; -use std::marker::PhantomData; +use core::marker::PhantomData; /// A parameter that can be used in an exclusive system (a system with an `&mut World` parameter). /// Any parameters implementing this trait must come after the `&mut World` parameter. @@ -126,7 +126,7 @@ mod tests { use crate as bevy_ecs; use crate::{schedule::Schedule, system::Local, world::World}; use bevy_ecs_macros::Resource; - use std::marker::PhantomData; + use core::marker::PhantomData; #[test] fn test_exclusive_system_params() { diff --git a/crates/bevy_ecs/src/system/function_system.rs b/crates/bevy_ecs/src/system/function_system.rs index 54b54bfd56217..0614d7339ca4b 100644 --- a/crates/bevy_ecs/src/system/function_system.rs +++ b/crates/bevy_ecs/src/system/function_system.rs @@ -11,8 +11,9 @@ use crate::{ world::{unsafe_world_cell::UnsafeWorldCell, DeferredWorld, World, WorldId}, }; +use alloc::borrow::Cow; use bevy_utils::all_tuples; -use std::{borrow::Cow, marker::PhantomData}; +use core::marker::PhantomData; #[cfg(feature = "trace")] use bevy_utils::tracing::{info_span, Span}; @@ -50,7 +51,7 @@ pub struct SystemMeta { impl SystemMeta { pub(crate) fn new() -> Self { - let name = std::any::type_name::(); + let name = core::any::type_name::(); Self { name: name.into(), archetype_component_access: Access::default(), @@ -405,7 +406,7 @@ impl SystemState { let archetypes = world.archetypes(); let old_generation = - std::mem::replace(&mut self.archetype_generation, archetypes.generation()); + core::mem::replace(&mut self.archetype_generation, archetypes.generation()); for archetype in &archetypes[old_generation..] { // SAFETY: The assertion above ensures that the param_state was initialized from `world`. @@ -680,7 +681,7 @@ where assert_eq!(self.world_id, Some(world.id()), "Encountered a mismatched World. A System cannot be used with Worlds other than the one it was initialized with."); let archetypes = world.archetypes(); let old_generation = - std::mem::replace(&mut self.archetype_generation, archetypes.generation()); + core::mem::replace(&mut self.archetype_generation, archetypes.generation()); for archetype in &archetypes[old_generation..] { let param_state = self.param_state.as_mut().unwrap(); @@ -884,7 +885,7 @@ mod tests { { fn reference_system() {} - use std::any::TypeId; + use core::any::TypeId; let system = IntoSystem::into_system(function); diff --git a/crates/bevy_ecs/src/system/input.rs b/crates/bevy_ecs/src/system/input.rs index 26bf5af368ffd..57032f71928ef 100644 --- a/crates/bevy_ecs/src/system/input.rs +++ b/crates/bevy_ecs/src/system/input.rs @@ -1,4 +1,4 @@ -use std::ops::{Deref, DerefMut}; +use core::ops::{Deref, DerefMut}; use crate::{bundle::Bundle, prelude::Trigger, system::System}; diff --git a/crates/bevy_ecs/src/system/mod.rs b/crates/bevy_ecs/src/system/mod.rs index 0da0a8c49de90..f557b273f457b 100644 --- a/crates/bevy_ecs/src/system/mod.rs +++ b/crates/bevy_ecs/src/system/mod.rs @@ -117,7 +117,7 @@ mod system_name; mod system_param; mod system_registry; -use std::any::TypeId; +use core::any::TypeId; pub use adapter_system::*; pub use builder::*; @@ -300,7 +300,7 @@ pub fn assert_system_does_not_conflict); + struct NotSend1(alloc::rc::Rc); #[allow(dead_code)] - struct NotSend2(std::rc::Rc); - world.insert_non_send_resource(NotSend1(std::rc::Rc::new(0))); + struct NotSend2(alloc::rc::Rc); + world.insert_non_send_resource(NotSend1(alloc::rc::Rc::new(0))); fn sys( op: Option>, @@ -905,12 +905,12 @@ mod tests { world.insert_resource(SystemRan::No); #[allow(dead_code)] - struct NotSend1(std::rc::Rc); + struct NotSend1(alloc::rc::Rc); #[allow(dead_code)] - struct NotSend2(std::rc::Rc); + struct NotSend2(alloc::rc::Rc); - world.insert_non_send_resource(NotSend1(std::rc::Rc::new(1))); - world.insert_non_send_resource(NotSend2(std::rc::Rc::new(2))); + world.insert_non_send_resource(NotSend1(alloc::rc::Rc::new(1))); + world.insert_non_send_resource(NotSend2(alloc::rc::Rc::new(2))); fn sys( _op: NonSend, @@ -1593,7 +1593,7 @@ mod tests { #[test] fn assert_systems() { - use std::str::FromStr; + use core::str::FromStr; use crate::{prelude::*, system::assert_is_system}; diff --git a/crates/bevy_ecs/src/system/query.rs b/crates/bevy_ecs/src/system/query.rs index ddff01e19fa11..83681ae5b686f 100644 --- a/crates/bevy_ecs/src/system/query.rs +++ b/crates/bevy_ecs/src/system/query.rs @@ -8,7 +8,7 @@ use crate::{ }, world::unsafe_world_cell::UnsafeWorldCell, }; -use std::borrow::Borrow; +use core::borrow::Borrow; /// [System parameter] that provides selective access to the [`Component`] data stored in a [`World`]. /// @@ -354,8 +354,8 @@ pub struct Query<'world, 'state, D: QueryData, F: QueryFilter = ()> { this_run: Tick, } -impl std::fmt::Debug for Query<'_, '_, D, F> { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { +impl core::fmt::Debug for Query<'_, '_, D, F> { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { f.debug_struct("Query") .field("matched_entities", &self.iter().count()) .field("state", &self.state) diff --git a/crates/bevy_ecs/src/system/system.rs b/crates/bevy_ecs/src/system/system.rs index 8f7a800b91475..63ef1a16c3d17 100644 --- a/crates/bevy_ecs/src/system/system.rs +++ b/crates/bevy_ecs/src/system/system.rs @@ -10,7 +10,8 @@ use crate::{ world::{unsafe_world_cell::UnsafeWorldCell, DeferredWorld, World}, }; -use std::{any::TypeId, borrow::Cow}; +use alloc::borrow::Cow; +use core::any::TypeId; use super::IntoSystem; @@ -206,7 +207,7 @@ where In: SystemInput + 'static, Out: 'static, { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { f.debug_struct("System") .field("name", &self.name()) .field("is_exclusive", &self.is_exclusive()) diff --git a/crates/bevy_ecs/src/system/system_name.rs b/crates/bevy_ecs/src/system/system_name.rs index 584cc3e4a1db6..4759f8cb5ca65 100644 --- a/crates/bevy_ecs/src/system/system_name.rs +++ b/crates/bevy_ecs/src/system/system_name.rs @@ -4,7 +4,8 @@ use crate::{ system::{ExclusiveSystemParam, ReadOnlySystemParam, SystemMeta, SystemParam}, world::unsafe_world_cell::UnsafeWorldCell, }; -use std::{borrow::Cow, ops::Deref}; +use alloc::borrow::Cow; +use core::ops::Deref; /// [`SystemParam`] that returns the name of the system which it is used in. /// @@ -61,10 +62,10 @@ impl<'s> From> for &'s str { } } -impl<'s> std::fmt::Display for SystemName<'s> { +impl<'s> core::fmt::Display for SystemName<'s> { #[inline(always)] - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - std::fmt::Display::fmt(&self.name(), f) + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + core::fmt::Display::fmt(&self.name(), f) } } diff --git a/crates/bevy_ecs/src/system/system_param.rs b/crates/bevy_ecs/src/system/system_param.rs index cb2730b3382fc..ba959bb86aca7 100644 --- a/crates/bevy_ecs/src/system/system_param.rs +++ b/crates/bevy_ecs/src/system/system_param.rs @@ -18,8 +18,8 @@ pub use bevy_ecs_macros::{Resource, SystemParam}; use bevy_ptr::UnsafeCellDeref; use bevy_utils::{all_tuples, synccell::SyncCell}; #[cfg(feature = "track_change_detection")] -use std::panic::Location; -use std::{ +use core::panic::Location; +use core::{ any::Any, fmt::Debug, marker::PhantomData, @@ -315,8 +315,8 @@ pub(crate) fn init_query_param ) { assert_component_access_compatibility( &system_meta.name, - std::any::type_name::(), - std::any::type_name::(), + core::any::type_name::(), + core::any::type_name::(), &system_meta.component_access_set, &state.component_access, world, @@ -598,7 +598,7 @@ unsafe impl<'a, T: Resource> SystemParam for Res<'a, T> { assert!( !combined_access.has_resource_write(component_id), "error[B0002]: Res<{}> in system {} conflicts with a previous ResMut<{0}> access. Consider removing the duplicate access. See: https://bevyengine.org/learn/errors/b0002", - std::any::type_name::(), + core::any::type_name::(), system_meta.name, ); system_meta @@ -639,7 +639,7 @@ unsafe impl<'a, T: Resource> SystemParam for Res<'a, T> { panic!( "Resource requested by {} does not exist: {}", system_meta.name, - std::any::type_name::() + core::any::type_name::() ) }); Res { @@ -705,11 +705,11 @@ unsafe impl<'a, T: Resource> SystemParam for ResMut<'a, T> { if combined_access.has_resource_write(component_id) { panic!( "error[B0002]: ResMut<{}> in system {} conflicts with a previous ResMut<{0}> access. Consider removing the duplicate access. See: https://bevyengine.org/learn/errors/b0002", - std::any::type_name::(), system_meta.name); + core::any::type_name::(), system_meta.name); } else if combined_access.has_resource_read(component_id) { panic!( "error[B0002]: ResMut<{}> in system {} conflicts with a previous Res<{0}> access. Consider removing the duplicate access. See: https://bevyengine.org/learn/errors/b0002", - std::any::type_name::(), system_meta.name); + core::any::type_name::(), system_meta.name); } system_meta .component_access_set @@ -748,7 +748,7 @@ unsafe impl<'a, T: Resource> SystemParam for ResMut<'a, T> { panic!( "Resource requested by {} does not exist: {}", system_meta.name, - std::any::type_name::() + core::any::type_name::() ) }); ResMut { @@ -1193,7 +1193,7 @@ impl<'w, T> Debug for NonSend<'w, T> where T: Debug, { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { f.debug_tuple("NonSend").field(&self.value).finish() } } @@ -1255,7 +1255,7 @@ unsafe impl<'a, T: 'static> SystemParam for NonSend<'a, T> { assert!( !combined_access.has_resource_write(component_id), "error[B0002]: NonSend<{}> in system {} conflicts with a previous mutable resource access ({0}). Consider removing the duplicate access. See: https://bevyengine.org/learn/errors/b0002", - std::any::type_name::(), + core::any::type_name::(), system_meta.name, ); system_meta @@ -1296,7 +1296,7 @@ unsafe impl<'a, T: 'static> SystemParam for NonSend<'a, T> { panic!( "Non-send resource requested by {} does not exist: {}", system_meta.name, - std::any::type_name::() + core::any::type_name::() ) }); @@ -1359,11 +1359,11 @@ unsafe impl<'a, T: 'static> SystemParam for NonSendMut<'a, T> { if combined_access.has_component_write(component_id) { panic!( "error[B0002]: NonSendMut<{}> in system {} conflicts with a previous mutable resource access ({0}). Consider removing the duplicate access. See: https://bevyengine.org/learn/errors/b0002", - std::any::type_name::(), system_meta.name); + core::any::type_name::(), system_meta.name); } else if combined_access.has_component_read(component_id) { panic!( "error[B0002]: NonSendMut<{}> in system {} conflicts with a previous immutable resource access ({0}). Consider removing the duplicate access. See: https://bevyengine.org/learn/errors/b0002", - std::any::type_name::(), system_meta.name); + core::any::type_name::(), system_meta.name); } system_meta .component_access_set @@ -1403,7 +1403,7 @@ unsafe impl<'a, T: 'static> SystemParam for NonSendMut<'a, T> { panic!( "Non-send resource requested by {} does not exist: {}", system_meta.name, - std::any::type_name::() + core::any::type_name::() ) }); NonSendMut { @@ -1866,7 +1866,7 @@ pub mod lifetimeless { /// struct GenericParam<'w, 's, T: SystemParam> { /// field: T, /// // Use the lifetimes in this type, or they will be unbound. -/// phantom: core::marker::PhantomData<&'w &'s ()> +/// phantom: std::marker::PhantomData<&'w &'s ()> /// } /// # fn check_always_is_system(){ /// # bevy_ecs::system::assert_is_system(do_thing_generically::); @@ -2273,7 +2273,7 @@ mod tests { self as bevy_ecs, // Necessary for the `SystemParam` Derive when used inside `bevy_ecs`. system::assert_is_system, }; - use std::cell::RefCell; + use core::cell::RefCell; // Compile test for https://github.com/bevyengine/bevy/pull/2838. #[test] @@ -2465,7 +2465,7 @@ mod tests { } let mut world = World::new(); - world.insert_non_send_resource(std::ptr::null_mut::()); + world.insert_non_send_resource(core::ptr::null_mut::()); let mut schedule = crate::schedule::Schedule::default(); schedule.add_systems((non_send_param_set, non_send_param_set, non_send_param_set)); schedule.run(&mut world); @@ -2480,7 +2480,7 @@ mod tests { } let mut world = World::new(); - world.insert_non_send_resource(std::ptr::null_mut::()); + world.insert_non_send_resource(core::ptr::null_mut::()); let mut schedule = crate::schedule::Schedule::default(); schedule.add_systems((non_send_param_set, non_send_param_set, non_send_param_set)); schedule.run(&mut world); diff --git a/crates/bevy_ecs/src/system/system_registry.rs b/crates/bevy_ecs/src/system/system_registry.rs index 91791b9571260..a459383ebc53a 100644 --- a/crates/bevy_ecs/src/system/system_registry.rs +++ b/crates/bevy_ecs/src/system/system_registry.rs @@ -1,14 +1,14 @@ -use std::marker::PhantomData; - use crate::{ + self as bevy_ecs, bundle::Bundle, change_detection::Mut, entity::Entity, - system::{input::SystemInput, BoxedSystem, IntoSystem, System}, + system::input::SystemInput, + system::{BoxedSystem, IntoSystem, System}, world::{Command, World}, - {self as bevy_ecs}, }; use bevy_ecs_macros::{Component, Resource}; +use core::marker::PhantomData; use thiserror::Error; /// A small wrapper for [`BoxedSystem`] that also keeps track whether or not the system has been initialized. @@ -96,14 +96,14 @@ impl PartialEq for SystemId { } // A manual impl is used because the trait bounds should ignore the `I` and `O` phantom parameters. -impl std::hash::Hash for SystemId { - fn hash(&self, state: &mut H) { +impl core::hash::Hash for SystemId { + fn hash(&self, state: &mut H) { self.entity.hash(state); } } -impl std::fmt::Debug for SystemId { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl core::fmt::Debug for SystemId { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { f.debug_tuple("SystemId").field(&self.entity).finish() } } @@ -597,8 +597,8 @@ pub enum RegisteredSystemError { SelfRemove(SystemId), } -impl std::fmt::Debug for RegisteredSystemError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl core::fmt::Debug for RegisteredSystemError { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { match self { Self::SystemIdNotRegistered(arg0) => { f.debug_tuple("SystemIdNotRegistered").field(arg0).finish() diff --git a/crates/bevy_ecs/src/world/command_queue.rs b/crates/bevy_ecs/src/world/command_queue.rs index 4183493a84540..9fd3a06b9d8ef 100644 --- a/crates/bevy_ecs/src/world/command_queue.rs +++ b/crates/bevy_ecs/src/world/command_queue.rs @@ -1,9 +1,9 @@ use crate::system::{SystemBuffer, SystemMeta}; -use std::{ +use core::{ fmt::Debug, mem::{size_of, MaybeUninit}, - panic::{self, AssertUnwindSafe}, + panic::AssertUnwindSafe, ptr::{addr_of_mut, NonNull}, }; @@ -58,7 +58,7 @@ pub(crate) struct RawCommandQueue { // It is not possible to soundly print the values of the contained bytes, as some of them may be padding or uninitialized (#4863) // So instead, the manual impl just prints the length of vec. impl Debug for CommandQueue { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { f.debug_struct("CommandQueue") .field("len_bytes", &self.bytes.len()) .finish_non_exhaustive() @@ -261,7 +261,7 @@ impl RawCommandQueue { self.bytes.as_mut().as_mut_ptr().add(local_cursor).cast(), )) }; - let result = panic::catch_unwind(AssertUnwindSafe(|| { + let result = std::panic::catch_unwind(AssertUnwindSafe(|| { // SAFETY: The data underneath the cursor must correspond to the type erased in metadata, // since they were stored next to each other by `.push()`. // For ZSTs, the type doesn't matter as long as the pointer is non-null. @@ -294,7 +294,7 @@ impl RawCommandQueue { if start == 0 { bytes.append(panic_recovery); } - panic::resume_unwind(payload); + std::panic::resume_unwind(payload); } } @@ -337,12 +337,10 @@ mod test { use super::*; use crate as bevy_ecs; use crate::system::Resource; - use std::{ + use alloc::sync::Arc; + use core::{ panic::AssertUnwindSafe, - sync::{ - atomic::{AtomicU32, Ordering}, - Arc, - }, + sync::atomic::{AtomicU32, Ordering}, }; struct DropCheck(Arc); @@ -444,7 +442,7 @@ mod test { #[test] fn test_command_queue_inner_panic_safe() { - panic::set_hook(Box::new(|_| {})); + std::panic::set_hook(Box::new(|_| {})); let mut queue = CommandQueue::default(); @@ -453,7 +451,7 @@ mod test { let mut world = World::new(); - let _ = panic::catch_unwind(AssertUnwindSafe(|| { + let _ = std::panic::catch_unwind(AssertUnwindSafe(|| { queue.apply(&mut world); })); @@ -467,7 +465,7 @@ mod test { #[test] fn test_command_queue_inner_nested_panic_safe() { - panic::set_hook(Box::new(|_| {})); + std::panic::set_hook(Box::new(|_| {})); #[derive(Resource, Default)] struct Order(Vec); @@ -487,7 +485,7 @@ mod test { }); world.commands().queue(add_index(4)); - let _ = panic::catch_unwind(AssertUnwindSafe(|| { + let _ = std::panic::catch_unwind(AssertUnwindSafe(|| { world.flush_commands(); })); diff --git a/crates/bevy_ecs/src/world/deferred_world.rs b/crates/bevy_ecs/src/world/deferred_world.rs index 9f80ca8d860ac..8b3b046859137 100644 --- a/crates/bevy_ecs/src/world/deferred_world.rs +++ b/crates/bevy_ecs/src/world/deferred_world.rs @@ -1,4 +1,4 @@ -use std::ops::Deref; +use core::ops::Deref; use crate::{ archetype::Archetype, @@ -152,7 +152,7 @@ impl<'w> DeferredWorld<'w> { Did you forget to add it using `app.insert_resource` / `app.init_resource`? Resources are also implicitly added via `app.add_event`, and can be added by plugins.", - std::any::type_name::() + core::any::type_name::() ), } } @@ -181,7 +181,7 @@ impl<'w> DeferredWorld<'w> { "Requested non-send resource {} does not exist in the `World`. Did you forget to add it using `app.insert_non_send_resource` / `app.init_non_send_resource`? Non-send resources can also be added by plugins.", - std::any::type_name::() + core::any::type_name::() ), } } @@ -202,7 +202,7 @@ impl<'w> DeferredWorld<'w> { /// or [`None`] if the `event` could not be sent. #[inline] pub fn send_event(&mut self, event: E) -> Option> { - self.send_event_batch(std::iter::once(event))?.next() + self.send_event_batch(core::iter::once(event))?.next() } /// Sends the default value of the [`Event`] of type `E`. @@ -224,7 +224,7 @@ impl<'w> DeferredWorld<'w> { let Some(mut events_resource) = self.get_resource_mut::>() else { bevy_utils::tracing::error!( "Unable to send event `{}`\n\tEvent must be added to the app with `add_event()`\n\thttps://docs.rs/bevy/*/bevy/app/struct.App.html#method.add_event ", - std::any::type_name::() + core::any::type_name::() ); return None; }; diff --git a/crates/bevy_ecs/src/world/entity_ref.rs b/crates/bevy_ecs/src/world/entity_ref.rs index 157b2a55f18ff..6851356f5c3a2 100644 --- a/crates/bevy_ecs/src/world/entity_ref.rs +++ b/crates/bevy_ecs/src/world/entity_ref.rs @@ -13,7 +13,7 @@ use crate::{ world::{DeferredWorld, Mut, World}, }; use bevy_ptr::{OwningPtr, Ptr}; -use std::{any::TypeId, marker::PhantomData}; +use core::{any::TypeId, marker::PhantomData}; use thiserror::Error; use super::{unsafe_world_cell::UnsafeEntityCell, Ref, ON_REMOVE, ON_REPLACE}; @@ -926,7 +926,7 @@ impl<'w> EntityWorldMut<'w> { .bundles .init_dynamic_info(&self.world.components, component_ids); let mut storage_types = - std::mem::take(self.world.bundles.get_storages_unchecked(bundle_id)); + core::mem::take(self.world.bundles.get_storages_unchecked(bundle_id)); let bundle_inserter = BundleInserter::new_with_id( self.world, self.location.archetype_id, @@ -941,7 +941,7 @@ impl<'w> EntityWorldMut<'w> { iter_components, (*storage_types).iter().cloned(), ); - *self.world.bundles.get_storages_unchecked(bundle_id) = std::mem::take(&mut storage_types); + *self.world.bundles.get_storages_unchecked(bundle_id) = core::mem::take(&mut storage_types); self } @@ -2784,7 +2784,7 @@ pub(crate) unsafe fn take_component<'a>( #[cfg(test)] mod tests { use bevy_ptr::OwningPtr; - use std::panic::AssertUnwindSafe; + use core::panic::AssertUnwindSafe; use crate::{ self as bevy_ecs, @@ -2830,7 +2830,7 @@ mod tests { let entity = world.spawn(TestComponent(42)).id(); let component_id = world .components() - .get_id(std::any::TypeId::of::()) + .get_id(core::any::TypeId::of::()) .unwrap(); let entity = world.entity(entity); @@ -2847,7 +2847,7 @@ mod tests { let entity = world.spawn(TestComponent(42)).id(); let component_id = world .components() - .get_id(std::any::TypeId::of::()) + .get_id(core::any::TypeId::of::()) .unwrap(); let mut entity_mut = world.entity_mut(entity); diff --git a/crates/bevy_ecs/src/world/identifier.rs b/crates/bevy_ecs/src/world/identifier.rs index 0e581b368fc2b..9187b818504b5 100644 --- a/crates/bevy_ecs/src/world/identifier.rs +++ b/crates/bevy_ecs/src/world/identifier.rs @@ -4,7 +4,7 @@ use crate::{ system::{ExclusiveSystemParam, ReadOnlySystemParam, SystemMeta, SystemParam}, world::{FromWorld, World}, }; -use std::sync::atomic::{AtomicUsize, Ordering}; +use core::sync::atomic::{AtomicUsize, Ordering}; use super::unsafe_world_cell::UnsafeWorldCell; @@ -97,7 +97,7 @@ mod tests { #[test] fn world_ids_unique() { - let ids = std::iter::repeat_with(WorldId::new) + let ids = core::iter::repeat_with(WorldId::new) .take(50) .map(Option::unwrap) .collect::>(); @@ -138,7 +138,7 @@ mod tests { // #[should_panic] // fn panic_on_overflow() { // MAX_WORLD_ID.store(usize::MAX - 50, Ordering::Relaxed); - // std::iter::repeat_with(WorldId::new) + // core::iter::repeat_with(WorldId::new) // .take(500) // .for_each(|_| ()); // } diff --git a/crates/bevy_ecs/src/world/mod.rs b/crates/bevy_ecs/src/world/mod.rs index 094a21af67f82..7e0d194442fd5 100644 --- a/crates/bevy_ecs/src/world/mod.rs +++ b/crates/bevy_ecs/src/world/mod.rs @@ -45,7 +45,7 @@ use crate::{ }; use bevy_ptr::{OwningPtr, Ptr}; use bevy_utils::tracing::warn; -use std::{ +use core::{ any::TypeId, fmt, mem::MaybeUninit, @@ -271,7 +271,7 @@ impl World { /// Will panic if `T` exists in any archetypes. pub fn register_component_hooks(&mut self) -> &mut ComponentHooks { let index = self.register_component::(); - assert!(!self.archetypes.archetypes.iter().any(|a| a.contains(index)), "Components hooks cannot be modified if the component already exists in an archetype, use register_component if {} may already be in use", std::any::type_name::()); + assert!(!self.archetypes.archetypes.iter().any(|a| a.contains(index)), "Components hooks cannot be modified if the component already exists in an archetype, use register_component if {} may already be in use", core::any::type_name::()); // SAFETY: We just created this component unsafe { self.components.get_hooks_mut(index).debug_checked_unwrap() } } @@ -590,7 +590,7 @@ impl World { entities: [Entity; N], ) -> Result<[EntityRef<'_>; N], Entity> { let mut refs = [MaybeUninit::uninit(); N]; - for (r, id) in std::iter::zip(&mut refs, entities) { + for (r, id) in core::iter::zip(&mut refs, entities) { *r = MaybeUninit::new(self.get_entity(id).ok_or(id)?); } @@ -773,7 +773,7 @@ impl World { let world_cell = self.as_unsafe_world_cell(); let mut cells = [MaybeUninit::uninit(); N]; - for (cell, id) in std::iter::zip(&mut cells, entities) { + for (cell, id) in core::iter::zip(&mut cells, entities) { *cell = MaybeUninit::new( world_cell .get_entity(id) @@ -1611,7 +1611,7 @@ impl World { Did you forget to add it using `app.insert_resource` / `app.init_resource`? Resources are also implicitly added via `app.add_event`, and can be added by plugins.", - std::any::type_name::() + core::any::type_name::() ), } } @@ -1635,7 +1635,7 @@ impl World { Did you forget to add it using `app.insert_resource` / `app.init_resource`? Resources are also implicitly added via `app.add_event`, and can be added by plugins.", - std::any::type_name::() + core::any::type_name::() ), } } @@ -1659,7 +1659,7 @@ impl World { Did you forget to add it using `app.insert_resource` / `app.init_resource`? Resources are also implicitly added via `app.add_event`, and can be added by plugins.", - std::any::type_name::() + core::any::type_name::() ), } } @@ -1746,7 +1746,7 @@ impl World { "Requested non-send resource {} does not exist in the `World`. Did you forget to add it using `app.insert_non_send_resource` / `app.init_non_send_resource`? Non-send resources can also be added by plugins.", - std::any::type_name::() + core::any::type_name::() ), } } @@ -1768,7 +1768,7 @@ impl World { "Requested non-send resource {} does not exist in the `World`. Did you forget to add it using `app.insert_non_send_resource` / `app.init_non_send_resource`? Non-send resources can also be added by plugins.", - std::any::type_name::() + core::any::type_name::() ), } } @@ -2000,13 +2000,13 @@ impl World { let component_id = self .components .get_resource_id(TypeId::of::()) - .unwrap_or_else(|| panic!("resource does not exist: {}", std::any::type_name::())); + .unwrap_or_else(|| panic!("resource does not exist: {}", core::any::type_name::())); let (ptr, mut ticks, mut _caller) = self .storages .resources .get_mut(component_id) .and_then(ResourceData::remove) - .unwrap_or_else(|| panic!("resource does not exist: {}", std::any::type_name::())); + .unwrap_or_else(|| panic!("resource does not exist: {}", core::any::type_name::())); // Read the value onto the stack to avoid potential mut aliasing. // SAFETY: `ptr` was obtained from the TypeId of `R`. let mut value = unsafe { ptr.read::() }; @@ -2025,7 +2025,7 @@ impl World { assert!(!self.contains_resource::(), "Resource `{}` was inserted during a call to World::resource_scope.\n\ This is not allowed as the original resource is reinserted to the world after the closure is invoked.", - std::any::type_name::()); + core::any::type_name::()); OwningPtr::make(value, |ptr| { // SAFETY: pointer is of type R @@ -2044,7 +2044,7 @@ impl World { .unwrap_or_else(|| { panic!( "No resource of type {} exists in the World.", - std::any::type_name::() + core::any::type_name::() ) }); } @@ -2058,7 +2058,7 @@ impl World { /// or [`None`] if the `event` could not be sent. #[inline] pub fn send_event(&mut self, event: E) -> Option> { - self.send_event_batch(std::iter::once(event))?.next() + self.send_event_batch(core::iter::once(event))?.next() } /// Sends the default value of the [`Event`] of type `E`. @@ -2080,7 +2080,7 @@ impl World { let Some(mut events_resource) = self.get_resource_mut::>() else { bevy_utils::tracing::error!( "Unable to send event `{}`\n\tEvent must be added to the app with `add_event()`\n\thttps://docs.rs/bevy/*/bevy/app/struct.App.html#method.add_event ", - std::any::type_name::() + core::any::type_name::() ); return None; }; @@ -2989,16 +2989,15 @@ mod tests { ptr::OwningPtr, system::Resource, }; + use alloc::sync::Arc; use bevy_ecs_macros::Component; use bevy_utils::{HashMap, HashSet}; - use std::{ + use core::{ any::TypeId, panic, - sync::{ - atomic::{AtomicBool, AtomicU32, Ordering}, - Arc, Mutex, - }, + sync::atomic::{AtomicBool, AtomicU32, Ordering}, }; + use std::sync::Mutex; // For bevy_ecs_macros use crate as bevy_ecs; @@ -3082,7 +3081,7 @@ mod tests { if !expected_panic_flag { match panic_res { Ok(()) => panic!("Expected a panic but it didn't happen"), - Err(e) => panic::resume_unwind(e), + Err(e) => std::panic::resume_unwind(e), } } @@ -3094,7 +3093,7 @@ mod tests { fn panic_while_overwriting_component() { let helper = DropTestHelper::new(); - let res = panic::catch_unwind(|| { + let res = std::panic::catch_unwind(|| { let mut world = World::new(); world .spawn_empty() @@ -3177,12 +3176,12 @@ mod tests { let mut iter = world.iter_resources(); let (info, ptr) = iter.next().unwrap(); - assert_eq!(info.name(), std::any::type_name::()); + assert_eq!(info.name(), core::any::type_name::()); // SAFETY: We know that the resource is of type `TestResource` assert_eq!(unsafe { ptr.deref::().0 }, 42); let (info, ptr) = iter.next().unwrap(); - assert_eq!(info.name(), std::any::type_name::()); + assert_eq!(info.name(), core::any::type_name::()); assert_eq!( // SAFETY: We know that the resource is of type `TestResource2` unsafe { &ptr.deref::().0 }, @@ -3203,14 +3202,14 @@ mod tests { let mut iter = world.iter_resources_mut(); let (info, mut mut_untyped) = iter.next().unwrap(); - assert_eq!(info.name(), std::any::type_name::()); + assert_eq!(info.name(), core::any::type_name::()); // SAFETY: We know that the resource is of type `TestResource` unsafe { mut_untyped.as_mut().deref_mut::().0 = 43; }; let (info, mut mut_untyped) = iter.next().unwrap(); - assert_eq!(info.name(), std::any::type_name::()); + assert_eq!(info.name(), core::any::type_name::()); // SAFETY: We know that the resource is of type `TestResource2` unsafe { mut_untyped.as_mut().deref_mut::().0 = "Hello, world?".to_string(); @@ -3237,7 +3236,7 @@ mod tests { ComponentDescriptor::new_with_layout( "Custom Test Component".to_string(), StorageType::Table, - std::alloc::Layout::new::<[u8; 8]>(), + core::alloc::Layout::new::<[u8; 8]>(), Some(|ptr| { let data = ptr.read::<[u8; 8]>(); assert_eq!(data, [0, 1, 2, 3, 4, 5, 6, 7]); @@ -3256,7 +3255,7 @@ mod tests { component_id, ptr, #[cfg(feature = "track_change_detection")] - core::panic::Location::caller(), + panic::Location::caller(), ); } }); @@ -3477,7 +3476,7 @@ mod tests { let mut entities = world.iter_entities_mut().collect::>(); entities.sort_by_key(|e| e.get::().map(|a| a.0).or(e.get::().map(|b| b.0))); let (a, b) = entities.split_at_mut(2); - std::mem::swap( + core::mem::swap( &mut a[1].get_mut::().unwrap().0, &mut b[0].get_mut::().unwrap().0, ); diff --git a/crates/bevy_ecs/src/world/reflect.rs b/crates/bevy_ecs/src/world/reflect.rs index 92add787d1e21..f0f982926549b 100644 --- a/crates/bevy_ecs/src/world/reflect.rs +++ b/crates/bevy_ecs/src/world/reflect.rs @@ -246,7 +246,7 @@ pub enum GetComponentReflectError { #[cfg(test)] mod tests { - use std::any::TypeId; + use core::any::TypeId; use bevy_reflect::Reflect; diff --git a/crates/bevy_ecs/src/world/spawn_batch.rs b/crates/bevy_ecs/src/world/spawn_batch.rs index ea6955a96d9ef..dbdbc1cfac31b 100644 --- a/crates/bevy_ecs/src/world/spawn_batch.rs +++ b/crates/bevy_ecs/src/world/spawn_batch.rs @@ -3,9 +3,9 @@ use crate::{ entity::Entity, world::World, }; -use std::iter::FusedIterator; +use core::iter::FusedIterator; #[cfg(feature = "track_change_detection")] -use std::panic::Location; +use core::panic::Location; /// An iterator that spawns a series of entities and returns the [ID](Entity) of /// each spawned entity. diff --git a/crates/bevy_ecs/src/world/unsafe_world_cell.rs b/crates/bevy_ecs/src/world/unsafe_world_cell.rs index e8d0fb6eb12f4..4c2813702a40c 100644 --- a/crates/bevy_ecs/src/world/unsafe_world_cell.rs +++ b/crates/bevy_ecs/src/world/unsafe_world_cell.rs @@ -20,7 +20,7 @@ use crate::{ use bevy_ptr::Ptr; #[cfg(feature = "track_change_detection")] use bevy_ptr::UnsafeCellDeref; -use std::{any::TypeId, cell::UnsafeCell, fmt::Debug, marker::PhantomData, ptr}; +use core::{any::TypeId, cell::UnsafeCell, fmt::Debug, marker::PhantomData, ptr}; /// Variant of the [`World`] where resource and component accesses take `&self`, and the responsibility to avoid /// aliasing violations are given to the caller instead of being checked at compile-time by rust's unique XOR shared rule. @@ -303,7 +303,7 @@ impl<'w> UnsafeWorldCell<'w> { let change_tick = unsafe { &self.world_metadata().change_tick }; // NOTE: We can used a relaxed memory ordering here, since nothing // other than the atomic value itself is relying on atomic synchronization - Tick::new(change_tick.fetch_add(1, std::sync::atomic::Ordering::Relaxed)) + Tick::new(change_tick.fetch_add(1, core::sync::atomic::Ordering::Relaxed)) } /// Provides unchecked access to the internal data stores of the [`World`]. @@ -632,7 +632,7 @@ impl<'w> UnsafeWorldCell<'w> { } impl Debug for UnsafeWorldCell<'_> { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { // SAFETY: World's Debug implementation only accesses metadata. Debug::fmt(unsafe { self.world_metadata() }, f) } diff --git a/crates/bevy_gizmos/src/arcs.rs b/crates/bevy_gizmos/src/arcs.rs index 204d927f596d8..cc4934398db06 100644 --- a/crates/bevy_gizmos/src/arcs.rs +++ b/crates/bevy_gizmos/src/arcs.rs @@ -9,7 +9,7 @@ use crate::{ }; use bevy_color::Color; use bevy_math::{Isometry2d, Isometry3d, Quat, Rot2, Vec2, Vec3}; -use std::f32::consts::{FRAC_PI_2, TAU}; +use core::f32::consts::{FRAC_PI_2, TAU}; // === 2D === @@ -367,7 +367,7 @@ where to: Vec2, color: impl Into, ) -> Arc2dBuilder<'_, 'w, 's, Config, Clear> { - self.arc_2d_from_to(center, from, to, color, std::convert::identity) + self.arc_2d_from_to(center, from, to, color, core::convert::identity) } /// Draws the longest arc between two points (`from` and `to`) relative to a specified `center` point. diff --git a/crates/bevy_gizmos/src/circles.rs b/crates/bevy_gizmos/src/circles.rs index 9e9a408bbe64e..7b0a5e82890a8 100644 --- a/crates/bevy_gizmos/src/circles.rs +++ b/crates/bevy_gizmos/src/circles.rs @@ -6,7 +6,7 @@ use crate::prelude::{GizmoConfigGroup, Gizmos}; use bevy_color::Color; use bevy_math::{ops, Isometry2d, Isometry3d, Quat, Vec2, Vec3}; -use std::f32::consts::TAU; +use core::f32::consts::TAU; pub(crate) const DEFAULT_CIRCLE_RESOLUTION: u32 = 32; diff --git a/crates/bevy_gizmos/src/config.rs b/crates/bevy_gizmos/src/config.rs index 0705029ddf19c..2f164d9f0b956 100644 --- a/crates/bevy_gizmos/src/config.rs +++ b/crates/bevy_gizmos/src/config.rs @@ -12,10 +12,10 @@ use bevy_ecs::component::Component; use bevy_ecs::{reflect::ReflectResource, system::Resource}; use bevy_reflect::{std_traits::ReflectDefault, Reflect, TypePath}; use bevy_utils::TypeIdMap; -use core::panic; -use std::{ +use core::{ any::TypeId, ops::{Deref, DerefMut}, + panic, }; /// An enum configuring how line joints will be drawn. diff --git a/crates/bevy_gizmos/src/gizmos.rs b/crates/bevy_gizmos/src/gizmos.rs index 7f50221978f38..86df15333949f 100644 --- a/crates/bevy_gizmos/src/gizmos.rs +++ b/crates/bevy_gizmos/src/gizmos.rs @@ -1,6 +1,6 @@ //! A module for the [`Gizmos`] [`SystemParam`]. -use std::{iter, marker::PhantomData, mem}; +use core::{iter, marker::PhantomData, mem}; use bevy_color::{Color, LinearRgba}; use bevy_ecs::{ diff --git a/crates/bevy_gizmos/src/lib.rs b/crates/bevy_gizmos/src/lib.rs index bbef44df46677..0c3bd81d67a10 100644 --- a/crates/bevy_gizmos/src/lib.rs +++ b/crates/bevy_gizmos/src/lib.rs @@ -57,6 +57,7 @@ mod pipeline_3d; pub mod prelude { #[cfg(feature = "bevy_render")] pub use crate::aabb::{AabbGizmoConfigGroup, ShowAabbGizmo}; + #[doc(hidden)] pub use crate::{ config::{ @@ -72,56 +73,56 @@ pub mod prelude { pub use crate::light::{LightGizmoColor, LightGizmoConfigGroup, ShowLightGizmo}; } -#[cfg(feature = "bevy_render")] -use bevy_ecs::{ - query::ROQueryItem, - system::{ - lifetimeless::{Read, SRes}, - Commands, SystemParamItem, - }, -}; - use bevy_app::{App, FixedFirst, FixedLast, Last, Plugin, RunFixedMainLoop}; use bevy_asset::{Asset, AssetApp, Assets, Handle}; use bevy_color::LinearRgba; -#[cfg(feature = "bevy_render")] -use bevy_ecs::component::Component; use bevy_ecs::{ schedule::{IntoSystemConfigs, SystemSet}, system::{Res, ResMut, Resource}, }; use bevy_math::Vec3; use bevy_reflect::TypePath; + +#[cfg(feature = "bevy_render")] +use { + bevy_ecs::{ + component::Component, + query::ROQueryItem, + system::{ + lifetimeless::{Read, SRes}, + Commands, SystemParamItem, + }, + }, + bevy_render::{ + extract_component::{ComponentUniforms, DynamicUniformIndex, UniformComponentPlugin}, + render_asset::{PrepareAssetError, RenderAsset, RenderAssetPlugin, RenderAssets}, + render_phase::{PhaseItem, RenderCommand, RenderCommandResult, TrackedRenderPass}, + render_resource::{ + binding_types::uniform_buffer, BindGroup, BindGroupEntries, BindGroupLayout, + BindGroupLayoutEntries, Buffer, BufferInitDescriptor, BufferUsages, Shader, + ShaderStages, ShaderType, VertexFormat, + }, + renderer::RenderDevice, + Extract, ExtractSchedule, Render, RenderApp, RenderSet, + }, + bytemuck::cast_slice, +}; + #[cfg(all( feature = "bevy_render", any(feature = "bevy_pbr", feature = "bevy_sprite"), ))] use bevy_render::render_resource::{VertexAttribute, VertexBufferLayout, VertexStepMode}; -#[cfg(feature = "bevy_render")] -use bevy_render::{ - extract_component::{ComponentUniforms, DynamicUniformIndex, UniformComponentPlugin}, - render_asset::{PrepareAssetError, RenderAsset, RenderAssetPlugin, RenderAssets}, - render_phase::{PhaseItem, RenderCommand, RenderCommandResult, TrackedRenderPass}, - render_resource::{ - binding_types::uniform_buffer, BindGroup, BindGroupEntries, BindGroupLayout, - BindGroupLayoutEntries, Buffer, BufferInitDescriptor, BufferUsages, Shader, ShaderStages, - ShaderType, VertexFormat, - }, - renderer::RenderDevice, - Extract, ExtractSchedule, Render, RenderApp, RenderSet, -}; use bevy_time::Fixed; use bevy_utils::TypeIdMap; -#[cfg(feature = "bevy_render")] -use bytemuck::cast_slice; use config::{ DefaultGizmoConfigGroup, GizmoConfig, GizmoConfigGroup, GizmoConfigStore, GizmoLineJoint, }; +use core::{any::TypeId, mem}; use gizmos::{GizmoStorage, Swap}; #[cfg(all(feature = "bevy_pbr", feature = "bevy_render"))] use light::LightGizmoPlugin; -use std::{any::TypeId, mem}; #[cfg(feature = "bevy_render")] const LINE_SHADER_HANDLE: Handle = Handle::weak_from_u128(7414812689238026784); diff --git a/crates/bevy_gizmos/src/light.rs b/crates/bevy_gizmos/src/light.rs index 0debc8238c247..615f1e8753cbf 100644 --- a/crates/bevy_gizmos/src/light.rs +++ b/crates/bevy_gizmos/src/light.rs @@ -1,6 +1,6 @@ //! A module adding debug visualization of [`PointLight`]s, [`SpotLight`]s and [`DirectionalLight`]s. -use std::f32::consts::PI; +use core::f32::consts::PI; use crate::{self as bevy_gizmos, primitives::dim3::GizmoPrimitive3d}; diff --git a/crates/bevy_gizmos/src/primitives/dim2.rs b/crates/bevy_gizmos/src/primitives/dim2.rs index bc20326c2ec1f..732eba0c019d8 100644 --- a/crates/bevy_gizmos/src/primitives/dim2.rs +++ b/crates/bevy_gizmos/src/primitives/dim2.rs @@ -1,6 +1,6 @@ //! A module for rendering each of the 2D [`bevy_math::primitives`] with [`Gizmos`]. -use std::f32::consts::{FRAC_PI_2, PI}; +use core::f32::consts::{FRAC_PI_2, PI}; use super::helpers::*; diff --git a/crates/bevy_gizmos/src/primitives/helpers.rs b/crates/bevy_gizmos/src/primitives/helpers.rs index fa86a6ebe0413..66e171c6c9f59 100644 --- a/crates/bevy_gizmos/src/primitives/helpers.rs +++ b/crates/bevy_gizmos/src/primitives/helpers.rs @@ -1,4 +1,4 @@ -use std::f32::consts::TAU; +use core::f32::consts::TAU; use bevy_math::{ops, Vec2}; @@ -37,7 +37,7 @@ pub(crate) fn circle_coordinates_closed( radius: f32, resolution: u32, ) -> impl Iterator { - circle_coordinates(radius, resolution).chain(std::iter::once(single_circle_coordinate( + circle_coordinates(radius, resolution).chain(core::iter::once(single_circle_coordinate( radius, resolution, resolution, ))) } diff --git a/crates/bevy_gizmos/src/rounded_box.rs b/crates/bevy_gizmos/src/rounded_box.rs index ac459c917866f..70ee09b64d01d 100644 --- a/crates/bevy_gizmos/src/rounded_box.rs +++ b/crates/bevy_gizmos/src/rounded_box.rs @@ -3,7 +3,7 @@ //! Includes the implementation of [`Gizmos::rounded_rect`], [`Gizmos::rounded_rect_2d`] and [`Gizmos::rounded_cuboid`]. //! and assorted support items. -use std::f32::consts::FRAC_PI_2; +use core::f32::consts::FRAC_PI_2; use crate::prelude::{GizmoConfigGroup, Gizmos}; use bevy_color::Color; @@ -75,7 +75,7 @@ impl Drop for RoundedRectBuilder<'_, '_, '_, T> { let mut inner_half_size = outer_half_size - Vec2::splat(corner_radius); if config.corner_radius < 0. { - std::mem::swap(&mut outer_half_size, &mut inner_half_size); + core::mem::swap(&mut outer_half_size, &mut inner_half_size); } // Handle cases where the rectangle collapses into simpler shapes diff --git a/crates/bevy_gltf/src/lib.rs b/crates/bevy_gltf/src/lib.rs index cb8ead5893aa7..fdd3a6e783557 100644 --- a/crates/bevy_gltf/src/lib.rs +++ b/crates/bevy_gltf/src/lib.rs @@ -95,6 +95,8 @@ //! //! You can use [`GltfAssetLabel`] to ensure you are using the correct label. +extern crate alloc; + #[cfg(feature = "bevy_animation")] use bevy_animation::AnimationClip; use bevy_utils::HashMap; @@ -526,8 +528,8 @@ pub enum GltfAssetLabel { InverseBindMatrices(usize), } -impl std::fmt::Display for GltfAssetLabel { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl core::fmt::Display for GltfAssetLabel { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { match self { GltfAssetLabel::Scene(index) => f.write_str(&format!("Scene{index}")), GltfAssetLabel::Node(index) => f.write_str(&format!("Node{index}")), diff --git a/crates/bevy_gltf/src/loader.rs b/crates/bevy_gltf/src/loader.rs index f7324223781e0..d569ad6451081 100644 --- a/crates/bevy_gltf/src/loader.rs +++ b/crates/bevy_gltf/src/loader.rs @@ -3,12 +3,9 @@ use crate::{ GltfMeshExtras, GltfNode, GltfSceneExtras, GltfSkin, }; -#[cfg(feature = "bevy_animation")] -use bevy_animation::{ - keyframes::{ - Keyframes, MorphWeightsKeyframes, RotationKeyframes, ScaleKeyframes, TranslationKeyframes, - }, - AnimationTarget, AnimationTargetId, +use alloc::collections::VecDeque; +use bevy_animation::prelude::{ + Keyframes, MorphWeightsKeyframes, RotationKeyframes, ScaleKeyframes, TranslationKeyframes, }; use bevy_asset::{ io::Reader, AssetLoadError, AssetLoader, Handle, LoadContext, ReadAssetBytesError, @@ -61,14 +58,16 @@ use gltf::{ }; use serde::{Deserialize, Serialize}; use serde_json::{value, Value}; -#[cfg(feature = "bevy_animation")] -use smallvec::SmallVec; use std::{ - collections::VecDeque, io::Error, path::{Path, PathBuf}, }; use thiserror::Error; +#[cfg(feature = "bevy_animation")] +use { + bevy_animation::{AnimationTarget, AnimationTargetId}, + smallvec::SmallVec, +}; /// An error that occurs when loading a glTF file. #[derive(Error, Debug)] @@ -1423,7 +1422,7 @@ fn load_node( // NOTE: KHR_punctual_lights defines the intensity units for point lights in // candela (lm/sr) which is luminous intensity and we need luminous power. // For a point light, luminous power = 4 * pi * luminous intensity - intensity: light.intensity() * std::f32::consts::PI * 4.0, + intensity: light.intensity() * core::f32::consts::PI * 4.0, range: light.range().unwrap_or(20.0), radius: 0.0, ..Default::default() @@ -1449,7 +1448,7 @@ fn load_node( // NOTE: KHR_punctual_lights defines the intensity units for spot lights in // candela (lm/sr) which is luminous intensity and we need luminous power. // For a spot light, we map luminous power = 4 * pi * luminous intensity - intensity: light.intensity() * std::f32::consts::PI * 4.0, + intensity: light.intensity() * core::f32::consts::PI * 4.0, range: light.range().unwrap_or(20.0), radius: light.range().unwrap_or(0.0), inner_angle: inner_cone_angle, diff --git a/crates/bevy_hierarchy/src/child_builder.rs b/crates/bevy_hierarchy/src/child_builder.rs index e754ec624de11..47c74bb4f6cdc 100644 --- a/crates/bevy_hierarchy/src/child_builder.rs +++ b/crates/bevy_hierarchy/src/child_builder.rs @@ -756,7 +756,7 @@ mod tests { let world = &mut World::new(); world.insert_resource(Events::::default()); - let [a, b, c, d] = std::array::from_fn(|_| world.spawn_empty().id()); + let [a, b, c, d] = core::array::from_fn(|_| world.spawn_empty().id()); world.entity_mut(a).add_child(b); @@ -791,7 +791,7 @@ mod tests { let world = &mut World::new(); world.insert_resource(Events::::default()); - let [a, b, c] = std::array::from_fn(|_| world.spawn_empty().id()); + let [a, b, c] = core::array::from_fn(|_| world.spawn_empty().id()); world.entity_mut(a).set_parent(b); @@ -825,7 +825,7 @@ mod tests { fn set_parent_of_orphan() { let world = &mut World::new(); - let [a, b, c] = std::array::from_fn(|_| world.spawn_empty().id()); + let [a, b, c] = core::array::from_fn(|_| world.spawn_empty().id()); world.entity_mut(a).set_parent(b); assert_parent(world, a, Some(b)); assert_children(world, b, Some(&[a])); @@ -842,7 +842,7 @@ mod tests { let world = &mut World::new(); world.insert_resource(Events::::default()); - let [a, b, c] = std::array::from_fn(|_| world.spawn_empty().id()); + let [a, b, c] = core::array::from_fn(|_| world.spawn_empty().id()); world.entity_mut(a).add_children(&[b, c]); world.entity_mut(b).remove_parent(); diff --git a/crates/bevy_hierarchy/src/components/children.rs b/crates/bevy_hierarchy/src/components/children.rs index ee2fb5578a8cf..df4127b2a40e8 100644 --- a/crates/bevy_hierarchy/src/components/children.rs +++ b/crates/bevy_hierarchy/src/components/children.rs @@ -6,9 +6,8 @@ use bevy_ecs::{ prelude::FromWorld, world::World, }; -use core::slice; +use core::{ops::Deref, slice}; use smallvec::SmallVec; -use std::ops::Deref; /// Contains references to the child entities of this entity. /// @@ -71,7 +70,7 @@ impl Children { #[inline] pub fn sort_by(&mut self, compare: F) where - F: FnMut(&Entity, &Entity) -> std::cmp::Ordering, + F: FnMut(&Entity, &Entity) -> core::cmp::Ordering, { self.0.sort_by(compare); } @@ -120,7 +119,7 @@ impl Children { #[inline] pub fn sort_unstable_by(&mut self, compare: F) where - F: FnMut(&Entity, &Entity) -> std::cmp::Ordering, + F: FnMut(&Entity, &Entity) -> core::cmp::Ordering, { self.0.sort_unstable_by(compare); } diff --git a/crates/bevy_hierarchy/src/components/parent.rs b/crates/bevy_hierarchy/src/components/parent.rs index 4bd1ea40859c9..4a00e87309d08 100644 --- a/crates/bevy_hierarchy/src/components/parent.rs +++ b/crates/bevy_hierarchy/src/components/parent.rs @@ -6,7 +6,7 @@ use bevy_ecs::{ traversal::Traversal, world::{FromWorld, World}, }; -use std::ops::Deref; +use core::ops::Deref; /// Holds a reference to the parent entity of this entity. /// This component should only be present on entities that actually have a parent entity. @@ -44,7 +44,7 @@ impl Parent { /// [`Children`]: super::children::Children #[inline(always)] pub fn as_slice(&self) -> &[Entity] { - std::slice::from_ref(&self.0) + core::slice::from_ref(&self.0) } } diff --git a/crates/bevy_hierarchy/src/hierarchy.rs b/crates/bevy_hierarchy/src/hierarchy.rs index 446f3884eff24..9f090d8ce4b91 100644 --- a/crates/bevy_hierarchy/src/hierarchy.rs +++ b/crates/bevy_hierarchy/src/hierarchy.rs @@ -36,7 +36,7 @@ pub fn despawn_with_children_recursive(world: &mut World, entity: Entity) { // Should only be called by `despawn_with_children_recursive`! fn despawn_with_children_recursive_inner(world: &mut World, entity: Entity) { if let Some(mut children) = world.get_mut::(entity) { - for e in std::mem::take(&mut children.0) { + for e in core::mem::take(&mut children.0) { despawn_with_children_recursive_inner(world, e); } } diff --git a/crates/bevy_hierarchy/src/lib.rs b/crates/bevy_hierarchy/src/lib.rs index 98011ced58591..ced37bd154f64 100755 --- a/crates/bevy_hierarchy/src/lib.rs +++ b/crates/bevy_hierarchy/src/lib.rs @@ -51,6 +51,8 @@ //! [plugin]: HierarchyPlugin //! [query extension methods]: HierarchyQueryExt +extern crate alloc; + mod components; pub use components::*; diff --git a/crates/bevy_hierarchy/src/query_extension.rs b/crates/bevy_hierarchy/src/query_extension.rs index de342846a7a82..36bf790cec1bd 100644 --- a/crates/bevy_hierarchy/src/query_extension.rs +++ b/crates/bevy_hierarchy/src/query_extension.rs @@ -1,4 +1,4 @@ -use std::collections::VecDeque; +use alloc::collections::VecDeque; use bevy_ecs::{ entity::Entity, @@ -170,7 +170,7 @@ mod tests { fn descendant_iter() { let world = &mut World::new(); - let [a, b, c, d] = std::array::from_fn(|i| world.spawn(A(i)).id()); + let [a, b, c, d] = core::array::from_fn(|i| world.spawn(A(i)).id()); world.entity_mut(a).add_children(&[b, c]); world.entity_mut(c).add_children(&[d]); @@ -189,7 +189,7 @@ mod tests { fn ancestor_iter() { let world = &mut World::new(); - let [a, b, c] = std::array::from_fn(|i| world.spawn(A(i)).id()); + let [a, b, c] = core::array::from_fn(|i| world.spawn(A(i)).id()); world.entity_mut(a).add_children(&[b]); world.entity_mut(b).add_children(&[c]); diff --git a/crates/bevy_hierarchy/src/valid_parent_check_plugin.rs b/crates/bevy_hierarchy/src/valid_parent_check_plugin.rs index d03460375eeda..c24266205c5e7 100644 --- a/crates/bevy_hierarchy/src/valid_parent_check_plugin.rs +++ b/crates/bevy_hierarchy/src/valid_parent_check_plugin.rs @@ -1,12 +1,9 @@ -use std::marker::PhantomData; +use core::marker::PhantomData; -#[cfg(feature = "bevy_app")] -use crate::Parent; use bevy_ecs::prelude::*; + #[cfg(feature = "bevy_app")] -use bevy_utils::HashSet; -#[cfg(feature = "bevy_app")] -use disqualified::ShortName; +use {crate::Parent, bevy_utils::HashSet, disqualified::ShortName}; /// When enabled, runs [`check_hierarchy_component_has_valid_parent`]. /// diff --git a/crates/bevy_input/src/axis.rs b/crates/bevy_input/src/axis.rs index 21e4b7165b444..5e84b4bb4a965 100644 --- a/crates/bevy_input/src/axis.rs +++ b/crates/bevy_input/src/axis.rs @@ -2,7 +2,7 @@ use bevy_ecs::system::Resource; use bevy_utils::HashMap; -use std::hash::Hash; +use core::hash::Hash; /// Stores the position data of the input devices of type `T`. /// diff --git a/crates/bevy_input/src/button_input.rs b/crates/bevy_input/src/button_input.rs index b122b4c25a247..559c7eda90cd8 100644 --- a/crates/bevy_input/src/button_input.rs +++ b/crates/bevy_input/src/button_input.rs @@ -1,12 +1,13 @@ //! The generic input type. -#[cfg(feature = "bevy_reflect")] -use bevy_ecs::reflect::ReflectResource; use bevy_ecs::system::Resource; -#[cfg(feature = "bevy_reflect")] -use bevy_reflect::{std_traits::ReflectDefault, Reflect}; use bevy_utils::HashSet; -use std::hash::Hash; +use core::hash::Hash; +#[cfg(feature = "bevy_reflect")] +use { + bevy_ecs::reflect::ReflectResource, + bevy_reflect::{std_traits::ReflectDefault, Reflect}, +}; /// A "press-able" input of type `T`. /// diff --git a/crates/bevy_input/src/common_conditions.rs b/crates/bevy_input/src/common_conditions.rs index a3525f1d99723..bc2e161b1b55a 100644 --- a/crates/bevy_input/src/common_conditions.rs +++ b/crates/bevy_input/src/common_conditions.rs @@ -1,6 +1,6 @@ use crate::ButtonInput; use bevy_ecs::system::Res; -use std::hash::Hash; +use core::hash::Hash; /// Stateful run condition that can be toggled via a input press using [`ButtonInput::just_pressed`]. /// diff --git a/crates/bevy_input/src/gamepad.rs b/crates/bevy_input/src/gamepad.rs index d45452cd6728c..63007631cdf13 100644 --- a/crates/bevy_input/src/gamepad.rs +++ b/crates/bevy_input/src/gamepad.rs @@ -1,17 +1,18 @@ //! The gamepad input functionality. use crate::{Axis, ButtonInput, ButtonState}; -#[cfg(feature = "bevy_reflect")] -use bevy_ecs::reflect::ReflectResource; use bevy_ecs::{ change_detection::DetectChangesMut, event::{Event, EventReader, EventWriter}, system::{Res, ResMut, Resource}, }; -#[cfg(feature = "bevy_reflect")] -use bevy_reflect::{std_traits::ReflectDefault, Reflect}; use bevy_utils::{tracing::info, Duration, HashMap}; use thiserror::Error; +#[cfg(feature = "bevy_reflect")] +use { + bevy_ecs::reflect::ReflectResource, + bevy_reflect::{std_traits::ReflectDefault, Reflect}, +}; /// Errors that occur when setting axis settings for gamepad input. #[derive(Error, Debug, PartialEq)] diff --git a/crates/bevy_input/src/mouse.rs b/crates/bevy_input/src/mouse.rs index 2ae9022973ee3..a6fd70f013712 100644 --- a/crates/bevy_input/src/mouse.rs +++ b/crates/bevy_input/src/mouse.rs @@ -1,8 +1,6 @@ //! The mouse input functionality. use crate::{ButtonInput, ButtonState}; -#[cfg(feature = "bevy_reflect")] -use bevy_ecs::reflect::ReflectResource; use bevy_ecs::{ change_detection::DetectChangesMut, entity::Entity, @@ -11,7 +9,10 @@ use bevy_ecs::{ }; use bevy_math::Vec2; #[cfg(feature = "bevy_reflect")] -use bevy_reflect::{std_traits::ReflectDefault, Reflect}; +use { + bevy_ecs::reflect::ReflectResource, + bevy_reflect::{std_traits::ReflectDefault, Reflect}, +}; #[cfg(all(feature = "serialize", feature = "bevy_reflect"))] use bevy_reflect::{ReflectDeserialize, ReflectSerialize}; diff --git a/crates/bevy_log/src/android_tracing.rs b/crates/bevy_log/src/android_tracing.rs index fe55d6d46d845..3b6649feaf614 100644 --- a/crates/bevy_log/src/android_tracing.rs +++ b/crates/bevy_log/src/android_tracing.rs @@ -1,12 +1,10 @@ +use alloc::ffi::CString; use bevy_utils::tracing::{ field::Field, span::{Attributes, Record}, Event, Id, Level, Subscriber, }; -use std::{ - ffi::CString, - fmt::{Debug, Write}, -}; +use core::fmt::{Debug, Write}; use tracing_subscriber::{field::Visit, layer::Context, registry::LookupSpan, Layer}; #[derive(Default)] @@ -40,7 +38,7 @@ impl Visit for StringRecorder { } } -impl core::default::Default for StringRecorder { +impl Default for StringRecorder { fn default() -> Self { StringRecorder::new() } @@ -69,7 +67,7 @@ impl LookupSpan<'a>> Layer for AndroidLayer { #[allow(unsafe_code)] fn on_event(&self, event: &Event<'_>, _ctx: Context<'_, S>) { fn sanitize(string: &str) -> CString { - let mut bytes: Vec = string + let bytes: Vec = string .as_bytes() .into_iter() .copied() diff --git a/crates/bevy_log/src/lib.rs b/crates/bevy_log/src/lib.rs index 00e82e64f6667..32bdb9a1224c8 100644 --- a/crates/bevy_log/src/lib.rs +++ b/crates/bevy_log/src/lib.rs @@ -16,9 +16,9 @@ //! For more fine-tuned control over logging behavior, set up the [`LogPlugin`] or //! `DefaultPlugins` during app initialization. -use std::error::Error; -#[cfg(feature = "trace")] -use std::panic; +extern crate alloc; + +use core::error::Error; #[cfg(target_os = "android")] mod android_tracing; @@ -53,8 +53,6 @@ pub use tracing_subscriber; use bevy_app::{App, Plugin}; use tracing_log::LogTracer; -#[cfg(feature = "tracing-chrome")] -use tracing_subscriber::fmt::{format::DefaultFields, FormattedFields}; use tracing_subscriber::{ filter::{FromEnvError, ParseError}, prelude::*, @@ -62,7 +60,11 @@ use tracing_subscriber::{ EnvFilter, Layer, }; #[cfg(feature = "tracing-chrome")] -use {bevy_ecs::system::Resource, bevy_utils::synccell::SyncCell}; +use { + bevy_ecs::system::Resource, + bevy_utils::synccell::SyncCell, + tracing_subscriber::fmt::{format::DefaultFields, FormattedFields}, +}; /// Wrapper resource for `tracing-chrome`'s flush guard. /// When the guard is dropped the chrome log is written to file. @@ -193,8 +195,8 @@ impl Plugin for LogPlugin { fn build(&self, app: &mut App) { #[cfg(feature = "trace")] { - let old_handler = panic::take_hook(); - panic::set_hook(Box::new(move |infos| { + let old_handler = std::panic::take_hook(); + std::panic::set_hook(Box::new(move |infos| { eprintln!("{}", tracing_error::SpanTrace::capture()); old_handler(infos); })); diff --git a/crates/bevy_macro_utils/src/fq_std.rs b/crates/bevy_macro_utils/src/fq_std.rs index 46bfdd43dab59..c350d101ad71a 100644 --- a/crates/bevy_macro_utils/src/fq_std.rs +++ b/crates/bevy_macro_utils/src/fq_std.rs @@ -39,7 +39,7 @@ use proc_macro2::TokenStream; use quote::{quote, ToTokens}; -/// Fully Qualified (FQ) short name for [`core::any::Any`] +/// Fully Qualified (FQ) short name for [`std::any::Any`] pub struct FQAny; /// Fully Qualified (FQ) short name for [`Box`] pub struct FQBox; diff --git a/crates/bevy_macro_utils/src/label.rs b/crates/bevy_macro_utils/src/label.rs index 130c85d5a6dc9..6eec83c04c6bb 100644 --- a/crates/bevy_macro_utils/src/label.rs +++ b/crates/bevy_macro_utils/src/label.rs @@ -76,24 +76,24 @@ pub fn derive_label( }); where_clause.predicates.push( syn::parse2(quote! { - Self: 'static + Send + Sync + Clone + Eq + ::std::fmt::Debug + ::std::hash::Hash + Self: 'static + Send + Sync + Clone + Eq + ::core::fmt::Debug + ::core::hash::Hash }) .unwrap(), ); quote! { impl #impl_generics #trait_path for #ident #ty_generics #where_clause { fn dyn_clone(&self) -> ::std::boxed::Box { - ::std::boxed::Box::new(::std::clone::Clone::clone(self)) + ::std::boxed::Box::new(::core::clone::Clone::clone(self)) } fn as_dyn_eq(&self) -> &dyn #dyn_eq_path { self } - fn dyn_hash(&self, mut state: &mut dyn ::std::hash::Hasher) { - let ty_id = ::std::any::TypeId::of::(); - ::std::hash::Hash::hash(&ty_id, &mut state); - ::std::hash::Hash::hash(self, &mut state); + fn dyn_hash(&self, mut state: &mut dyn ::core::hash::Hasher) { + let ty_id = ::core::any::TypeId::of::(); + ::core::hash::Hash::hash(&ty_id, &mut state); + ::core::hash::Hash::hash(self, &mut state); } } } diff --git a/crates/bevy_macro_utils/src/symbol.rs b/crates/bevy_macro_utils/src/symbol.rs index f99b8dfc5cbac..4bac22a0a16b2 100644 --- a/crates/bevy_macro_utils/src/symbol.rs +++ b/crates/bevy_macro_utils/src/symbol.rs @@ -1,4 +1,4 @@ -use std::fmt::{self, Display}; +use core::fmt::{self, Display}; use syn::{Ident, Path}; /// A single named value, representable as a [string](str). diff --git a/crates/bevy_math/src/bounding/bounded2d/mod.rs b/crates/bevy_math/src/bounding/bounded2d/mod.rs index 8db21c94ca8a9..8f6812bc27247 100644 --- a/crates/bevy_math/src/bounding/bounded2d/mod.rs +++ b/crates/bevy_math/src/bounding/bounded2d/mod.rs @@ -384,7 +384,7 @@ mod aabb2d_tests { min: Vec2::new(-2.0, -2.0), max: Vec2::new(2.0, 2.0), }; - let transformed = a.transformed_by(Vec2::new(2.0, -2.0), std::f32::consts::FRAC_PI_4); + let transformed = a.transformed_by(Vec2::new(2.0, -2.0), core::f32::consts::FRAC_PI_4); let half_length = ops::hypot(2.0, 2.0); assert_eq!( transformed.min, @@ -529,7 +529,7 @@ impl BoundingVolume for BoundingCircle { #[inline(always)] fn visible_area(&self) -> f32 { - std::f32::consts::PI * self.radius() * self.radius() + core::f32::consts::PI * self.radius() * self.radius() } #[inline(always)] @@ -701,10 +701,10 @@ mod bounding_circle_tests { #[test] fn transform() { let a = BoundingCircle::new(Vec2::ONE, 5.0); - let transformed = a.transformed_by(Vec2::new(2.0, -2.0), std::f32::consts::FRAC_PI_4); + let transformed = a.transformed_by(Vec2::new(2.0, -2.0), core::f32::consts::FRAC_PI_4); assert_eq!( transformed.center, - Vec2::new(2.0, std::f32::consts::SQRT_2 - 2.0) + Vec2::new(2.0, core::f32::consts::SQRT_2 - 2.0) ); assert_eq!(transformed.radius(), 5.0); } diff --git a/crates/bevy_math/src/bounding/bounded2d/primitive_impls.rs b/crates/bevy_math/src/bounding/bounded2d/primitive_impls.rs index f3cccbfb0fd1a..1d6b67b0d6aa7 100644 --- a/crates/bevy_math/src/bounding/bounded2d/primitive_impls.rs +++ b/crates/bevy_math/src/bounding/bounded2d/primitive_impls.rs @@ -9,7 +9,7 @@ use crate::{ }, Dir2, Isometry2d, Mat2, Rot2, Vec2, }; -use std::f32::consts::{FRAC_PI_2, PI, TAU}; +use core::f32::consts::{FRAC_PI_2, PI, TAU}; use smallvec::SmallVec; @@ -397,7 +397,7 @@ impl Bounded2d for Capsule2d { #[cfg(test)] mod tests { - use std::f32::consts::{FRAC_PI_2, FRAC_PI_3, FRAC_PI_4, FRAC_PI_6, TAU}; + use core::f32::consts::{FRAC_PI_2, FRAC_PI_3, FRAC_PI_4, FRAC_PI_6, TAU}; use approx::assert_abs_diff_eq; use glam::Vec2; @@ -866,7 +866,7 @@ mod tests { let bounding_circle = polyline.bounding_circle(isometry); assert_eq!(bounding_circle.center, translation); - assert_eq!(bounding_circle.radius(), std::f32::consts::SQRT_2); + assert_eq!(bounding_circle.radius(), core::f32::consts::SQRT_2); } #[test] @@ -939,7 +939,7 @@ mod tests { let bounding_circle = polygon.bounding_circle(isometry); assert_eq!(bounding_circle.center, translation); - assert_eq!(bounding_circle.radius(), std::f32::consts::SQRT_2); + assert_eq!(bounding_circle.radius(), core::f32::consts::SQRT_2); } #[test] diff --git a/crates/bevy_math/src/bounding/bounded3d/extrusion.rs b/crates/bevy_math/src/bounding/bounded3d/extrusion.rs index 2c15d92694bf0..8784a3286ecfd 100644 --- a/crates/bevy_math/src/bounding/bounded3d/extrusion.rs +++ b/crates/bevy_math/src/bounding/bounded3d/extrusion.rs @@ -1,4 +1,4 @@ -use std::f32::consts::FRAC_PI_2; +use core::f32::consts::FRAC_PI_2; use glam::{Vec2, Vec3A, Vec3Swizzles}; @@ -243,7 +243,7 @@ pub trait BoundedExtrusion: Primitive2d + Bounded2d { #[cfg(test)] mod tests { - use std::f32::consts::FRAC_PI_4; + use core::f32::consts::FRAC_PI_4; use glam::{EulerRot, Quat, Vec2, Vec3, Vec3A}; diff --git a/crates/bevy_math/src/bounding/bounded3d/mod.rs b/crates/bevy_math/src/bounding/bounded3d/mod.rs index 60822fa3fe4cd..81edbe8a57d4f 100644 --- a/crates/bevy_math/src/bounding/bounded3d/mod.rs +++ b/crates/bevy_math/src/bounding/bounded3d/mod.rs @@ -387,7 +387,7 @@ mod aabb3d_tests { }; let transformed = a.transformed_by( Vec3A::new(2.0, -2.0, 4.0), - Quat::from_rotation_z(std::f32::consts::FRAC_PI_4), + Quat::from_rotation_z(core::f32::consts::FRAC_PI_4), ); let half_length = ops::hypot(2.0, 2.0); assert_eq!( @@ -547,7 +547,7 @@ impl BoundingVolume for BoundingSphere { #[inline(always)] fn visible_area(&self) -> f32 { - 2. * std::f32::consts::PI * self.radius() * self.radius() + 2. * core::f32::consts::PI * self.radius() * self.radius() } #[inline(always)] @@ -733,11 +733,11 @@ mod bounding_sphere_tests { let a = BoundingSphere::new(Vec3::ONE, 5.0); let transformed = a.transformed_by( Vec3::new(2.0, -2.0, 4.0), - Quat::from_rotation_z(std::f32::consts::FRAC_PI_4), + Quat::from_rotation_z(core::f32::consts::FRAC_PI_4), ); assert_relative_eq!( transformed.center, - Vec3A::new(2.0, std::f32::consts::SQRT_2 - 2.0, 5.0) + Vec3A::new(2.0, core::f32::consts::SQRT_2 - 2.0, 5.0) ); assert_eq!(transformed.radius(), 5.0); } diff --git a/crates/bevy_math/src/bounding/bounded3d/primitive_impls.rs b/crates/bevy_math/src/bounding/bounded3d/primitive_impls.rs index 8827b0f253b61..bb6a6a5a12c37 100644 --- a/crates/bevy_math/src/bounding/bounded3d/primitive_impls.rs +++ b/crates/bevy_math/src/bounding/bounded3d/primitive_impls.rs @@ -475,7 +475,7 @@ mod tests { let aabb = cuboid.aabb_3d(Isometry3d::new( translation, - Quat::from_rotation_z(std::f32::consts::FRAC_PI_4), + Quat::from_rotation_z(core::f32::consts::FRAC_PI_4), )); let expected_half_size = Vec3A::new(1.0606601, 1.0606601, 0.5); assert_eq!(aabb.min, Vec3A::from(translation) - expected_half_size); diff --git a/crates/bevy_math/src/common_traits.rs b/crates/bevy_math/src/common_traits.rs index 481950338fabd..12bea91461e57 100644 --- a/crates/bevy_math/src/common_traits.rs +++ b/crates/bevy_math/src/common_traits.rs @@ -1,7 +1,7 @@ //! This module contains abstract mathematical traits shared by types used in `bevy_math`. use crate::{ops, Dir2, Dir3, Dir3A, Quat, Rot2, Vec2, Vec3, Vec3A, Vec4}; -use std::{ +use core::{ fmt::Debug, ops::{Add, Div, Mul, Neg, Sub}, }; diff --git a/crates/bevy_math/src/cubic_splines.rs b/crates/bevy_math/src/cubic_splines.rs index b99c035c8e71f..63d5c03cdfe4c 100644 --- a/crates/bevy_math/src/cubic_splines.rs +++ b/crates/bevy_math/src/cubic_splines.rs @@ -1,6 +1,6 @@ //! Provides types for building cubic splines for rendering curves and use with animation easing. -use std::{fmt::Debug, iter::once}; +use core::{fmt::Debug, iter::once}; use crate::{ops::FloatPow, Vec2, VectorSpace}; @@ -701,10 +701,10 @@ impl CubicNurbs

{ } let last_knots_value = control_points - 3; Some( - std::iter::repeat(0.0) + core::iter::repeat(0.0) .take(4) .chain((1..last_knots_value).map(|v| v as f32)) - .chain(std::iter::repeat(last_knots_value as f32).take(4)) + .chain(core::iter::repeat(last_knots_value as f32).take(4)) .collect(), ) } @@ -1667,7 +1667,7 @@ mod tests { /// Test that a nurbs curve can approximate a portion of a circle. #[test] fn nurbs_circular_arc() { - use std::f32::consts::FRAC_PI_2; + use core::f32::consts::FRAC_PI_2; const EPSILON: f32 = 0.0000001; // The following NURBS parameters were determined by constraining the first two diff --git a/crates/bevy_math/src/curve/interval.rs b/crates/bevy_math/src/curve/interval.rs index e3852ad06ef60..ae651b52cfb77 100644 --- a/crates/bevy_math/src/curve/interval.rs +++ b/crates/bevy_math/src/curve/interval.rs @@ -1,10 +1,10 @@ //! The [`Interval`] type for nonempty intervals used by the [`Curve`](super::Curve) trait. -use itertools::Either; -use std::{ +use core::{ cmp::{max_by, min_by}, ops::RangeInclusive, }; +use itertools::Either; use thiserror::Error; #[cfg(feature = "bevy_reflect")] diff --git a/crates/bevy_math/src/curve/mod.rs b/crates/bevy_math/src/curve/mod.rs index 3dfb9284ade54..608027ba33f3a 100644 --- a/crates/bevy_math/src/curve/mod.rs +++ b/crates/bevy_math/src/curve/mod.rs @@ -9,9 +9,9 @@ pub use interval::{interval, Interval}; use itertools::Itertools; use crate::StableInterpolate; +use core::{marker::PhantomData, ops::Deref}; use cores::{EvenCore, EvenCoreError, UnevenCore, UnevenCoreError}; use interval::InvalidIntervalError; -use std::{marker::PhantomData, ops::Deref}; use thiserror::Error; #[cfg(feature = "bevy_reflect")] @@ -1021,7 +1021,7 @@ mod tests { use super::*; use crate::{ops, Quat}; use approx::{assert_abs_diff_eq, AbsDiffEq}; - use std::f32::consts::TAU; + use core::f32::consts::TAU; #[test] fn curve_can_be_made_into_an_object() { diff --git a/crates/bevy_math/src/direction.rs b/crates/bevy_math/src/direction.rs index 8f4cf7d9eabab..fe796c64602b4 100644 --- a/crates/bevy_math/src/direction.rs +++ b/crates/bevy_math/src/direction.rs @@ -36,8 +36,8 @@ impl InvalidDirectionError { } } -impl std::fmt::Display for InvalidDirectionError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl core::fmt::Display for InvalidDirectionError { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { write!( f, "Direction can not be zero (or very close to zero), or non-finite." @@ -278,35 +278,35 @@ impl From for Vec2 { } } -impl std::ops::Deref for Dir2 { +impl core::ops::Deref for Dir2 { type Target = Vec2; fn deref(&self) -> &Self::Target { &self.0 } } -impl std::ops::Neg for Dir2 { +impl core::ops::Neg for Dir2 { type Output = Self; fn neg(self) -> Self::Output { Self(-self.0) } } -impl std::ops::Mul for Dir2 { +impl core::ops::Mul for Dir2 { type Output = Vec2; fn mul(self, rhs: f32) -> Self::Output { self.0 * rhs } } -impl std::ops::Mul for f32 { +impl core::ops::Mul for f32 { type Output = Vec2; fn mul(self, rhs: Dir2) -> Self::Output { self * rhs.0 } } -impl std::ops::Mul for Rot2 { +impl core::ops::Mul for Rot2 { type Output = Dir2; /// Rotates the [`Dir2`] using a [`Rot2`]. @@ -540,35 +540,35 @@ impl From for Vec3 { } } -impl std::ops::Deref for Dir3 { +impl core::ops::Deref for Dir3 { type Target = Vec3; fn deref(&self) -> &Self::Target { &self.0 } } -impl std::ops::Neg for Dir3 { +impl core::ops::Neg for Dir3 { type Output = Self; fn neg(self) -> Self::Output { Self(-self.0) } } -impl std::ops::Mul for Dir3 { +impl core::ops::Mul for Dir3 { type Output = Vec3; fn mul(self, rhs: f32) -> Self::Output { self.0 * rhs } } -impl std::ops::Mul for f32 { +impl core::ops::Mul for f32 { type Output = Vec3; fn mul(self, rhs: Dir3) -> Self::Output { self * rhs.0 } } -impl std::ops::Mul for Quat { +impl core::ops::Mul for Quat { type Output = Dir3; /// Rotates the [`Dir3`] using a [`Quat`]. @@ -781,35 +781,35 @@ impl From for Vec3A { } } -impl std::ops::Deref for Dir3A { +impl core::ops::Deref for Dir3A { type Target = Vec3A; fn deref(&self) -> &Self::Target { &self.0 } } -impl std::ops::Neg for Dir3A { +impl core::ops::Neg for Dir3A { type Output = Self; fn neg(self) -> Self::Output { Self(-self.0) } } -impl std::ops::Mul for Dir3A { +impl core::ops::Mul for Dir3A { type Output = Vec3A; fn mul(self, rhs: f32) -> Self::Output { self.0 * rhs } } -impl std::ops::Mul for f32 { +impl core::ops::Mul for f32 { type Output = Vec3A; fn mul(self, rhs: Dir3A) -> Self::Output { self * rhs.0 } } -impl std::ops::Mul for Quat { +impl core::ops::Mul for Quat { type Output = Dir3A; /// Rotates the [`Dir3A`] using a [`Quat`]. @@ -963,7 +963,7 @@ mod tests { // Test rotation assert!( - (Quat::from_rotation_z(std::f32::consts::FRAC_PI_2) * Dir3::X) + (Quat::from_rotation_z(core::f32::consts::FRAC_PI_2) * Dir3::X) .abs_diff_eq(Vec3::Y, 10e-6) ); } @@ -1034,7 +1034,7 @@ mod tests { // Test rotation assert!( - (Quat::from_rotation_z(std::f32::consts::FRAC_PI_2) * Dir3A::X) + (Quat::from_rotation_z(core::f32::consts::FRAC_PI_2) * Dir3A::X) .abs_diff_eq(Vec3A::Y, 10e-6) ); } diff --git a/crates/bevy_math/src/float_ord.rs b/crates/bevy_math/src/float_ord.rs index 63360449258d3..e53a083f773e6 100644 --- a/crates/bevy_math/src/float_ord.rs +++ b/crates/bevy_math/src/float_ord.rs @@ -1,4 +1,4 @@ -use std::{ +use core::{ cmp::Ordering, hash::{Hash, Hasher}, ops::Neg, diff --git a/crates/bevy_math/src/isometry.rs b/crates/bevy_math/src/isometry.rs index a6505eb846c5d..356b78738db05 100644 --- a/crates/bevy_math/src/isometry.rs +++ b/crates/bevy_math/src/isometry.rs @@ -1,7 +1,7 @@ //! Isometry types for expressing rigid motions in two and three dimensions. use crate::{Affine2, Affine3, Affine3A, Dir2, Dir3, Mat3, Mat3A, Quat, Rot2, Vec2, Vec3, Vec3A}; -use std::ops::Mul; +use core::ops::Mul; #[cfg(feature = "approx")] use approx::{AbsDiffEq, RelativeEq, UlpsEq}; @@ -286,7 +286,7 @@ impl UlpsEq for Isometry2d { /// /// ``` /// # use bevy_math::{Isometry3d, Quat, Vec3}; -/// # use core::f32::consts::FRAC_PI_2; +/// # use std::f32::consts::FRAC_PI_2; /// # /// let iso = Isometry3d::new(Vec3::new(2.0, 1.0, 3.0), Quat::from_rotation_z(FRAC_PI_2)); /// ``` @@ -295,7 +295,7 @@ impl UlpsEq for Isometry2d { /// /// ``` /// # use bevy_math::{Isometry3d, Quat, Vec3}; -/// # use core::f32::consts::FRAC_PI_2; +/// # use std::f32::consts::FRAC_PI_2; /// # /// let iso1 = Isometry3d::from_translation(Vec3::new(2.0, 1.0, 3.0)); /// let iso2 = Isometry3d::from_rotation(Quat::from_rotation_z(FRAC_PI_2)); @@ -306,7 +306,7 @@ impl UlpsEq for Isometry2d { /// ``` /// # use approx::assert_relative_eq; /// # use bevy_math::{Isometry3d, Quat, Vec3}; -/// # use core::f32::consts::FRAC_PI_2; +/// # use std::f32::consts::FRAC_PI_2; /// # /// let iso = Isometry3d::new(Vec3::new(2.0, 1.0, 3.0), Quat::from_rotation_z(FRAC_PI_2)); /// let point = Vec3::new(4.0, 4.0, 4.0); @@ -322,7 +322,7 @@ impl UlpsEq for Isometry2d { /// /// ``` /// # use bevy_math::{Isometry3d, Quat, Vec3}; -/// # use core::f32::consts::FRAC_PI_2; +/// # use std::f32::consts::FRAC_PI_2; /// # /// # let iso = Isometry3d::new(Vec3::new(2.0, 1.0, 3.0), Quat::from_rotation_z(FRAC_PI_2)); /// # let iso1 = Isometry3d::from_translation(Vec3::new(2.0, 1.0, 3.0)); @@ -336,7 +336,7 @@ impl UlpsEq for Isometry2d { /// /// ``` /// # use bevy_math::{Isometry3d, Quat, Vec3}; -/// # use core::f32::consts::FRAC_PI_2; +/// # use std::f32::consts::FRAC_PI_2; /// # /// let sphere_iso = Isometry3d::from_translation(Vec3::new(2.0, 1.0, 3.0)); /// let cuboid_iso = Isometry3d::from_rotation(Quat::from_rotation_z(FRAC_PI_2)); @@ -558,7 +558,7 @@ mod tests { use super::*; use crate::{vec2, vec3, vec3a}; use approx::assert_abs_diff_eq; - use std::f32::consts::{FRAC_PI_2, FRAC_PI_3}; + use core::f32::consts::{FRAC_PI_2, FRAC_PI_3}; #[test] fn mul_2d() { diff --git a/crates/bevy_math/src/lib.rs b/crates/bevy_math/src/lib.rs index 1020cb114cc07..984a068ff82a4 100644 --- a/crates/bevy_math/src/lib.rs +++ b/crates/bevy_math/src/lib.rs @@ -41,15 +41,14 @@ pub use ray::{Ray2d, Ray3d}; pub use rects::*; pub use rotation2d::Rot2; #[cfg(feature = "rand")] -pub use sampling::{FromRng, ShapeSample}; +pub use sampling::FromRng; +#[cfg(feature = "rand")] +pub use sampling::ShapeSample; /// The math prelude. /// /// This includes the most common types in this crate, re-exported for your convenience. pub mod prelude { - #[doc(hidden)] - #[cfg(feature = "rand")] - pub use crate::sampling::{FromRng, ShapeSample}; #[doc(hidden)] pub use crate::{ cubic_splines::{ @@ -65,6 +64,10 @@ pub mod prelude { Isometry3d, Mat2, Mat3, Mat4, Quat, Ray2d, Ray3d, Rect, Rot2, StableInterpolate, URect, UVec2, UVec3, UVec4, Vec2, Vec2Swizzles, Vec3, Vec3Swizzles, Vec4, Vec4Swizzles, }; + + #[doc(hidden)] + #[cfg(feature = "rand")] + pub use crate::sampling::{FromRng, ShapeSample}; } pub use glam::*; diff --git a/crates/bevy_math/src/primitives/dim2.rs b/crates/bevy_math/src/primitives/dim2.rs index f43541809b970..6e44d8bc045ec 100644 --- a/crates/bevy_math/src/primitives/dim2.rs +++ b/crates/bevy_math/src/primitives/dim2.rs @@ -1,4 +1,4 @@ -use std::f32::consts::{FRAC_1_SQRT_2, FRAC_PI_2, FRAC_PI_3, PI}; +use core::f32::consts::{FRAC_1_SQRT_2, FRAC_PI_2, FRAC_PI_3, PI}; use super::{Measured2d, Primitive2d, WindingOrder}; use crate::{ @@ -536,7 +536,7 @@ impl CircularSegment { #[cfg(test)] mod arc_tests { - use std::f32::consts::FRAC_PI_4; + use core::f32::consts::FRAC_PI_4; use approx::assert_abs_diff_eq; @@ -1041,7 +1041,7 @@ impl Rhombus { /// Create a new `Rhombus` from a given inradius with all inner angles equal. #[inline(always)] pub fn from_inradius(inradius: f32) -> Self { - let half_diagonal = inradius * 2.0 / std::f32::consts::SQRT_2; + let half_diagonal = inradius * 2.0 / core::f32::consts::SQRT_2; Self { half_diagonals: Vec2::new(half_diagonal, half_diagonal), } @@ -1749,7 +1749,7 @@ impl RegularPolygon { pub fn vertices(self, rotation: f32) -> impl IntoIterator { // Add pi/2 so that the polygon has a vertex at the top (sin is 1.0 and cos is 0.0) let start_angle = rotation + FRAC_PI_2; - let step = std::f32::consts::TAU / self.sides as f32; + let step = core::f32::consts::TAU / self.sides as f32; (0..self.sides).map(move |i| { let theta = start_angle + i as f32 * step; @@ -1915,7 +1915,7 @@ mod tests { assert_eq!(rhombus.side(), 0.0, "incorrect side"); assert_eq!(rhombus.inradius(), 0.0, "incorrect inradius"); assert_eq!(rhombus.circumradius(), 0.0, "incorrect circumradius"); - let rhombus = Rhombus::from_side(std::f32::consts::SQRT_2); + let rhombus = Rhombus::from_side(core::f32::consts::SQRT_2); assert_abs_diff_eq!(rhombus.half_diagonals, Vec2::new(1.0, 1.0)); assert_abs_diff_eq!( rhombus.half_diagonals, @@ -2069,7 +2069,7 @@ mod tests { assert!((vertices.next().unwrap() - Vec2::Y).length() < 1e-7); // Rotate by 45 degrees, forming an axis-aligned square - let mut rotated_vertices = polygon.vertices(std::f32::consts::FRAC_PI_4).into_iter(); + let mut rotated_vertices = polygon.vertices(core::f32::consts::FRAC_PI_4).into_iter(); // Distance from the origin to the middle of a side, derived using Pythagorean theorem let side_sistance = FRAC_1_SQRT_2; diff --git a/crates/bevy_math/src/primitives/dim3.rs b/crates/bevy_math/src/primitives/dim3.rs index 7ee6a82d6f241..d3761455d8cf2 100644 --- a/crates/bevy_math/src/primitives/dim3.rs +++ b/crates/bevy_math/src/primitives/dim3.rs @@ -1,4 +1,4 @@ -use std::f32::consts::{FRAC_PI_3, PI}; +use core::f32::consts::{FRAC_PI_3, PI}; use super::{Circle, Measured2d, Measured3d, Primitive2d, Primitive3d}; use crate::{ops, ops::FloatPow, Dir3, InvalidDirectionError, Isometry3d, Mat3, Vec2, Vec3}; @@ -187,7 +187,7 @@ impl InfinitePlane3d { #[inline(always)] pub fn new>(normal: T) -> Self where - >::Error: std::fmt::Debug, + >::Error: core::fmt::Debug, { Self { normal: normal @@ -926,9 +926,9 @@ impl Torus { } match self.major_radius.partial_cmp(&self.minor_radius).unwrap() { - std::cmp::Ordering::Greater => TorusKind::Ring, - std::cmp::Ordering::Equal => TorusKind::Horn, - std::cmp::Ordering::Less => TorusKind::Spindle, + core::cmp::Ordering::Greater => TorusKind::Ring, + core::cmp::Ordering::Equal => TorusKind::Horn, + core::cmp::Ordering::Less => TorusKind::Spindle, } } } @@ -1320,7 +1320,7 @@ mod tests { // Test rotation assert!( - (Quat::from_rotation_z(std::f32::consts::FRAC_PI_2) * Dir3::X) + (Quat::from_rotation_z(core::f32::consts::FRAC_PI_2) * Dir3::X) .abs_diff_eq(Vec3::Y, 10e-6) ); } diff --git a/crates/bevy_math/src/primitives/serde.rs b/crates/bevy_math/src/primitives/serde.rs index 79abb778cd39d..bdbf72f69e737 100644 --- a/crates/bevy_math/src/primitives/serde.rs +++ b/crates/bevy_math/src/primitives/serde.rs @@ -4,12 +4,12 @@ //! pub(crate) mod array { + use core::marker::PhantomData; use serde::{ de::{SeqAccess, Visitor}, ser::SerializeTuple, Deserialize, Deserializer, Serialize, Serializer, }; - use std::marker::PhantomData; pub fn serialize( data: &[T; N], @@ -30,7 +30,7 @@ pub(crate) mod array { { type Value = [T; N]; - fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result { formatter.write_str(&format!("an array of length {}", N)) } diff --git a/crates/bevy_math/src/rotation2d.rs b/crates/bevy_math/src/rotation2d.rs index 51290241baad0..d4df9548f5741 100644 --- a/crates/bevy_math/src/rotation2d.rs +++ b/crates/bevy_math/src/rotation2d.rs @@ -1,4 +1,4 @@ -use std::f32::consts::TAU; +use core::f32::consts::TAU; use glam::FloatExt; @@ -442,7 +442,7 @@ impl From for Mat2 { } } -impl std::ops::Mul for Rot2 { +impl core::ops::Mul for Rot2 { type Output = Self; fn mul(self, rhs: Self) -> Self::Output { @@ -453,13 +453,13 @@ impl std::ops::Mul for Rot2 { } } -impl std::ops::MulAssign for Rot2 { +impl core::ops::MulAssign for Rot2 { fn mul_assign(&mut self, rhs: Self) { *self = *self * rhs; } } -impl std::ops::Mul for Rot2 { +impl core::ops::Mul for Rot2 { type Output = Vec2; /// Rotates a [`Vec2`] by a [`Rot2`]. @@ -506,7 +506,7 @@ impl approx::UlpsEq for Rot2 { #[cfg(test)] mod tests { - use std::f32::consts::FRAC_PI_2; + use core::f32::consts::FRAC_PI_2; use approx::assert_relative_eq; @@ -569,7 +569,7 @@ mod tests { // This should be equivalent to the above assert_relative_eq!( rotation2.angle_between(rotation1), - std::f32::consts::FRAC_PI_4 + core::f32::consts::FRAC_PI_4 ); } diff --git a/crates/bevy_math/src/sampling/shape_sampling.rs b/crates/bevy_math/src/sampling/shape_sampling.rs index 10d99f8a8b16d..7e8c672a6bf7c 100644 --- a/crates/bevy_math/src/sampling/shape_sampling.rs +++ b/crates/bevy_math/src/sampling/shape_sampling.rs @@ -38,7 +38,7 @@ //! //! In any case, the [`Rng`] used as the source of randomness must be provided explicitly. -use std::f32::consts::{PI, TAU}; +use core::f32::consts::{PI, TAU}; use crate::{ops, primitives::*, NormedVectorSpace, Vec2, Vec3}; use rand::{ diff --git a/crates/bevy_math/src/sampling/standard.rs b/crates/bevy_math/src/sampling/standard.rs index 9c5ff1fa3dea4..6750d5c6d5fac 100644 --- a/crates/bevy_math/src/sampling/standard.rs +++ b/crates/bevy_math/src/sampling/standard.rs @@ -21,7 +21,7 @@ //! let many_random_directions: Vec = rng.sample_iter(Standard).take(5).collect(); //! ``` -use std::f32::consts::TAU; +use core::f32::consts::TAU; use crate::{ primitives::{Circle, Sphere}, diff --git a/crates/bevy_mikktspace/src/generated.rs b/crates/bevy_mikktspace/src/generated.rs index 2589e3930b1a4..b4bf42275a66c 100644 --- a/crates/bevy_mikktspace/src/generated.rs +++ b/crates/bevy_mikktspace/src/generated.rs @@ -45,7 +45,7 @@ unsafe_code )] -use std::ptr::{self, null_mut}; +use core::ptr::{self, null_mut}; use glam::Vec3; diff --git a/crates/bevy_pbr/src/cluster/assign.rs b/crates/bevy_pbr/src/cluster/assign.rs index 1f3f1bc52d792..d1dcdb8fc54d8 100644 --- a/crates/bevy_pbr/src/cluster/assign.rs +++ b/crates/bevy_pbr/src/cluster/assign.rs @@ -360,7 +360,7 @@ pub(crate) fn assign_objects_to_clusters( // initialize empty cluster bounding spheres cluster_aabb_spheres.clear(); - cluster_aabb_spheres.extend(std::iter::repeat(None).take(cluster_count)); + cluster_aabb_spheres.extend(core::iter::repeat(None).take(cluster_count)); // Calculate the x/y/z cluster frustum planes in view space let mut x_planes = Vec::with_capacity(clusters.dimensions.x as usize + 1); diff --git a/crates/bevy_pbr/src/cluster/mod.rs b/crates/bevy_pbr/src/cluster/mod.rs index add1b38850b54..f21781e147232 100644 --- a/crates/bevy_pbr/src/cluster/mod.rs +++ b/crates/bevy_pbr/src/cluster/mod.rs @@ -1,6 +1,6 @@ //! Spatial clustering of objects, currently just point and spot lights. -use std::num::NonZero; +use core::num::NonZero; use bevy_core_pipeline::core_3d::Camera3d; use bevy_ecs::{ @@ -507,7 +507,7 @@ impl Default for GpuClusterableObjectsUniform { pub(crate) fn clusterable_object_order( (entity_1, shadows_enabled_1, is_spot_light_1): (&Entity, &bool, &bool), (entity_2, shadows_enabled_2, is_spot_light_2): (&Entity, &bool, &bool), -) -> std::cmp::Ordering { +) -> core::cmp::Ordering { is_spot_light_1 .cmp(is_spot_light_2) // pointlights before spot lights .then_with(|| shadows_enabled_2.cmp(shadows_enabled_1)) // shadow casters before non-casters diff --git a/crates/bevy_pbr/src/fog.rs b/crates/bevy_pbr/src/fog.rs index 5f4738d619bea..c2ff30bb56411 100644 --- a/crates/bevy_pbr/src/fog.rs +++ b/crates/bevy_pbr/src/fog.rs @@ -409,7 +409,7 @@ impl FogFalloff { extinction_color: Color, inscattering_color: Color, ) -> FogFalloff { - use std::f32::consts::E; + use core::f32::consts::E; let [r_e, g_e, b_e, a_e] = LinearRgba::from(extinction_color).to_f32_array(); let [r_i, g_i, b_i, a_i] = LinearRgba::from(inscattering_color).to_f32_array(); diff --git a/crates/bevy_pbr/src/lib.rs b/crates/bevy_pbr/src/lib.rs index 59cdf3e33bb88..feb6b3d4fccf0 100644 --- a/crates/bevy_pbr/src/lib.rs +++ b/crates/bevy_pbr/src/lib.rs @@ -7,6 +7,8 @@ html_favicon_url = "https://bevyengine.org/assets/icon.png" )] +extern crate alloc; + #[cfg(feature = "meshlet")] mod meshlet; pub mod wireframe; @@ -41,7 +43,7 @@ mod ssr; mod volumetric_fog; use bevy_color::{Color, LinearRgba}; -use std::marker::PhantomData; +use core::marker::PhantomData; pub use bundle::*; pub use cluster::*; diff --git a/crates/bevy_pbr/src/light/mod.rs b/crates/bevy_pbr/src/light/mod.rs index 8bf10e34752fc..e7477a5a23639 100644 --- a/crates/bevy_pbr/src/light/mod.rs +++ b/crates/bevy_pbr/src/light/mod.rs @@ -1,4 +1,4 @@ -use std::ops::DerefMut; +use core::ops::DerefMut; use bevy_ecs::{entity::EntityHashMap, prelude::*}; use bevy_math::{ops, Mat4, Vec3A, Vec4}; @@ -527,7 +527,7 @@ pub enum SimulationLightSystems { pub(crate) fn directional_light_order( (entity_1, volumetric_1, shadows_enabled_1): (&Entity, &bool, &bool), (entity_2, volumetric_2, shadows_enabled_2): (&Entity, &bool, &bool), -) -> std::cmp::Ordering { +) -> core::cmp::Ordering { volumetric_2 .cmp(volumetric_1) // volumetric before shadows .then_with(|| shadows_enabled_2.cmp(shadows_enabled_1)) // shadow casters before non-casters @@ -596,7 +596,7 @@ pub fn update_point_light_frusta( } let clip_from_view = Mat4::perspective_infinite_reverse_rh( - std::f32::consts::FRAC_PI_2, + core::f32::consts::FRAC_PI_2, 1.0, point_light.shadow_map_near_z, ); @@ -824,7 +824,7 @@ pub fn check_dir_light_mesh_visibility( // Defer marking view visibility so this system can run in parallel with check_point_light_mesh_visibility // TODO: use resource to avoid unnecessary memory alloc - let mut defer_queue = std::mem::take(defer_visible_entities_queue.deref_mut()); + let mut defer_queue = core::mem::take(defer_visible_entities_queue.deref_mut()); commands.queue(move |world: &mut World| { let mut query = world.query::<&mut ViewVisibility>(); for entities in defer_queue.iter_mut() { diff --git a/crates/bevy_pbr/src/light/spot_light.rs b/crates/bevy_pbr/src/light/spot_light.rs index 88c69995cf026..b8d98c7b338ef 100644 --- a/crates/bevy_pbr/src/light/spot_light.rs +++ b/crates/bevy_pbr/src/light/spot_light.rs @@ -117,7 +117,7 @@ impl Default for SpotLight { shadow_normal_bias: Self::DEFAULT_SHADOW_NORMAL_BIAS, shadow_map_near_z: Self::DEFAULT_SHADOW_MAP_NEAR_Z, inner_angle: 0.0, - outer_angle: std::f32::consts::FRAC_PI_4, + outer_angle: core::f32::consts::FRAC_PI_4, } } } diff --git a/crates/bevy_pbr/src/light_probe/environment_map.rs b/crates/bevy_pbr/src/light_probe/environment_map.rs index f60a8b34f3d84..c366d02b59bb6 100644 --- a/crates/bevy_pbr/src/light_probe/environment_map.rs +++ b/crates/bevy_pbr/src/light_probe/environment_map.rs @@ -66,7 +66,7 @@ use bevy_render::{ texture::{FallbackImage, GpuImage, Image}, }; -use std::{num::NonZero, ops::Deref}; +use core::{num::NonZero, ops::Deref}; use crate::{ add_cubemap_texture_view, binding_arrays_are_usable, EnvironmentMapUniform, LightProbe, diff --git a/crates/bevy_pbr/src/light_probe/irradiance_volume.rs b/crates/bevy_pbr/src/light_probe/irradiance_volume.rs index 8a4e4c2402b18..f43d84d4e7c39 100644 --- a/crates/bevy_pbr/src/light_probe/irradiance_volume.rs +++ b/crates/bevy_pbr/src/light_probe/irradiance_volume.rs @@ -142,7 +142,7 @@ use bevy_render::{ renderer::RenderDevice, texture::{FallbackImage, GpuImage, Image}, }; -use std::{num::NonZero, ops::Deref}; +use core::{num::NonZero, ops::Deref}; use bevy_asset::{AssetId, Handle}; use bevy_reflect::{std_traits::ReflectDefault, Reflect}; diff --git a/crates/bevy_pbr/src/light_probe/mod.rs b/crates/bevy_pbr/src/light_probe/mod.rs index 0a35aee1a2303..f110dc6f82c2f 100644 --- a/crates/bevy_pbr/src/light_probe/mod.rs +++ b/crates/bevy_pbr/src/light_probe/mod.rs @@ -28,7 +28,7 @@ use bevy_render::{ use bevy_transform::{components::Transform, prelude::GlobalTransform}; use bevy_utils::{tracing::error, HashMap}; -use std::{hash::Hash, ops::Deref}; +use core::{hash::Hash, ops::Deref}; use crate::{ irradiance_volume::IRRADIANCE_VOLUME_SHADER_HANDLE, diff --git a/crates/bevy_pbr/src/material.rs b/crates/bevy_pbr/src/material.rs index c4edd1101c624..7dff0a7d56a8b 100644 --- a/crates/bevy_pbr/src/material.rs +++ b/crates/bevy_pbr/src/material.rs @@ -20,7 +20,8 @@ use bevy_ecs::{ prelude::*, system::{lifetimeless::SRes, SystemParamItem}, }; -use bevy_reflect::{std_traits::ReflectDefault, Reflect}; +use bevy_reflect::std_traits::ReflectDefault; +use bevy_reflect::Reflect; use bevy_render::{ camera::TemporalJitter, extract_instances::{ExtractInstancesPlugin, ExtractedInstances}, @@ -33,7 +34,7 @@ use bevy_render::{ view::{ExtractedView, Msaa, RenderVisibilityRanges, VisibleEntities, WithMesh}, }; use bevy_utils::tracing::error; -use std::{ +use core::{ hash::Hash, marker::PhantomData, num::NonZero, @@ -350,7 +351,7 @@ impl Hash for MaterialPipelineKey where M::Data: Hash, { - fn hash(&self, state: &mut H) { + fn hash(&self, state: &mut H) { self.mesh_key.hash(state); self.bind_group_data.hash(state); } diff --git a/crates/bevy_pbr/src/meshlet/asset.rs b/crates/bevy_pbr/src/meshlet/asset.rs index 108cf981515c7..6daf1ba4d5f30 100644 --- a/crates/bevy_pbr/src/meshlet/asset.rs +++ b/crates/bevy_pbr/src/meshlet/asset.rs @@ -1,3 +1,4 @@ +use alloc::sync::Arc; use bevy_asset::{ io::{Reader, Writer}, saver::{AssetSaver, SavedAsset}, @@ -8,10 +9,7 @@ use bevy_reflect::TypePath; use bevy_tasks::block_on; use bytemuck::{Pod, Zeroable}; use lz4_flex::frame::{FrameDecoder, FrameEncoder}; -use std::{ - io::{Read, Write}, - sync::Arc, -}; +use std::io::{Read, Write}; /// Unique identifier for the [`MeshletMesh`] asset format. const MESHLET_MESH_ASSET_MAGIC: u64 = 1717551717668; @@ -200,7 +198,7 @@ fn write_slice( fn read_slice(reader: &mut dyn Read) -> Result, std::io::Error> { let len = read_u64(reader)? as usize; - let mut data: Arc<[T]> = std::iter::repeat_with(T::zeroed).take(len).collect(); + let mut data: Arc<[T]> = core::iter::repeat_with(T::zeroed).take(len).collect(); let slice = Arc::get_mut(&mut data).unwrap(); reader.read_exact(bytemuck::cast_slice_mut(slice))?; diff --git a/crates/bevy_pbr/src/meshlet/from_mesh.rs b/crates/bevy_pbr/src/meshlet/from_mesh.rs index aa132e14415a5..d085db86ba18d 100644 --- a/crates/bevy_pbr/src/meshlet/from_mesh.rs +++ b/crates/bevy_pbr/src/meshlet/from_mesh.rs @@ -1,9 +1,11 @@ use super::asset::{Meshlet, MeshletBoundingSphere, MeshletBoundingSpheres, MeshletMesh}; +use alloc::borrow::Cow; use bevy_render::{ mesh::{Indices, Mesh}, render_resource::PrimitiveTopology, }; use bevy_utils::HashMap; +use core::ops::Range; use itertools::Itertools; use meshopt::{ build_meshlets, compute_cluster_bounds, compute_meshlet_bounds, ffi::meshopt_Bounds, simplify, @@ -11,7 +13,6 @@ use meshopt::{ }; use metis::Graph; use smallvec::SmallVec; -use std::{borrow::Cow, ops::Range}; impl MeshletMesh { /// Process a [`Mesh`] to generate a [`MeshletMesh`]. diff --git a/crates/bevy_pbr/src/meshlet/instance_manager.rs b/crates/bevy_pbr/src/meshlet/instance_manager.rs index 0f370f2200459..161cbf7f8b963 100644 --- a/crates/bevy_pbr/src/meshlet/instance_manager.rs +++ b/crates/bevy_pbr/src/meshlet/instance_manager.rs @@ -13,7 +13,7 @@ use bevy_ecs::{ use bevy_render::{render_resource::StorageBuffer, view::RenderLayers, MainWorld}; use bevy_transform::components::GlobalTransform; use bevy_utils::{HashMap, HashSet}; -use std::ops::{DerefMut, Range}; +use core::ops::{DerefMut, Range}; /// Manages data for each entity with a [`MeshletMesh`]. #[derive(Resource)] diff --git a/crates/bevy_pbr/src/meshlet/material_pipeline_prepare.rs b/crates/bevy_pbr/src/meshlet/material_pipeline_prepare.rs index 6a0f093d815c3..b1b91e8cc5c6a 100644 --- a/crates/bevy_pbr/src/meshlet/material_pipeline_prepare.rs +++ b/crates/bevy_pbr/src/meshlet/material_pipeline_prepare.rs @@ -18,7 +18,7 @@ use bevy_render::{ view::ExtractedView, }; use bevy_utils::{HashMap, HashSet}; -use std::hash::Hash; +use core::hash::Hash; /// A list of `(Material ID, Pipeline, BindGroup)` for a view for use in [`super::MeshletMainOpaquePass3dNode`]. #[derive(Component, Deref, DerefMut, Default)] diff --git a/crates/bevy_pbr/src/meshlet/meshlet_mesh_manager.rs b/crates/bevy_pbr/src/meshlet/meshlet_mesh_manager.rs index 7c25be7529759..09e065b019f45 100644 --- a/crates/bevy_pbr/src/meshlet/meshlet_mesh_manager.rs +++ b/crates/bevy_pbr/src/meshlet/meshlet_mesh_manager.rs @@ -3,6 +3,7 @@ use super::{ persistent_buffer::PersistentGpuBuffer, MeshletMesh, }; +use alloc::sync::Arc; use bevy_asset::{AssetId, Assets}; use bevy_ecs::{ system::{Res, ResMut, Resource}, @@ -13,7 +14,7 @@ use bevy_render::{ renderer::{RenderDevice, RenderQueue}, }; use bevy_utils::HashMap; -use std::{ops::Range, sync::Arc}; +use core::ops::Range; /// Manages uploading [`MeshletMesh`] asset data to the GPU. #[derive(Resource)] diff --git a/crates/bevy_pbr/src/meshlet/persistent_buffer.rs b/crates/bevy_pbr/src/meshlet/persistent_buffer.rs index e10dad6ef0aed..85dec457f9808 100644 --- a/crates/bevy_pbr/src/meshlet/persistent_buffer.rs +++ b/crates/bevy_pbr/src/meshlet/persistent_buffer.rs @@ -5,8 +5,8 @@ use bevy_render::{ }, renderer::{RenderDevice, RenderQueue}, }; +use core::{num::NonZero, ops::Range}; use range_alloc::RangeAllocator; -use std::{num::NonZero, ops::Range}; /// Wrapper for a GPU buffer holding a large amount of data that persists across frames. pub struct PersistentGpuBuffer { diff --git a/crates/bevy_pbr/src/meshlet/persistent_buffer_impls.rs b/crates/bevy_pbr/src/meshlet/persistent_buffer_impls.rs index 175fbe75143f5..bd15e4c42c477 100644 --- a/crates/bevy_pbr/src/meshlet/persistent_buffer_impls.rs +++ b/crates/bevy_pbr/src/meshlet/persistent_buffer_impls.rs @@ -2,7 +2,7 @@ use super::{ asset::{Meshlet, MeshletBoundingSpheres}, persistent_buffer::PersistentGpuBufferable, }; -use std::sync::Arc; +use alloc::sync::Arc; const MESHLET_VERTEX_SIZE_IN_BYTES: u32 = 48; diff --git a/crates/bevy_pbr/src/meshlet/resource_manager.rs b/crates/bevy_pbr/src/meshlet/resource_manager.rs index 4df1fb8fd3e05..aca52d133364b 100644 --- a/crates/bevy_pbr/src/meshlet/resource_manager.rs +++ b/crates/bevy_pbr/src/meshlet/resource_manager.rs @@ -1,5 +1,6 @@ use super::{instance_manager::InstanceManager, meshlet_mesh_manager::MeshletMeshManager}; use crate::ShadowView; +use alloc::sync::Arc; use bevy_core_pipeline::{ core_3d::Camera3d, prepass::{PreviousViewData, PreviousViewUniforms}, @@ -18,11 +19,8 @@ use bevy_render::{ view::{ExtractedView, RenderLayers, ViewUniform, ViewUniforms}, }; use binding_types::*; +use core::{array, iter, sync::atomic::AtomicBool}; use encase::internal::WriteInto; -use std::{ - array, iter, - sync::{atomic::AtomicBool, Arc}, -}; /// Manages per-view and per-cluster GPU resources for [`super::MeshletPlugin`]. #[derive(Resource)] diff --git a/crates/bevy_pbr/src/meshlet/visibility_buffer_raster_node.rs b/crates/bevy_pbr/src/meshlet/visibility_buffer_raster_node.rs index e05956fc80789..3dceb239ccda3 100644 --- a/crates/bevy_pbr/src/meshlet/visibility_buffer_raster_node.rs +++ b/crates/bevy_pbr/src/meshlet/visibility_buffer_raster_node.rs @@ -17,7 +17,7 @@ use bevy_render::{ renderer::RenderContext, view::{ViewDepthTexture, ViewUniformOffset}, }; -use std::sync::atomic::Ordering; +use core::sync::atomic::Ordering; /// Rasterize meshlets into a depth buffer, and optional visibility buffer + material depth buffer for shading passes. pub struct MeshletVisibilityBufferRasterPassNode { diff --git a/crates/bevy_pbr/src/prepass/mod.rs b/crates/bevy_pbr/src/prepass/mod.rs index 5ac73690b392c..6cf3d8f6419f1 100644 --- a/crates/bevy_pbr/src/prepass/mod.rs +++ b/crates/bevy_pbr/src/prepass/mod.rs @@ -39,7 +39,7 @@ use crate::meshlet::{ }; use crate::*; -use std::{hash::Hash, marker::PhantomData}; +use core::{hash::Hash, marker::PhantomData}; pub const PREPASS_SHADER_HANDLE: Handle = Handle::weak_from_u128(921124473254008983); diff --git a/crates/bevy_pbr/src/render/gpu_preprocess.rs b/crates/bevy_pbr/src/render/gpu_preprocess.rs index 502b2e7210efc..3db9508c17b65 100644 --- a/crates/bevy_pbr/src/render/gpu_preprocess.rs +++ b/crates/bevy_pbr/src/render/gpu_preprocess.rs @@ -6,7 +6,7 @@ //! [`MeshInputUniform`]s instead and use the GPU to calculate the remaining //! derived fields in [`MeshUniform`]. -use std::num::NonZero; +use core::num::NonZero; use bevy_app::{App, Plugin}; use bevy_asset::{load_internal_asset, Handle}; diff --git a/crates/bevy_pbr/src/render/light.rs b/crates/bevy_pbr/src/render/light.rs index aa8fd87f97e24..f15c8bc38f55b 100644 --- a/crates/bevy_pbr/src/render/light.rs +++ b/crates/bevy_pbr/src/render/light.rs @@ -24,10 +24,10 @@ use bevy_transform::{components::GlobalTransform, prelude::Transform}; #[cfg(feature = "trace")] use bevy_utils::tracing::info_span; use bevy_utils::{ - prelude::default, + default, tracing::{error, warn}, }; -use std::{hash::Hash, ops::Range}; +use core::{hash::Hash, ops::Range}; use crate::*; @@ -261,7 +261,7 @@ pub fn extract_lights( // NOTE: Map from luminous power in lumens to luminous intensity in lumens per steradian // for a point light. See https://google.github.io/filament/Filament.html#mjx-eqn-pointLightLuminousPower // for details. - intensity: point_light.intensity / (4.0 * std::f32::consts::PI), + intensity: point_light.intensity / (4.0 * core::f32::consts::PI), range: point_light.range, radius: point_light.radius, transform: *transform, @@ -271,7 +271,7 @@ pub fn extract_lights( // The factor of SQRT_2 is for the worst-case diagonal offset shadow_normal_bias: point_light.shadow_normal_bias * point_light_texel_size - * std::f32::consts::SQRT_2, + * core::f32::consts::SQRT_2, shadow_map_near_z: point_light.shadow_map_near_z, spot_light_angles: None, }; @@ -312,7 +312,7 @@ pub fn extract_lights( // Note: Filament uses a divisor of PI for spot lights. We choose to use the same 4*PI divisor // in both cases so that toggling between point light and spot light keeps lit areas lit equally, // which seems least surprising for users - intensity: spot_light.intensity / (4.0 * std::f32::consts::PI), + intensity: spot_light.intensity / (4.0 * core::f32::consts::PI), range: spot_light.range, radius: spot_light.radius, transform: *transform, @@ -322,7 +322,7 @@ pub fn extract_lights( // The factor of SQRT_2 is for the worst-case diagonal offset shadow_normal_bias: spot_light.shadow_normal_bias * texel_size - * std::f32::consts::SQRT_2, + * core::f32::consts::SQRT_2, shadow_map_near_z: spot_light.shadow_map_near_z, spot_light_angles: Some((spot_light.inner_angle, spot_light.outer_angle)), }, @@ -364,7 +364,8 @@ pub fn extract_lights( shadows_enabled: directional_light.shadows_enabled, shadow_depth_bias: directional_light.shadow_depth_bias, // The factor of SQRT_2 is for the worst-case diagonal offset - shadow_normal_bias: directional_light.shadow_normal_bias * std::f32::consts::SQRT_2, + shadow_normal_bias: directional_light.shadow_normal_bias + * core::f32::consts::SQRT_2, cascade_shadow_config: cascade_config.clone(), cascades: cascades.cascades.clone(), frusta: frusta.frusta.clone(), @@ -701,7 +702,7 @@ pub fn prepare_lights( } let cube_face_projection = Mat4::perspective_infinite_reverse_rh( - std::f32::consts::FRAC_PI_2, + core::f32::consts::FRAC_PI_2, 1.0, light.shadow_map_near_z, ); @@ -909,7 +910,7 @@ pub fn prepare_lights( let view_translation = GlobalTransform::from_translation(light.transform.translation()); let cube_face_projection = Mat4::perspective_infinite_reverse_rh( - std::f32::consts::FRAC_PI_2, + core::f32::consts::FRAC_PI_2, 1.0, light.shadow_map_near_z, ); diff --git a/crates/bevy_pbr/src/render/mesh.rs b/crates/bevy_pbr/src/render/mesh.rs index 27d543a061cd0..c1c9a29129563 100644 --- a/crates/bevy_pbr/src/render/mesh.rs +++ b/crates/bevy_pbr/src/render/mesh.rs @@ -1,4 +1,4 @@ -use std::mem::{self, size_of}; +use core::mem::{self, size_of}; use allocator::MeshAllocator; use bevy_asset::{load_internal_asset, AssetId}; diff --git a/crates/bevy_pbr/src/render/mesh_view_bindings.rs b/crates/bevy_pbr/src/render/mesh_view_bindings.rs index 9446b3c9a9180..f44999b8b6499 100644 --- a/crates/bevy_pbr/src/render/mesh_view_bindings.rs +++ b/crates/bevy_pbr/src/render/mesh_view_bindings.rs @@ -1,4 +1,5 @@ -use std::{array, num::NonZero, sync::Arc}; +use alloc::sync::Arc; +use core::{array, num::NonZero}; use bevy_core_pipeline::{ core_3d::ViewTransmissionTexture, diff --git a/crates/bevy_pbr/src/render/morph.rs b/crates/bevy_pbr/src/render/morph.rs index 259481e379053..c2696652a7a2f 100644 --- a/crates/bevy_pbr/src/render/morph.rs +++ b/crates/bevy_pbr/src/render/morph.rs @@ -1,4 +1,4 @@ -use std::{iter, mem}; +use core::{iter, mem}; use bevy_ecs::{entity::EntityHashMap, prelude::*}; use bevy_render::{ @@ -88,7 +88,7 @@ fn add_to_alignment(buffer: &mut RawBufferVec) { panic!( "RawBufferVec should contain only types with a size multiple or divisible by {n}, \ {} has a size of {t_size}, which is neither multiple or divisible by {n}", - std::any::type_name::() + core::any::type_name::() ); } diff --git a/crates/bevy_pbr/src/render/skin.rs b/crates/bevy_pbr/src/render/skin.rs index eea4c7a8437f6..1719789d55420 100644 --- a/crates/bevy_pbr/src/render/skin.rs +++ b/crates/bevy_pbr/src/render/skin.rs @@ -1,4 +1,4 @@ -use std::mem::{self, size_of}; +use core::mem::{self, size_of}; use bevy_asset::Assets; use bevy_ecs::{entity::EntityHashMap, prelude::*}; diff --git a/crates/bevy_pbr/src/ssao/mod.rs b/crates/bevy_pbr/src/ssao/mod.rs index eff2ec733b40c..ffbd7584583af 100644 --- a/crates/bevy_pbr/src/ssao/mod.rs +++ b/crates/bevy_pbr/src/ssao/mod.rs @@ -36,7 +36,7 @@ use bevy_utils::{ prelude::default, tracing::{error, warn}, }; -use std::mem; +use core::mem; const PREPROCESS_DEPTH_SHADER_HANDLE: Handle = Handle::weak_from_u128(102258915420479); const GTAO_SHADER_HANDLE: Handle = Handle::weak_from_u128(253938746510568); diff --git a/crates/bevy_pbr/src/volumetric_fog/render.rs b/crates/bevy_pbr/src/volumetric_fog/render.rs index 9a35a92eae31c..126d2fddf7dd3 100644 --- a/crates/bevy_pbr/src/volumetric_fog/render.rs +++ b/crates/bevy_pbr/src/volumetric_fog/render.rs @@ -1,6 +1,6 @@ //! Rendering of fog volumes. -use std::array; +use core::array; use bevy_asset::{AssetId, Handle}; use bevy_color::ColorToComponents as _; diff --git a/crates/bevy_picking/src/events.rs b/crates/bevy_picking/src/events.rs index 56f10c24cb881..c61ca42aea4c9 100644 --- a/crates/bevy_picking/src/events.rs +++ b/crates/bevy_picking/src/events.rs @@ -37,7 +37,7 @@ //! When received by an observer, these events will always be wrapped by the [`Pointer`] type, which contains //! general metadata about the pointer and it's location. -use std::fmt::Debug; +use core::fmt::Debug; use bevy_ecs::prelude::*; use bevy_hierarchy::Parent; @@ -78,8 +78,8 @@ where const AUTO_PROPAGATE: bool = true; } -impl std::fmt::Display for Pointer { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl core::fmt::Display for Pointer { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { f.write_fmt(format_args!( "{:?}, {:.1?}, {:.1?}", self.pointer_id, self.pointer_location.position, self.event @@ -87,7 +87,7 @@ impl std::fmt::Display for Pointer { } } -impl std::ops::Deref for Pointer { +impl core::ops::Deref for Pointer { type Target = E; fn deref(&self) -> &Self::Target { diff --git a/crates/bevy_picking/src/focus.rs b/crates/bevy_picking/src/focus.rs index 3d10019401736..6d9a5d1c95799 100644 --- a/crates/bevy_picking/src/focus.rs +++ b/crates/bevy_picking/src/focus.rs @@ -3,10 +3,9 @@ //! The most important type in this module is the [`HoverMap`], which maps pointers to the entities //! they are hovering over. -use std::{ - collections::{BTreeMap, HashSet}, - fmt::Debug, -}; +use alloc::collections::BTreeMap; +use core::fmt::Debug; +use std::collections::HashSet; use crate::{ backend::{self, HitData}, diff --git a/crates/bevy_picking/src/lib.rs b/crates/bevy_picking/src/lib.rs index 4f38d3454d04a..68441496707aa 100644 --- a/crates/bevy_picking/src/lib.rs +++ b/crates/bevy_picking/src/lib.rs @@ -150,6 +150,8 @@ #![deny(missing_docs)] +extern crate alloc; + pub mod backend; pub mod events; pub mod focus; diff --git a/crates/bevy_picking/src/pointer.rs b/crates/bevy_picking/src/pointer.rs index 4dbeb46146b7d..ee04fc732c880 100644 --- a/crates/bevy_picking/src/pointer.rs +++ b/crates/bevy_picking/src/pointer.rs @@ -17,7 +17,7 @@ use bevy_window::PrimaryWindow; use uuid::Uuid; -use std::fmt::Debug; +use core::fmt::Debug; use crate::backend::HitData; diff --git a/crates/bevy_ptr/src/lib.rs b/crates/bevy_ptr/src/lib.rs index bab0cec5fb49d..d1eed83907da4 100644 --- a/crates/bevy_ptr/src/lib.rs +++ b/crates/bevy_ptr/src/lib.rs @@ -53,7 +53,7 @@ impl ConstNonNull { /// let x = 0u32; /// let ptr = ConstNonNull::::new(&x as *const _).expect("ptr is null!"); /// - /// if let Some(ptr) = ConstNonNull::::new(std::ptr::null()) { + /// if let Some(ptr) = ConstNonNull::::new(core::ptr::null()) { /// unreachable!(); /// } /// ``` @@ -82,7 +82,7 @@ impl ConstNonNull { /// use bevy_ptr::ConstNonNull; /// /// // NEVER DO THAT!!! This is undefined behavior. ⚠️ - /// let ptr = unsafe { ConstNonNull::::new_unchecked(std::ptr::null()) }; + /// let ptr = unsafe { ConstNonNull::::new_unchecked(core::ptr::null()) }; /// ``` pub const unsafe fn new_unchecked(ptr: *const T) -> Self { // SAFETY: This function's safety invariants are identical to `NonNull::new_unchecked` diff --git a/crates/bevy_reflect/compile_fail/tests/reflect_derive/custom_where_fail.rs b/crates/bevy_reflect/compile_fail/tests/reflect_derive/custom_where_fail.rs index 3cd2d1f60fd43..28370ca7555de 100644 --- a/crates/bevy_reflect/compile_fail/tests/reflect_derive/custom_where_fail.rs +++ b/crates/bevy_reflect/compile_fail/tests/reflect_derive/custom_where_fail.rs @@ -1,5 +1,5 @@ use bevy_reflect::{FromType, Reflect}; -use std::marker::PhantomData; +use core::marker::PhantomData; #[derive(Clone)] struct ReflectMyTrait; @@ -12,7 +12,7 @@ impl FromType for ReflectMyTrait { // Reason: populated `where` clause must be last with #[reflect(MyTrait)] #[derive(Reflect)] -#[reflect(where T: std::fmt::Debug, MyTrait)] +#[reflect(where T: core::fmt::Debug, MyTrait)] //~^ ERROR: /expected.+:/ // TODO: Investigate a way to improve the error message. pub struct Foo { diff --git a/crates/bevy_reflect/compile_fail/tests/reflect_derive/custom_where_pass.rs b/crates/bevy_reflect/compile_fail/tests/reflect_derive/custom_where_pass.rs index 2b317c2e6185e..456afd35f5240 100644 --- a/crates/bevy_reflect/compile_fail/tests/reflect_derive/custom_where_pass.rs +++ b/crates/bevy_reflect/compile_fail/tests/reflect_derive/custom_where_pass.rs @@ -1,6 +1,6 @@ //@check-pass use bevy_reflect::{FromType, Reflect}; -use std::marker::PhantomData; +use core::marker::PhantomData; #[derive(Clone)] struct ReflectMyTrait; @@ -12,7 +12,7 @@ impl FromType for ReflectMyTrait { } #[derive(Reflect)] -#[reflect(MyTrait, where T: std::fmt::Debug)] +#[reflect(MyTrait, where T: core::fmt::Debug)] pub struct Foo { value: String, #[reflect(ignore)] @@ -29,7 +29,7 @@ pub struct Bar { #[derive(Reflect)] #[reflect(MyTrait)] -#[reflect(where T: std::fmt::Debug)] +#[reflect(where T: core::fmt::Debug)] pub struct Baz { value: String, #[reflect(ignore)] diff --git a/crates/bevy_reflect/derive/src/derive_data.rs b/crates/bevy_reflect/derive/src/derive_data.rs index 4e04d6670d97f..44e06658fca82 100644 --- a/crates/bevy_reflect/derive/src/derive_data.rs +++ b/crates/bevy_reflect/derive/src/derive_data.rs @@ -4,18 +4,17 @@ use proc_macro2::Span; use crate::{ container_attributes::{ContainerAttributes, FromReflectAttrs, TypePathAttrs}, field_attributes::FieldAttributes, + remote::RemoteType, result_sifter::ResultSifter, + serialization::SerializationDataDef, string_expr::StringExpr, type_path::parse_path_no_leading_colon, where_clause_options::WhereClauseOptions, + REFLECT_ATTRIBUTE_NAME, TYPE_NAME_ATTRIBUTE_NAME, TYPE_PATH_ATTRIBUTE_NAME, }; use quote::{quote, ToTokens}; use syn::token::Comma; -use crate::{ - remote::RemoteType, serialization::SerializationDataDef, REFLECT_ATTRIBUTE_NAME, - TYPE_NAME_ATTRIBUTE_NAME, TYPE_PATH_ATTRIBUTE_NAME, -}; use syn::{ parse_str, punctuated::Punctuated, spanned::Spanned, Data, DeriveInput, Field, Fields, GenericParam, Generics, Ident, LitStr, Meta, Path, PathSegment, Type, TypeParam, Variant, @@ -478,7 +477,7 @@ impl<'a> ReflectMeta<'a> { self, where_clause_options, None, - Option::>::None, + Option::>::None, ) } @@ -856,14 +855,14 @@ impl<'a> EnumVariant<'a> { /// ```ignore (bevy_reflect is not accessible from this crate) /// # use syn::parse_quote; /// # use bevy_reflect_derive::ReflectTypePath; -/// let path: syn::Path = parse_quote!(::core::marker::PhantomData)?; +/// let path: syn::Path = parse_quote!(::std::marker::PhantomData)?; /// /// let type_path = ReflectTypePath::External { /// path, /// custom_path: None, /// }; /// -/// // Equivalent to "core::marker". +/// // Equivalent to "std::marker". /// let module_path = type_path.module_path(); /// # Ok::<(), syn::Error>(()) /// ``` @@ -1059,7 +1058,7 @@ impl<'a> ReflectTypePath<'a> { /// Returns a [`StringExpr`] representing the "type path" of the type. /// - /// For `Option`, this is `"core::option::Option"`. + /// For `Option`, this is `"std::option::Option"`. pub fn long_type_path(&self, bevy_reflect_path: &Path) -> StringExpr { match self { Self::Primitive(ident) => StringExpr::from(ident), @@ -1135,7 +1134,7 @@ impl<'a> ReflectTypePath<'a> { /// /// For non-customised [internal] paths this is created from [`module_path`]. /// - /// For `Option`, this is `"core::option"`. + /// For `Option`, this is `"std::option"`. /// /// [primitive]: ReflectTypePath::Primitive /// [anonymous]: ReflectTypePath::Anonymous diff --git a/crates/bevy_reflect/derive/src/enum_utility.rs b/crates/bevy_reflect/derive/src/enum_utility.rs index b370d36703c26..f4b1e5ede8b77 100644 --- a/crates/bevy_reflect/derive/src/enum_utility.rs +++ b/crates/bevy_reflect/derive/src/enum_utility.rs @@ -1,6 +1,5 @@ use crate::{ - derive_data::{ReflectEnum, StructField}, - field_attributes::DefaultBehavior, + derive_data::ReflectEnum, derive_data::StructField, field_attributes::DefaultBehavior, ident::ident_or_index, }; use bevy_macro_utils::fq_std::{FQDefault, FQOption}; diff --git a/crates/bevy_reflect/derive/src/lib.rs b/crates/bevy_reflect/derive/src/lib.rs index e7fc27bcfe1a3..a54442028df37 100644 --- a/crates/bevy_reflect/derive/src/lib.rs +++ b/crates/bevy_reflect/derive/src/lib.rs @@ -159,7 +159,7 @@ fn match_reflect_impls(ast: DeriveInput, source: ReflectImplSource) -> TokenStre /// the type's [`Debug`] implementation. /// A custom implementation may be provided using `#[reflect(Debug(my_debug_func))]` where /// `my_debug_func` is the path to a function matching the signature: -/// `(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result`. +/// `(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result`. /// * `#[reflect(PartialEq)]` will force the implementation of `Reflect::reflect_partial_eq` to rely on /// the type's [`PartialEq`] implementation. /// A custom implementation may be provided using `#[reflect(PartialEq(my_partial_eq_func))]` where diff --git a/crates/bevy_reflect/derive/src/remote.rs b/crates/bevy_reflect/derive/src/remote.rs index 2ef657ffa7cbf..13cbe681ed4c7 100644 --- a/crates/bevy_reflect/derive/src/remote.rs +++ b/crates/bevy_reflect/derive/src/remote.rs @@ -167,7 +167,7 @@ fn impl_reflect_remote(input: &ReflectDerive, remote_ty: &TypePath) -> proc_macr // ``` // error[E0512]: cannot transmute between types of different sizes, or dependently-sized types // | - // | std::mem::transmute::(a) + // | core::mem::transmute::(a) // | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ // | // = note: source type: `A` (this type does not have a fixed size) @@ -196,7 +196,7 @@ fn impl_reflect_remote(input: &ReflectDerive, remote_ty: &TypePath) -> proc_macr // ``` // error[E0512]: cannot transmute between types of different sizes, or dependently-sized types // | - // | std::mem::transmute::(a) + // | core::mem::transmute::(a) // | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ // | // = note: source type: `A` (this type does not have a fixed size) diff --git a/crates/bevy_reflect/derive/src/struct_utility.rs b/crates/bevy_reflect/derive/src/struct_utility.rs index ffad10a06a136..09604419b6043 100644 --- a/crates/bevy_reflect/derive/src/struct_utility.rs +++ b/crates/bevy_reflect/derive/src/struct_utility.rs @@ -6,7 +6,7 @@ use quote::quote; /// These are "remote-aware" because when a field is a remote field, it uses a [`transmute`] internally /// to access the field. /// -/// [`transmute`]: core::mem::transmute +/// [`transmute`]: std::mem::transmute pub(crate) struct FieldAccessors { /// The referenced field accessors, such as `&self.foo`. pub fields_ref: Vec, diff --git a/crates/bevy_reflect/src/array.rs b/crates/bevy_reflect/src/array.rs index 5b9f2ce916308..87e86d45f8b36 100644 --- a/crates/bevy_reflect/src/array.rs +++ b/crates/bevy_reflect/src/array.rs @@ -4,7 +4,7 @@ use crate::{ TypeInfo, TypePath, }; use bevy_reflect_derive::impl_type_path; -use std::{ +use core::{ any::Any, fmt::{Debug, Formatter}, hash::{Hash, Hasher}, @@ -264,7 +264,7 @@ impl PartialReflect for DynamicArray { array_partial_eq(self, value) } - fn debug(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + fn debug(&self, f: &mut Formatter<'_>) -> core::fmt::Result { write!(f, "DynamicArray(")?; array_debug(self, f)?; write!(f, ")") @@ -335,7 +335,7 @@ impl FromIterator for DynamicArray { impl IntoIterator for DynamicArray { type Item = Box; - type IntoIter = std::vec::IntoIter; + type IntoIter = alloc::vec::IntoIter; fn into_iter(self) -> Self::IntoIter { self.values.into_vec().into_iter() @@ -492,7 +492,7 @@ pub fn array_partial_eq( /// // ] /// ``` #[inline] -pub fn array_debug(dyn_array: &dyn Array, f: &mut Formatter<'_>) -> std::fmt::Result { +pub fn array_debug(dyn_array: &dyn Array, f: &mut Formatter<'_>) -> core::fmt::Result { let mut debug = f.debug_list(); for item in dyn_array.iter() { debug.entry(&item as &dyn Debug); diff --git a/crates/bevy_reflect/src/attributes.rs b/crates/bevy_reflect/src/attributes.rs index c25093a6722b0..029f61ed1b73e 100644 --- a/crates/bevy_reflect/src/attributes.rs +++ b/crates/bevy_reflect/src/attributes.rs @@ -1,7 +1,9 @@ use crate::Reflect; use bevy_utils::TypeIdMap; -use core::fmt::{Debug, Formatter}; -use std::any::TypeId; +use core::{ + any::TypeId, + fmt::{Debug, Formatter}, +}; /// A collection of custom attributes for a type, field, or variant. /// @@ -14,7 +16,7 @@ use std::any::TypeId; /// /// ``` /// # use bevy_reflect::{Reflect, Typed, TypeInfo}; -/// use core::ops::RangeInclusive; +/// use std::ops::RangeInclusive; /// #[derive(Reflect)] /// struct Slider { /// #[reflect(@RangeInclusive::::new(0.0, 1.0))] @@ -153,7 +155,7 @@ macro_rules! impl_custom_attribute_methods { /// Gets a custom attribute by its [`TypeId`](std::any::TypeId). /// /// This is the dynamic equivalent of [`get_attribute`](Self::get_attribute). - pub fn get_attribute_by_id(&$self, id: ::std::any::TypeId) -> Option<&dyn $crate::Reflect> { + pub fn get_attribute_by_id(&$self, id: ::core::any::TypeId) -> Option<&dyn $crate::Reflect> { $self.custom_attributes().get_by_id(id) } @@ -163,9 +165,9 @@ macro_rules! impl_custom_attribute_methods { $self.custom_attributes().contains::() } - #[doc = concat!("Returns `true` if this ", $term, " has a custom attribute with the specified [`TypeId`](::std::any::TypeId).")] + #[doc = concat!("Returns `true` if this ", $term, " has a custom attribute with the specified [`TypeId`](::core::any::TypeId).")] #[doc = "\n\nThis is the dynamic equivalent of [`has_attribute`](Self::has_attribute)"] - pub fn has_attribute_by_id(&$self, id: ::std::any::TypeId) -> bool { + pub fn has_attribute_by_id(&$self, id: ::core::any::TypeId) -> bool { $self.custom_attributes().contains_by_id(id) } }; @@ -178,7 +180,7 @@ mod tests { use super::*; use crate as bevy_reflect; use crate::{type_info::Typed, TypeInfo, VariantInfo}; - use std::ops::RangeInclusive; + use core::ops::RangeInclusive; #[derive(Reflect, PartialEq, Debug)] struct Tooltip(String); diff --git a/crates/bevy_reflect/src/enums/dynamic_enum.rs b/crates/bevy_reflect/src/enums/dynamic_enum.rs index 5b3f813e14c70..d925377b2f462 100644 --- a/crates/bevy_reflect/src/enums/dynamic_enum.rs +++ b/crates/bevy_reflect/src/enums/dynamic_enum.rs @@ -6,7 +6,7 @@ use crate::{ Struct, Tuple, TypeInfo, VariantFieldIter, VariantType, }; -use std::fmt::Formatter; +use core::fmt::Formatter; /// A dynamic representation of an enum variant. #[derive(Debug, Default)] @@ -403,7 +403,7 @@ impl PartialReflect for DynamicEnum { } #[inline] - fn debug(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + fn debug(&self, f: &mut Formatter<'_>) -> core::fmt::Result { write!(f, "DynamicEnum(")?; enum_debug(self, f)?; write!(f, ")") diff --git a/crates/bevy_reflect/src/enums/enum_trait.rs b/crates/bevy_reflect/src/enums/enum_trait.rs index cc8dfb6200957..086092b52050f 100644 --- a/crates/bevy_reflect/src/enums/enum_trait.rs +++ b/crates/bevy_reflect/src/enums/enum_trait.rs @@ -3,8 +3,9 @@ use crate::{ type_info::impl_type_methods, DynamicEnum, PartialReflect, Type, TypePath, VariantInfo, VariantType, }; +use alloc::sync::Arc; use bevy_utils::HashMap; -use std::{slice::Iter, sync::Arc}; +use core::slice::Iter; /// A trait used to power [enum-like] operations via [reflection]. /// diff --git a/crates/bevy_reflect/src/enums/helpers.rs b/crates/bevy_reflect/src/enums/helpers.rs index e92580527f644..659d0bd7bc823 100644 --- a/crates/bevy_reflect/src/enums/helpers.rs +++ b/crates/bevy_reflect/src/enums/helpers.rs @@ -1,5 +1,5 @@ use crate::{utility::reflect_hasher, Enum, PartialReflect, ReflectRef, VariantType}; -use std::{ +use core::{ fmt::Debug, hash::{Hash, Hasher}, }; @@ -8,7 +8,7 @@ use std::{ #[inline] pub fn enum_hash(value: &TEnum) -> Option { let mut hasher = reflect_hasher(); - std::any::Any::type_id(value).hash(&mut hasher); + core::any::Any::type_id(value).hash(&mut hasher); value.variant_name().hash(&mut hasher); value.variant_type().hash(&mut hasher); for field in value.iter_fields() { @@ -100,7 +100,7 @@ pub fn enum_partial_eq(a: &TEnum, b: &dyn PartialReflect) /// // ) /// ``` #[inline] -pub fn enum_debug(dyn_enum: &dyn Enum, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +pub fn enum_debug(dyn_enum: &dyn Enum, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { match dyn_enum.variant_type() { VariantType::Unit => f.write_str(dyn_enum.variant_name()), VariantType::Tuple => { diff --git a/crates/bevy_reflect/src/enums/variants.rs b/crates/bevy_reflect/src/enums/variants.rs index a4dbc0fa4f958..6323e2a3c92d0 100644 --- a/crates/bevy_reflect/src/enums/variants.rs +++ b/crates/bevy_reflect/src/enums/variants.rs @@ -3,9 +3,9 @@ use crate::{ NamedField, UnnamedField, }; use bevy_utils::HashMap; -use std::slice::Iter; +use core::slice::Iter; -use std::sync::Arc; +use alloc::sync::Arc; use thiserror::Error; /// Describes the form of an enum variant. diff --git a/crates/bevy_reflect/src/fields.rs b/crates/bevy_reflect/src/fields.rs index d535b9f0020a3..ab7c3cd34db84 100644 --- a/crates/bevy_reflect/src/fields.rs +++ b/crates/bevy_reflect/src/fields.rs @@ -3,7 +3,7 @@ use crate::{ type_info::impl_type_methods, MaybeTyped, PartialReflect, Type, TypeInfo, TypePath, }; -use std::sync::Arc; +use alloc::sync::Arc; /// The named field of a reflected struct. #[derive(Clone, Debug)] diff --git a/crates/bevy_reflect/src/func/args/arg.rs b/crates/bevy_reflect/src/func/args/arg.rs index 1ef415591a0ae..a61ff7c184fe2 100644 --- a/crates/bevy_reflect/src/func/args/arg.rs +++ b/crates/bevy_reflect/src/func/args/arg.rs @@ -2,7 +2,7 @@ use crate::{ func::args::{ArgError, FromArg, Ownership}, PartialReflect, Reflect, TypePath, }; -use std::ops::Deref; +use core::ops::Deref; /// Represents an argument that can be passed to a [`DynamicFunction`] or [`DynamicFunctionMut`]. /// @@ -85,8 +85,8 @@ impl<'a> Arg<'a> { match self.value { ArgValue::Owned(arg) => arg.try_take().map_err(|arg| ArgError::UnexpectedType { index: self.index, - expected: std::borrow::Cow::Borrowed(T::type_path()), - received: std::borrow::Cow::Owned(arg.reflect_type_path().to_string()), + expected: alloc::borrow::Cow::Borrowed(T::type_path()), + received: alloc::borrow::Cow::Owned(arg.reflect_type_path().to_string()), }), ArgValue::Ref(_) => Err(ArgError::InvalidOwnership { index: self.index, @@ -128,8 +128,8 @@ impl<'a> Arg<'a> { .try_downcast_ref() .ok_or_else(|| ArgError::UnexpectedType { index: self.index, - expected: std::borrow::Cow::Borrowed(T::type_path()), - received: std::borrow::Cow::Owned(arg.reflect_type_path().to_string()), + expected: alloc::borrow::Cow::Borrowed(T::type_path()), + received: alloc::borrow::Cow::Owned(arg.reflect_type_path().to_string()), })?) } ArgValue::Mut(_) => Err(ArgError::InvalidOwnership { @@ -168,12 +168,12 @@ impl<'a> Arg<'a> { received: Ownership::Ref, }), ArgValue::Mut(arg) => { - let received = std::borrow::Cow::Owned(arg.reflect_type_path().to_string()); + let received = alloc::borrow::Cow::Owned(arg.reflect_type_path().to_string()); Ok(arg .try_downcast_mut() .ok_or_else(|| ArgError::UnexpectedType { index: self.index, - expected: std::borrow::Cow::Borrowed(T::type_path()), + expected: alloc::borrow::Cow::Borrowed(T::type_path()), received, })?) } diff --git a/crates/bevy_reflect/src/func/args/list.rs b/crates/bevy_reflect/src/func/args/list.rs index 2021a8b422f26..ea35cdb2adbdc 100644 --- a/crates/bevy_reflect/src/func/args/list.rs +++ b/crates/bevy_reflect/src/func/args/list.rs @@ -5,7 +5,7 @@ use crate::{ }, PartialReflect, Reflect, TypePath, }; -use std::collections::VecDeque; +use alloc::collections::VecDeque; /// A list of arguments that can be passed to a [`DynamicFunction`] or [`DynamicFunctionMut`]. /// diff --git a/crates/bevy_reflect/src/func/dynamic_function.rs b/crates/bevy_reflect/src/func/dynamic_function.rs index 926205c29f503..e6cfd9bea7022 100644 --- a/crates/bevy_reflect/src/func/dynamic_function.rs +++ b/crates/bevy_reflect/src/func/dynamic_function.rs @@ -1,5 +1,5 @@ -use crate as bevy_reflect; use crate::{ + self as bevy_reflect, __macro_exports::RegisterForReflection, func::{ args::ArgList, info::FunctionInfo, DynamicFunctionMut, Function, FunctionError, @@ -9,10 +9,9 @@ use crate::{ ApplyError, MaybeTyped, PartialReflect, Reflect, ReflectKind, ReflectMut, ReflectOwned, ReflectRef, TypeInfo, TypePath, }; -use alloc::borrow::Cow; +use alloc::{borrow::Cow, sync::Arc}; use bevy_reflect_derive::impl_type_path; use core::fmt::{Debug, Formatter}; -use std::sync::Arc; /// A dynamic representation of a function. /// diff --git a/crates/bevy_reflect/src/func/info.rs b/crates/bevy_reflect/src/func/info.rs index 1a93342f6d58f..39accdf52dceb 100644 --- a/crates/bevy_reflect/src/func/info.rs +++ b/crates/bevy_reflect/src/func/info.rs @@ -353,7 +353,7 @@ all_tuples!(impl_typed_function, 0, 15, Arg, arg); /// /// [`type_name`]: std::any::type_name fn create_info() -> FunctionInfo { - let name = std::any::type_name::(); + let name = core::any::type_name::(); if name.ends_with("{{closure}}") || name.starts_with("fn(") { FunctionInfo::anonymous() @@ -374,7 +374,7 @@ mod tests { // Sanity check: assert_eq!( - std::any::type_name_of_val(&add), + core::any::type_name_of_val(&add), "bevy_reflect::func::info::tests::should_create_function_info::add" ); @@ -398,7 +398,7 @@ mod tests { let add = add as fn(i32, i32) -> i32; // Sanity check: - assert_eq!(std::any::type_name_of_val(&add), "fn(i32, i32) -> i32"); + assert_eq!(core::any::type_name_of_val(&add), "fn(i32, i32) -> i32"); let info = add.get_function_info(); assert!(info.name().is_none()); @@ -414,7 +414,7 @@ mod tests { // Sanity check: assert_eq!( - std::any::type_name_of_val(&add), + core::any::type_name_of_val(&add), "bevy_reflect::func::info::tests::should_create_anonymous_function_info::{{closure}}" ); @@ -433,7 +433,7 @@ mod tests { // Sanity check: assert_eq!( - std::any::type_name_of_val(&add), + core::any::type_name_of_val(&add), "bevy_reflect::func::info::tests::should_create_closure_info::{{closure}}" ); diff --git a/crates/bevy_reflect/src/func/mod.rs b/crates/bevy_reflect/src/func/mod.rs index 6e07f0bef1aac..2811f5c22663a 100644 --- a/crates/bevy_reflect/src/func/mod.rs +++ b/crates/bevy_reflect/src/func/mod.rs @@ -107,14 +107,14 @@ //! //! let mut registry = FunctionRegistry::default(); //! -//! // You can register functions and methods by their `std::any::type_name`: +//! // You can register functions and methods by their `core::any::type_name`: //! registry.register(add).unwrap(); //! //! // Or you can register them by a custom name: //! registry.register_with_name("mul", |a: i32, b: i32| a * b).unwrap(); //! //! // You can then retrieve and call these functions by name: -//! let reflect_add = registry.get(std::any::type_name_of_val(&add)).unwrap(); +//! let reflect_add = registry.get(core::any::type_name_of_val(&add)).unwrap(); //! let value = reflect_add.call(ArgList::default().push_owned(10_i32).push_owned(5_i32)).unwrap(); //! assert_eq!(value.unwrap_owned().try_downcast_ref::(), Some(&15)); //! diff --git a/crates/bevy_reflect/src/func/registry.rs b/crates/bevy_reflect/src/func/registry.rs index 40a1d4cbe14d6..59fb9e7f8b792 100644 --- a/crates/bevy_reflect/src/func/registry.rs +++ b/crates/bevy_reflect/src/func/registry.rs @@ -1,6 +1,6 @@ -use alloc::borrow::Cow; +use alloc::{borrow::Cow, sync::Arc}; use core::fmt::Debug; -use std::sync::{Arc, PoisonError, RwLock, RwLockReadGuard, RwLockWriteGuard}; +use std::sync::{PoisonError, RwLock, RwLockReadGuard, RwLockWriteGuard}; use bevy_utils::HashMap; @@ -366,7 +366,7 @@ mod tests { let mut registry = FunctionRegistry::default(); registry.register(foo).unwrap(); - let function = registry.get(std::any::type_name_of_val(&foo)).unwrap(); + let function = registry.get(core::any::type_name_of_val(&foo)).unwrap(); let value = function.call(ArgList::new()).unwrap().unwrap_owned(); assert_eq!(value.try_downcast_ref::(), Some(&123)); } @@ -435,7 +435,7 @@ mod tests { 321 } - let name = std::any::type_name_of_val(&foo); + let name = core::any::type_name_of_val(&foo); let mut registry = FunctionRegistry::default(); registry.register(foo).unwrap(); @@ -462,7 +462,7 @@ mod tests { 321 } - let name = std::any::type_name_of_val(&foo); + let name = core::any::type_name_of_val(&foo); let mut registry = FunctionRegistry::default(); registry.register(foo).unwrap(); @@ -488,7 +488,7 @@ mod tests { let args = ArgList::new().push_owned(25_i32).push_owned(75_i32); let result = registry - .call(std::any::type_name_of_val(&add), args) + .call(core::any::type_name_of_val(&add), args) .unwrap(); let value = result.unwrap().unwrap_owned(); assert_eq!(value.try_downcast_ref::(), Some(&100)); diff --git a/crates/bevy_reflect/src/impls/petgraph.rs b/crates/bevy_reflect/src/impls/petgraph.rs index c4bdaa83e1a72..f9ab09e1b9f26 100644 --- a/crates/bevy_reflect/src/impls/petgraph.rs +++ b/crates/bevy_reflect/src/impls/petgraph.rs @@ -9,7 +9,7 @@ impl_reflect_opaque!(::petgraph::graph::NodeIndex( Deserialize )); impl_reflect_opaque!(::petgraph::graph::DiGraph< - N: ::std::clone::Clone, - E: ::std::clone::Clone, + N: ::core::clone::Clone, + E: ::core::clone::Clone, Ix: ::petgraph::graph::IndexType >()); diff --git a/crates/bevy_reflect/src/impls/smallvec.rs b/crates/bevy_reflect/src/impls/smallvec.rs index dd8f06e2f3cbd..7fa43e3308dc0 100644 --- a/crates/bevy_reflect/src/impls/smallvec.rs +++ b/crates/bevy_reflect/src/impls/smallvec.rs @@ -1,7 +1,7 @@ use bevy_reflect_derive::impl_type_path; use smallvec::{Array as SmallArray, SmallVec}; -use std::any::Any; +use core::any::Any; use crate::{ self as bevy_reflect, utility::GenericTypeInfoCell, ApplyError, FromReflect, FromType, diff --git a/crates/bevy_reflect/src/impls/std.rs b/crates/bevy_reflect/src/impls/std.rs index 284216dce0f7b..dba41e003f695 100644 --- a/crates/bevy_reflect/src/impls/std.rs +++ b/crates/bevy_reflect/src/impls/std.rs @@ -3,9 +3,9 @@ use crate::{ self as bevy_reflect, impl_type_path, map_apply, map_partial_eq, map_try_apply, + prelude::ReflectDefault, reflect::impl_full_reflect, set_apply, set_partial_eq, set_try_apply, - std_traits::ReflectDefault, utility::{reflect_hasher, GenericTypeInfoCell, GenericTypePathCell, NonGenericTypeInfoCell}, ApplyError, Array, ArrayInfo, ArrayIter, DynamicMap, DynamicSet, DynamicTypePath, FromReflect, FromType, GetTypeRegistration, List, ListInfo, ListIter, Map, MapInfo, MapIter, MaybeTyped, @@ -13,15 +13,14 @@ use crate::{ ReflectKind, ReflectMut, ReflectOwned, ReflectRef, ReflectSerialize, Set, SetInfo, TypeInfo, TypePath, TypeRegistration, TypeRegistry, Typed, }; +use alloc::{borrow::Cow, collections::VecDeque}; use bevy_reflect_derive::{impl_reflect, impl_reflect_opaque}; -use std::{ +use core::{ any::Any, - borrow::Cow, - collections::VecDeque, fmt, hash::{BuildHasher, Hash, Hasher}, - path::Path, }; +use std::path::Path; impl_reflect_opaque!(bool( Debug, @@ -98,15 +97,15 @@ impl_reflect_opaque!(::std::path::PathBuf( Deserialize, Default )); -impl_reflect_opaque!(::std::any::TypeId(Debug, Hash, PartialEq,)); -impl_reflect_opaque!(::std::collections::BTreeSet()); +impl_reflect_opaque!(::core::any::TypeId(Debug, Hash, PartialEq,)); +impl_reflect_opaque!(::alloc::collections::BTreeSet()); impl_reflect_opaque!(::core::ops::Range()); impl_reflect_opaque!(::core::ops::RangeInclusive()); impl_reflect_opaque!(::core::ops::RangeFrom()); impl_reflect_opaque!(::core::ops::RangeTo()); impl_reflect_opaque!(::core::ops::RangeToInclusive()); impl_reflect_opaque!(::core::ops::RangeFull()); -impl_reflect_opaque!(::std::ops::Bound()); +impl_reflect_opaque!(::core::ops::Bound()); impl_reflect_opaque!(::bevy_utils::Duration( Debug, Hash, @@ -202,7 +201,7 @@ impl_reflect_opaque!(::core::num::NonZeroI8( )); impl_reflect_opaque!(::core::num::Wrapping()); impl_reflect_opaque!(::core::num::Saturating()); -impl_reflect_opaque!(::std::sync::Arc); +impl_reflect_opaque!(::alloc::sync::Arc); // `Serialize` and `Deserialize` only for platforms supported by serde: // https://github.com/serde-rs/serde/blob/3ffb86fc70efd3d329519e2dddfa306cc04f167c/serde/src/de/impls.rs#L1732 @@ -345,48 +344,48 @@ macro_rules! impl_reflect_for_atomic { } impl_reflect_for_atomic!( - ::std::sync::atomic::AtomicIsize, - ::std::sync::atomic::Ordering::SeqCst + ::core::sync::atomic::AtomicIsize, + ::core::sync::atomic::Ordering::SeqCst ); impl_reflect_for_atomic!( - ::std::sync::atomic::AtomicUsize, - ::std::sync::atomic::Ordering::SeqCst + ::core::sync::atomic::AtomicUsize, + ::core::sync::atomic::Ordering::SeqCst ); impl_reflect_for_atomic!( - ::std::sync::atomic::AtomicI64, - ::std::sync::atomic::Ordering::SeqCst + ::core::sync::atomic::AtomicI64, + ::core::sync::atomic::Ordering::SeqCst ); impl_reflect_for_atomic!( - ::std::sync::atomic::AtomicU64, - ::std::sync::atomic::Ordering::SeqCst + ::core::sync::atomic::AtomicU64, + ::core::sync::atomic::Ordering::SeqCst ); impl_reflect_for_atomic!( - ::std::sync::atomic::AtomicI32, - ::std::sync::atomic::Ordering::SeqCst + ::core::sync::atomic::AtomicI32, + ::core::sync::atomic::Ordering::SeqCst ); impl_reflect_for_atomic!( - ::std::sync::atomic::AtomicU32, - ::std::sync::atomic::Ordering::SeqCst + ::core::sync::atomic::AtomicU32, + ::core::sync::atomic::Ordering::SeqCst ); impl_reflect_for_atomic!( - ::std::sync::atomic::AtomicI16, - ::std::sync::atomic::Ordering::SeqCst + ::core::sync::atomic::AtomicI16, + ::core::sync::atomic::Ordering::SeqCst ); impl_reflect_for_atomic!( - ::std::sync::atomic::AtomicU16, - ::std::sync::atomic::Ordering::SeqCst + ::core::sync::atomic::AtomicU16, + ::core::sync::atomic::Ordering::SeqCst ); impl_reflect_for_atomic!( - ::std::sync::atomic::AtomicI8, - ::std::sync::atomic::Ordering::SeqCst + ::core::sync::atomic::AtomicI8, + ::core::sync::atomic::Ordering::SeqCst ); impl_reflect_for_atomic!( - ::std::sync::atomic::AtomicU8, - ::std::sync::atomic::Ordering::SeqCst + ::core::sync::atomic::AtomicU8, + ::core::sync::atomic::Ordering::SeqCst ); impl_reflect_for_atomic!( - ::std::sync::atomic::AtomicBool, - ::std::sync::atomic::Ordering::SeqCst + ::core::sync::atomic::AtomicBool, + ::core::sync::atomic::Ordering::SeqCst ); macro_rules! impl_reflect_for_veclike { @@ -1053,7 +1052,7 @@ crate::func::macros::impl_function_traits!(::bevy_utils::hashbrown::HashSet ); -impl Map for ::std::collections::BTreeMap +impl Map for ::alloc::collections::BTreeMap where K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Ord, V: FromReflect + MaybeTyped + TypePath + GetTypeRegistration, @@ -1152,7 +1151,7 @@ where } } -impl PartialReflect for ::std::collections::BTreeMap +impl PartialReflect for ::alloc::collections::BTreeMap where K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Ord, V: FromReflect + MaybeTyped + TypePath + GetTypeRegistration, @@ -1218,13 +1217,13 @@ where } impl_full_reflect!( - for ::std::collections::BTreeMap + for ::alloc::collections::BTreeMap where K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Ord, V: FromReflect + MaybeTyped + TypePath + GetTypeRegistration, ); -impl Typed for ::std::collections::BTreeMap +impl Typed for ::alloc::collections::BTreeMap where K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Ord, V: FromReflect + MaybeTyped + TypePath + GetTypeRegistration, @@ -1235,7 +1234,7 @@ where } } -impl GetTypeRegistration for ::std::collections::BTreeMap +impl GetTypeRegistration for ::alloc::collections::BTreeMap where K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Ord, V: FromReflect + MaybeTyped + TypePath + GetTypeRegistration, @@ -1247,7 +1246,7 @@ where } } -impl FromReflect for ::std::collections::BTreeMap +impl FromReflect for ::alloc::collections::BTreeMap where K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Ord, V: FromReflect + MaybeTyped + TypePath + GetTypeRegistration, @@ -1267,9 +1266,9 @@ where } } -impl_type_path!(::std::collections::BTreeMap); +impl_type_path!(::alloc::collections::BTreeMap); #[cfg(feature = "functions")] -crate::func::macros::impl_function_traits!(::std::collections::BTreeMap; +crate::func::macros::impl_function_traits!(::alloc::collections::BTreeMap; < K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Ord, V: FromReflect + MaybeTyped + TypePath + GetTypeRegistration @@ -2228,13 +2227,11 @@ mod tests { self as bevy_reflect, Enum, FromReflect, PartialReflect, Reflect, ReflectSerialize, TypeInfo, TypeRegistry, Typed, VariantInfo, VariantType, }; + use alloc::collections::BTreeMap; use bevy_utils::{Duration, HashMap, Instant}; + use core::f32::consts::{PI, TAU}; use static_assertions::assert_impl_all; - use std::{ - collections::BTreeMap, - f32::consts::{PI, TAU}, - path::Path, - }; + use std::path::Path; #[test] fn can_serialize_duration() { @@ -2242,7 +2239,7 @@ mod tests { type_registry.register::(); let reflect_serialize = type_registry - .get_type_data::(std::any::TypeId::of::()) + .get_type_data::(core::any::TypeId::of::()) .unwrap(); let _serializable = reflect_serialize.get_serializable(&Duration::ZERO); } @@ -2445,11 +2442,11 @@ mod tests { #[test] fn nonzero_usize_impl_reflect_from_reflect() { - let a: &dyn PartialReflect = &std::num::NonZero::::new(42).unwrap(); - let b: &dyn PartialReflect = &std::num::NonZero::::new(42).unwrap(); + let a: &dyn PartialReflect = &core::num::NonZero::::new(42).unwrap(); + let b: &dyn PartialReflect = &core::num::NonZero::::new(42).unwrap(); assert!(a.reflect_partial_eq(b).unwrap_or_default()); - let forty_two: std::num::NonZero = FromReflect::from_reflect(a).unwrap(); - assert_eq!(forty_two, std::num::NonZero::::new(42).unwrap()); + let forty_two: core::num::NonZero = FromReflect::from_reflect(a).unwrap(); + assert_eq!(forty_two, core::num::NonZero::::new(42).unwrap()); } #[test] @@ -2468,8 +2465,8 @@ mod tests { #[test] fn type_id_should_from_reflect() { - let type_id = std::any::TypeId::of::(); - let output = ::from_reflect(&type_id).unwrap(); + let type_id = core::any::TypeId::of::(); + let output = ::from_reflect(&type_id).unwrap(); assert_eq!(type_id, output); } diff --git a/crates/bevy_reflect/src/kind.rs b/crates/bevy_reflect/src/kind.rs index 079f3150783ae..114be8ed3830c 100644 --- a/crates/bevy_reflect/src/kind.rs +++ b/crates/bevy_reflect/src/kind.rs @@ -67,8 +67,8 @@ pub enum ReflectKind { Opaque, } -impl std::fmt::Display for ReflectKind { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl core::fmt::Display for ReflectKind { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { match self { ReflectKind::Struct => f.pad("struct"), ReflectKind::TupleStruct => f.pad("tuple struct"), diff --git a/crates/bevy_reflect/src/lib.rs b/crates/bevy_reflect/src/lib.rs index 37198e9a5c37b..021971a33a68c 100644 --- a/crates/bevy_reflect/src/lib.rs +++ b/crates/bevy_reflect/src/lib.rs @@ -333,7 +333,7 @@ //! registry.register::(); //! registry.register_type_data::(); //! -//! let registration = registry.get(std::any::TypeId::of::()).unwrap(); +//! let registration = registry.get(core::any::TypeId::of::()).unwrap(); //! let reflect_default = registration.data::().unwrap(); //! //! let new_value: Box = reflect_default.default(); @@ -542,6 +542,8 @@ //! [`bevy_reflect_derive/documentation`]: bevy_reflect_derive //! [derive `Reflect`]: derive@crate::Reflect +extern crate alloc; + mod array; mod fields; mod from_reflect; @@ -592,6 +594,7 @@ pub mod utility; /// This includes the most common types in this crate, re-exported for your convenience. pub mod prelude { pub use crate::std_traits::*; + #[doc(hidden)] pub use crate::{ reflect_trait, FromReflect, GetField, GetPath, GetTupleStructField, PartialReflect, @@ -625,8 +628,6 @@ pub use type_registry::*; pub use bevy_reflect_derive::*; pub use erased_serde; -extern crate alloc; - /// Exports used by the reflection macros. /// /// These are not meant to be used directly and are subject to breaking changes. @@ -679,20 +680,20 @@ pub mod __macro_exports { #[allow(clippy::disallowed_types, clippy::approx_constant)] mod tests { use ::serde::{de::DeserializeSeed, Deserialize, Serialize}; + use alloc::borrow::Cow; use bevy_utils::HashMap; + use core::{ + any::TypeId, + fmt::{Debug, Formatter}, + hash::Hash, + marker::PhantomData, + }; use disqualified::ShortName; use ron::{ ser::{to_string_pretty, PrettyConfig}, Deserializer, }; use static_assertions::{assert_impl_all, assert_not_impl_all}; - use std::{ - any::TypeId, - borrow::Cow, - fmt::{Debug, Formatter}, - hash::Hash, - marker::PhantomData, - }; use super::{prelude::*, *}; use crate as bevy_reflect; @@ -1798,7 +1799,7 @@ mod tests { let info = MyCowStr::type_info().as_opaque().unwrap(); assert!(info.is::()); - assert_eq!(std::any::type_name::(), info.type_path()); + assert_eq!(core::any::type_name::(), info.type_path()); let value: &dyn Reflect = &Cow::<'static, str>::Owned("Hello!".to_string()); let info = value.reflect_type_info(); @@ -1812,8 +1813,8 @@ mod tests { assert!(info.is::()); assert!(info.item_ty().is::()); assert!(info.item_info().unwrap().is::()); - assert_eq!(std::any::type_name::(), info.type_path()); - assert_eq!(std::any::type_name::(), info.item_ty().path()); + assert_eq!(core::any::type_name::(), info.type_path()); + assert_eq!(core::any::type_name::(), info.item_ty().path()); let value: &dyn Reflect = &Cow::<'static, [u8]>::Owned(vec![0, 1, 2, 3]); let info = value.reflect_type_info(); @@ -2092,7 +2093,7 @@ mod tests { #[reflect(Debug)] struct CustomDebug; impl Debug for CustomDebug { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { f.write_str("Cool debug!") } } @@ -2160,7 +2161,7 @@ bevy_reflect::tests::Test { struct Foo(i32); impl Debug for Foo { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { write!(f, "Foo") } } @@ -2181,7 +2182,7 @@ bevy_reflect::tests::Test { a: u32, } - fn custom_debug(_x: &Foo, f: &mut Formatter<'_>) -> std::fmt::Result { + fn custom_debug(_x: &Foo, f: &mut Formatter<'_>) -> core::fmt::Result { write!(f, "123") } @@ -2223,7 +2224,7 @@ bevy_reflect::tests::Test { fn should_allow_multiple_custom_where() { #[derive(Reflect)] #[reflect(where T: Default)] - #[reflect(where U: std::ops::Add)] + #[reflect(where U: core::ops::Add)] struct Foo(T, U); #[derive(Reflect)] @@ -2346,7 +2347,7 @@ bevy_reflect::tests::Test { impl TypePath for Foo { fn type_path() -> &'static str { - std::any::type_name::() + core::any::type_name::() } fn short_type_path() -> &'static str { @@ -2772,7 +2773,7 @@ bevy_reflect::tests::Test { #[test] fn should_reflect_nested_remote_enum() { mod external_crate { - use std::fmt::Debug; + use core::fmt::Debug; #[derive(Debug)] pub enum TheirOuter { diff --git a/crates/bevy_reflect/src/list.rs b/crates/bevy_reflect/src/list.rs index 5ab3107bb1c30..3844605b0b9ae 100644 --- a/crates/bevy_reflect/src/list.rs +++ b/crates/bevy_reflect/src/list.rs @@ -1,4 +1,4 @@ -use std::{ +use core::{ any::Any, fmt::{Debug, Formatter}, hash::{Hash, Hasher}, @@ -320,7 +320,7 @@ impl PartialReflect for DynamicList { list_partial_eq(self, value) } - fn debug(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + fn debug(&self, f: &mut Formatter<'_>) -> core::fmt::Result { write!(f, "DynamicList(")?; list_debug(self, f)?; write!(f, ")") @@ -335,7 +335,7 @@ impl PartialReflect for DynamicList { impl_type_path!((in bevy_reflect) DynamicList); impl Debug for DynamicList { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { self.debug(f) } } @@ -360,7 +360,7 @@ impl FromIterator for DynamicList { impl IntoIterator for DynamicList { type Item = Box; - type IntoIter = std::vec::IntoIter; + type IntoIter = alloc::vec::IntoIter; fn into_iter(self) -> Self::IntoIter { self.values.into_iter() @@ -509,7 +509,7 @@ pub fn list_partial_eq(a: &L, b: &dyn PartialReflect) -> Optio /// // ] /// ``` #[inline] -pub fn list_debug(dyn_list: &dyn List, f: &mut Formatter<'_>) -> std::fmt::Result { +pub fn list_debug(dyn_list: &dyn List, f: &mut Formatter<'_>) -> core::fmt::Result { let mut debug = f.debug_list(); for item in dyn_list.iter() { debug.entry(&item as &dyn Debug); @@ -521,7 +521,7 @@ pub fn list_debug(dyn_list: &dyn List, f: &mut Formatter<'_>) -> std::fmt::Resul mod tests { use super::DynamicList; use crate::Reflect; - use std::assert_eq; + use core::assert_eq; #[test] fn test_into_iter() { diff --git a/crates/bevy_reflect/src/map.rs b/crates/bevy_reflect/src/map.rs index fc1fd25b9b415..ad1fcdd73e78c 100644 --- a/crates/bevy_reflect/src/map.rs +++ b/crates/bevy_reflect/src/map.rs @@ -1,4 +1,4 @@ -use std::fmt::{Debug, Formatter}; +use core::fmt::{Debug, Formatter}; use bevy_reflect_derive::impl_type_path; use bevy_utils::{Entry, HashMap}; @@ -291,7 +291,7 @@ impl Map for DynamicMap { { Entry::Occupied(entry) => { let (_old_key, old_value) = self.values.get_mut(*entry.get()).unwrap(); - std::mem::swap(old_value, &mut value); + core::mem::swap(old_value, &mut value); Some(value) } Entry::Vacant(entry) => { @@ -376,7 +376,7 @@ impl PartialReflect for DynamicMap { map_partial_eq(self, value) } - fn debug(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + fn debug(&self, f: &mut Formatter<'_>) -> core::fmt::Result { write!(f, "DynamicMap(")?; map_debug(self, f)?; write!(f, ")") @@ -391,7 +391,7 @@ impl PartialReflect for DynamicMap { impl_type_path!((in bevy_reflect) DynamicMap); impl Debug for DynamicMap { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { self.debug(f) } } @@ -449,7 +449,7 @@ impl FromIterator<(K, V)> for DynamicMap { impl IntoIterator for DynamicMap { type Item = (Box, Box); - type IntoIter = std::vec::IntoIter; + type IntoIter = alloc::vec::IntoIter; fn into_iter(self) -> Self::IntoIter { self.values.into_iter() @@ -518,7 +518,7 @@ pub fn map_partial_eq(a: &M, b: &dyn PartialReflect) -> Option< /// // } /// ``` #[inline] -pub fn map_debug(dyn_map: &dyn Map, f: &mut Formatter<'_>) -> std::fmt::Result { +pub fn map_debug(dyn_map: &dyn Map, f: &mut Formatter<'_>) -> core::fmt::Result { let mut debug = f.debug_map(); for (key, value) in dyn_map.iter() { debug.entry(&key as &dyn Debug, &value as &dyn Debug); diff --git a/crates/bevy_reflect/src/path/access.rs b/crates/bevy_reflect/src/path/access.rs index 4648b9dfa6349..c0a141fcbaee1 100644 --- a/crates/bevy_reflect/src/path/access.rs +++ b/crates/bevy_reflect/src/path/access.rs @@ -1,6 +1,7 @@ //! Representation for individual element accesses within a path. -use std::{borrow::Cow, fmt}; +use alloc::borrow::Cow; +use core::fmt; use super::error::AccessErrorKind; use crate::{AccessError, PartialReflect, ReflectKind, ReflectMut, ReflectRef, VariantType}; diff --git a/crates/bevy_reflect/src/path/error.rs b/crates/bevy_reflect/src/path/error.rs index d25d1670492f6..0e900c8315ecb 100644 --- a/crates/bevy_reflect/src/path/error.rs +++ b/crates/bevy_reflect/src/path/error.rs @@ -1,4 +1,4 @@ -use std::fmt; +use core::fmt; use super::Access; use crate::{ReflectKind, VariantType}; @@ -126,4 +126,4 @@ impl fmt::Display for AccessError<'_> { } } } -impl std::error::Error for AccessError<'_> {} +impl core::error::Error for AccessError<'_> {} diff --git a/crates/bevy_reflect/src/path/mod.rs b/crates/bevy_reflect/src/path/mod.rs index 610b95d96004a..bbfa6cad52bcd 100644 --- a/crates/bevy_reflect/src/path/mod.rs +++ b/crates/bevy_reflect/src/path/mod.rs @@ -9,7 +9,7 @@ pub use parse::ParseError; use parse::PathParser; use crate::{PartialReflect, Reflect}; -use std::fmt; +use core::fmt; use thiserror::Error; type PathResult<'a, T> = Result>; @@ -491,13 +491,13 @@ impl fmt::Display for ParsedPath { Ok(()) } } -impl std::ops::Index for ParsedPath { +impl core::ops::Index for ParsedPath { type Output = OffsetAccess; fn index(&self, index: usize) -> &Self::Output { &self.0[index] } } -impl std::ops::IndexMut for ParsedPath { +impl core::ops::IndexMut for ParsedPath { fn index_mut(&mut self, index: usize) -> &mut Self::Output { &mut self.0[index] } diff --git a/crates/bevy_reflect/src/path/parse.rs b/crates/bevy_reflect/src/path/parse.rs index 8195a23a31cb4..0c85c4b93331a 100644 --- a/crates/bevy_reflect/src/path/parse.rs +++ b/crates/bevy_reflect/src/path/parse.rs @@ -1,4 +1,4 @@ -use std::{ +use core::{ fmt::{self, Write}, num::ParseIntError, str::from_utf8_unchecked, diff --git a/crates/bevy_reflect/src/reflect.rs b/crates/bevy_reflect/src/reflect.rs index 0c8550107c96b..b572780896375 100644 --- a/crates/bevy_reflect/src/reflect.rs +++ b/crates/bevy_reflect/src/reflect.rs @@ -3,7 +3,7 @@ use crate::{ tuple_debug, tuple_struct_debug, DynamicTypePath, DynamicTyped, OpaqueInfo, ReflectKind, ReflectKindMismatchError, ReflectMut, ReflectOwned, ReflectRef, TypeInfo, TypePath, Typed, }; -use std::{ +use core::{ any::{Any, TypeId}, fmt::Debug, }; @@ -253,7 +253,7 @@ where /// [`List`]: crate::List /// [`Map`]: crate::Map /// [type path]: TypePath::type_path - fn debug(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn debug(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { match self.reflect_ref() { ReflectRef::Struct(dyn_struct) => struct_debug(dyn_struct, f), ReflectRef::TupleStruct(dyn_tuple_struct) => tuple_struct_debug(dyn_tuple_struct, f), @@ -408,7 +408,7 @@ impl dyn PartialReflect { } impl Debug for dyn PartialReflect { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { self.debug(f) } } @@ -488,7 +488,7 @@ impl dyn Reflect { } impl Debug for dyn Reflect { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { self.debug(f) } } @@ -515,15 +515,15 @@ impl TypePath for dyn Reflect { macro_rules! impl_full_reflect { ($(<$($id:ident),* $(,)?>)? for $ty:ty $(where $($tt:tt)*)?) => { impl $(<$($id),*>)? $crate::Reflect for $ty $(where $($tt)*)? { - fn into_any(self: Box) -> Box { + fn into_any(self: Box) -> Box { self } - fn as_any(&self) -> &dyn ::std::any::Any { + fn as_any(&self) -> &dyn ::core::any::Any { self } - fn as_any_mut(&mut self) -> &mut dyn ::std::any::Any { + fn as_any_mut(&mut self) -> &mut dyn ::core::any::Any { self } diff --git a/crates/bevy_reflect/src/remote.rs b/crates/bevy_reflect/src/remote.rs index a19d3bdb148d6..22e663b20d7fa 100644 --- a/crates/bevy_reflect/src/remote.rs +++ b/crates/bevy_reflect/src/remote.rs @@ -41,7 +41,7 @@ use crate::Reflect; /// ``` /// /// [reflectable]: Reflect -/// [`transmute`]: core::mem::transmute +/// [`transmute`]: std::mem::transmute /// [very unsafe]: https://doc.rust-lang.org/1.71.0/nomicon/transmutes.html /// [`FromReflect`]: crate::FromReflect pub trait ReflectRemote: Reflect { diff --git a/crates/bevy_reflect/src/serde/de/arrays.rs b/crates/bevy_reflect/src/serde/de/arrays.rs index b1f7b60ffe350..24d009716a36c 100644 --- a/crates/bevy_reflect/src/serde/de/arrays.rs +++ b/crates/bevy_reflect/src/serde/de/arrays.rs @@ -2,9 +2,8 @@ use crate::{ serde::{de::registration_utils::try_get_registration, TypedReflectDeserializer}, ArrayInfo, DynamicArray, TypeRegistry, }; -use core::fmt::Formatter; +use core::{fmt, fmt::Formatter}; use serde::de::{Error, SeqAccess, Visitor}; -use std::fmt; /// A [`Visitor`] for deserializing [`Array`] values. /// diff --git a/crates/bevy_reflect/src/serde/de/deserializer.rs b/crates/bevy_reflect/src/serde/de/deserializer.rs index 0bd6be5bf3aa6..6eddc2deed076 100644 --- a/crates/bevy_reflect/src/serde/de/deserializer.rs +++ b/crates/bevy_reflect/src/serde/de/deserializer.rs @@ -11,9 +11,8 @@ use crate::{ }, PartialReflect, ReflectDeserialize, TypeInfo, TypeRegistration, TypeRegistry, }; -use core::fmt::Formatter; +use core::{fmt, fmt::Formatter}; use serde::de::{DeserializeSeed, Error, IgnoredAny, MapAccess, Visitor}; -use std::fmt; /// A general purpose deserializer for reflected types. /// diff --git a/crates/bevy_reflect/src/serde/de/enums.rs b/crates/bevy_reflect/src/serde/de/enums.rs index 90836c31f3d51..ecdcc1435c6b3 100644 --- a/crates/bevy_reflect/src/serde/de/enums.rs +++ b/crates/bevy_reflect/src/serde/de/enums.rs @@ -12,9 +12,8 @@ use crate::{ DynamicEnum, DynamicStruct, DynamicTuple, DynamicVariant, EnumInfo, StructVariantInfo, TupleVariantInfo, TypeRegistration, TypeRegistry, VariantInfo, }; -use core::fmt::Formatter; +use core::{fmt, fmt::Formatter}; use serde::de::{DeserializeSeed, EnumAccess, Error, MapAccess, SeqAccess, VariantAccess, Visitor}; -use std::fmt; /// A [`Visitor`] for deserializing [`Enum`] values. /// diff --git a/crates/bevy_reflect/src/serde/de/error_utils.rs b/crates/bevy_reflect/src/serde/de/error_utils.rs index 6a97c2518cbf7..f028976805791 100644 --- a/crates/bevy_reflect/src/serde/de/error_utils.rs +++ b/crates/bevy_reflect/src/serde/de/error_utils.rs @@ -6,7 +6,7 @@ thread_local! { /// The thread-local [`TypeInfoStack`] used for debugging. /// /// [`TypeInfoStack`]: crate::type_info_stack::TypeInfoStack - pub(super) static TYPE_INFO_STACK: std::cell::RefCell = const { std::cell::RefCell::new( + pub(super) static TYPE_INFO_STACK: core::cell::RefCell = const { core::cell::RefCell::new( crate::type_info_stack::TypeInfoStack::new() ) }; } diff --git a/crates/bevy_reflect/src/serde/de/helpers.rs b/crates/bevy_reflect/src/serde/de/helpers.rs index db4d5a35bb08d..bdb567a22eeb1 100644 --- a/crates/bevy_reflect/src/serde/de/helpers.rs +++ b/crates/bevy_reflect/src/serde/de/helpers.rs @@ -1,9 +1,11 @@ -use core::fmt::{Debug, Display, Formatter}; +use core::{ + fmt, + fmt::{Debug, Display, Formatter}, +}; use serde::{ de::{Error, Visitor}, Deserialize, }; -use std::fmt; /// A debug struct used for error messages that displays a list of expected values. /// diff --git a/crates/bevy_reflect/src/serde/de/lists.rs b/crates/bevy_reflect/src/serde/de/lists.rs index 82c5858f992c6..7d4ab44f8aea9 100644 --- a/crates/bevy_reflect/src/serde/de/lists.rs +++ b/crates/bevy_reflect/src/serde/de/lists.rs @@ -2,9 +2,8 @@ use crate::{ serde::{de::registration_utils::try_get_registration, TypedReflectDeserializer}, DynamicList, ListInfo, TypeRegistry, }; -use core::fmt::Formatter; +use core::{fmt, fmt::Formatter}; use serde::de::{SeqAccess, Visitor}; -use std::fmt; /// A [`Visitor`] for deserializing [`List`] values. /// diff --git a/crates/bevy_reflect/src/serde/de/maps.rs b/crates/bevy_reflect/src/serde/de/maps.rs index 1db14991368cf..fbb5f9d449208 100644 --- a/crates/bevy_reflect/src/serde/de/maps.rs +++ b/crates/bevy_reflect/src/serde/de/maps.rs @@ -2,9 +2,8 @@ use crate::{ serde::{de::registration_utils::try_get_registration, TypedReflectDeserializer}, DynamicMap, Map, MapInfo, TypeRegistry, }; -use core::fmt::Formatter; +use core::{fmt, fmt::Formatter}; use serde::de::{MapAccess, Visitor}; -use std::fmt; /// A [`Visitor`] for deserializing [`Map`] values. /// diff --git a/crates/bevy_reflect/src/serde/de/mod.rs b/crates/bevy_reflect/src/serde/de/mod.rs index 4ba84162c5b5c..482ce9fb6378c 100644 --- a/crates/bevy_reflect/src/serde/de/mod.rs +++ b/crates/bevy_reflect/src/serde/de/mod.rs @@ -21,7 +21,7 @@ mod tuples; #[cfg(test)] mod tests { use bincode::Options; - use std::{any::TypeId, f32::consts::PI, ops::RangeInclusive}; + use core::{any::TypeId, f32::consts::PI, ops::RangeInclusive}; use serde::{de::DeserializeSeed, Deserialize}; diff --git a/crates/bevy_reflect/src/serde/de/options.rs b/crates/bevy_reflect/src/serde/de/options.rs index 4713e7a8f594a..de9ded50750cb 100644 --- a/crates/bevy_reflect/src/serde/de/options.rs +++ b/crates/bevy_reflect/src/serde/de/options.rs @@ -5,9 +5,8 @@ use crate::{ }, DynamicEnum, DynamicTuple, EnumInfo, TypeRegistry, VariantInfo, }; -use core::fmt::Formatter; +use core::{fmt, fmt::Formatter}; use serde::de::{DeserializeSeed, Error, Visitor}; -use std::fmt; /// A [`Visitor`] for deserializing [`Option`] values. pub(super) struct OptionVisitor<'a> { diff --git a/crates/bevy_reflect/src/serde/de/registrations.rs b/crates/bevy_reflect/src/serde/de/registrations.rs index b80ff1874f9c3..adc0025c5489a 100644 --- a/crates/bevy_reflect/src/serde/de/registrations.rs +++ b/crates/bevy_reflect/src/serde/de/registrations.rs @@ -1,7 +1,6 @@ use crate::{serde::de::error_utils::make_custom_error, TypeRegistration, TypeRegistry}; -use core::fmt::Formatter; +use core::{fmt, fmt::Formatter}; use serde::de::{DeserializeSeed, Error, Visitor}; -use std::fmt; /// A deserializer for type registrations. /// diff --git a/crates/bevy_reflect/src/serde/de/sets.rs b/crates/bevy_reflect/src/serde/de/sets.rs index c1f668c960967..faecf5bc396e8 100644 --- a/crates/bevy_reflect/src/serde/de/sets.rs +++ b/crates/bevy_reflect/src/serde/de/sets.rs @@ -2,9 +2,8 @@ use crate::{ serde::{de::registration_utils::try_get_registration, TypedReflectDeserializer}, DynamicSet, Set, SetInfo, TypeRegistry, }; -use core::fmt::Formatter; +use core::{fmt, fmt::Formatter}; use serde::de::{SeqAccess, Visitor}; -use std::fmt; /// A [`Visitor`] for deserializing [`Set`] values. /// diff --git a/crates/bevy_reflect/src/serde/de/structs.rs b/crates/bevy_reflect/src/serde/de/structs.rs index 899e839004635..750c739e8ef5a 100644 --- a/crates/bevy_reflect/src/serde/de/structs.rs +++ b/crates/bevy_reflect/src/serde/de/structs.rs @@ -2,9 +2,8 @@ use crate::{ serde::de::struct_utils::{visit_struct, visit_struct_seq}, DynamicStruct, StructInfo, TypeRegistration, TypeRegistry, }; -use core::fmt::Formatter; +use core::{fmt, fmt::Formatter}; use serde::de::{MapAccess, SeqAccess, Visitor}; -use std::fmt; /// A [`Visitor`] for deserializing [`Struct`] values. /// diff --git a/crates/bevy_reflect/src/serde/de/tuple_structs.rs b/crates/bevy_reflect/src/serde/de/tuple_structs.rs index 3817c66c94059..e070142ab71c8 100644 --- a/crates/bevy_reflect/src/serde/de/tuple_structs.rs +++ b/crates/bevy_reflect/src/serde/de/tuple_structs.rs @@ -2,9 +2,8 @@ use crate::{ serde::de::tuple_utils::visit_tuple, DynamicTupleStruct, TupleStructInfo, TypeRegistration, TypeRegistry, }; -use core::fmt::Formatter; +use core::{fmt, fmt::Formatter}; use serde::de::{SeqAccess, Visitor}; -use std::fmt; /// A [`Visitor`] for deserializing [`TupleStruct`] values. /// diff --git a/crates/bevy_reflect/src/serde/de/tuples.rs b/crates/bevy_reflect/src/serde/de/tuples.rs index f182078186fb9..ea06ad3154db8 100644 --- a/crates/bevy_reflect/src/serde/de/tuples.rs +++ b/crates/bevy_reflect/src/serde/de/tuples.rs @@ -1,9 +1,8 @@ use crate::{ serde::de::tuple_utils::visit_tuple, DynamicTuple, TupleInfo, TypeRegistration, TypeRegistry, }; -use core::fmt::Formatter; +use core::{fmt, fmt::Formatter}; use serde::de::{SeqAccess, Visitor}; -use std::fmt; /// A [`Visitor`] for deserializing [`Tuple`] values. /// diff --git a/crates/bevy_reflect/src/serde/ser/error_utils.rs b/crates/bevy_reflect/src/serde/ser/error_utils.rs index 58a029f986588..8e6570c6691a2 100644 --- a/crates/bevy_reflect/src/serde/ser/error_utils.rs +++ b/crates/bevy_reflect/src/serde/ser/error_utils.rs @@ -6,7 +6,7 @@ thread_local! { /// The thread-local [`TypeInfoStack`] used for debugging. /// /// [`TypeInfoStack`]: crate::type_info_stack::TypeInfoStack - pub(super) static TYPE_INFO_STACK: std::cell::RefCell = const { std::cell::RefCell::new( + pub(super) static TYPE_INFO_STACK: core::cell::RefCell = const { core::cell::RefCell::new( crate::type_info_stack::TypeInfoStack::new() ) }; } diff --git a/crates/bevy_reflect/src/serde/ser/mod.rs b/crates/bevy_reflect/src/serde/ser/mod.rs index 42274c1563717..9ce71a839be35 100644 --- a/crates/bevy_reflect/src/serde/ser/mod.rs +++ b/crates/bevy_reflect/src/serde/ser/mod.rs @@ -20,9 +20,9 @@ mod tests { Struct, TypeRegistry, }; use bevy_utils::{HashMap, HashSet}; + use core::{f32::consts::PI, ops::RangeInclusive}; use ron::{extensions::Extensions, ser::PrettyConfig}; use serde::Serialize; - use std::{f32::consts::PI, ops::RangeInclusive}; #[derive(Reflect, Debug, PartialEq)] struct MyStruct { @@ -409,7 +409,7 @@ mod tests { serializer.serialize(&mut ser).unwrap(); - let output = std::str::from_utf8(&buf).unwrap(); + let output = core::str::from_utf8(&buf).unwrap(); let expected = r#"{ "bevy_reflect::serde::ser::tests::OtherStruct": { "some": { diff --git a/crates/bevy_reflect/src/serde/ser/serializable.rs b/crates/bevy_reflect/src/serde/ser/serializable.rs index 80f0ccca98484..3ca19a3912568 100644 --- a/crates/bevy_reflect/src/serde/ser/serializable.rs +++ b/crates/bevy_reflect/src/serde/ser/serializable.rs @@ -1,8 +1,8 @@ use crate::{ serde::ser::error_utils::make_custom_error, PartialReflect, ReflectSerialize, TypeRegistry, }; +use core::ops::Deref; use serde::ser::Error; -use std::ops::Deref; /// A type-erased serializable value. pub enum Serializable<'a> { diff --git a/crates/bevy_reflect/src/set.rs b/crates/bevy_reflect/src/set.rs index 49d3a09e30c1e..85bc57ca8431a 100644 --- a/crates/bevy_reflect/src/set.rs +++ b/crates/bevy_reflect/src/set.rs @@ -1,4 +1,4 @@ -use std::fmt::{Debug, Formatter}; +use core::fmt::{Debug, Formatter}; use bevy_reflect_derive::impl_type_path; use bevy_utils::hashbrown::{hash_table::OccupiedEntry as HashTableOccupiedEntry, HashTable}; @@ -310,7 +310,7 @@ impl PartialReflect for DynamicSet { set_partial_eq(self, value) } - fn debug(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + fn debug(&self, f: &mut Formatter<'_>) -> core::fmt::Result { write!(f, "DynamicSet(")?; set_debug(self, f)?; write!(f, ")") @@ -325,7 +325,7 @@ impl PartialReflect for DynamicSet { impl_type_path!((in bevy_reflect) DynamicSet); impl Debug for DynamicSet { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { self.debug(f) } } @@ -371,7 +371,7 @@ impl IntoIterator for DynamicSet { impl<'a> IntoIterator for &'a DynamicSet { type Item = &'a dyn PartialReflect; - type IntoIter = std::iter::Map< + type IntoIter = core::iter::Map< bevy_utils::hashbrown::hash_table::Iter<'a, Box>, fn(&'a Box) -> Self::Item, >; @@ -432,7 +432,7 @@ pub fn set_partial_eq(a: &M, b: &dyn PartialReflect) -> Option { /// // } /// ``` #[inline] -pub fn set_debug(dyn_set: &dyn Set, f: &mut Formatter<'_>) -> std::fmt::Result { +pub fn set_debug(dyn_set: &dyn Set, f: &mut Formatter<'_>) -> core::fmt::Result { let mut debug = f.debug_set(); for value in dyn_set.iter() { debug.entry(&value as &dyn Debug); diff --git a/crates/bevy_reflect/src/struct_trait.rs b/crates/bevy_reflect/src/struct_trait.rs index 1d571d8b45982..95e306361563c 100644 --- a/crates/bevy_reflect/src/struct_trait.rs +++ b/crates/bevy_reflect/src/struct_trait.rs @@ -5,13 +5,12 @@ use crate::{ ApplyError, NamedField, PartialReflect, Reflect, ReflectKind, ReflectMut, ReflectOwned, ReflectRef, Type, TypeInfo, TypePath, }; +use alloc::{borrow::Cow, sync::Arc}; use bevy_reflect_derive::impl_type_path; use bevy_utils::HashMap; -use std::{ - borrow::Cow, +use core::{ fmt::{Debug, Formatter}, slice::Iter, - sync::Arc, }; /// A trait used to power [struct-like] operations via [reflection]. @@ -450,7 +449,7 @@ impl PartialReflect for DynamicStruct { struct_partial_eq(self, value) } - fn debug(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + fn debug(&self, f: &mut Formatter<'_>) -> core::fmt::Result { write!(f, "DynamicStruct(")?; struct_debug(self, f)?; write!(f, ")") @@ -465,7 +464,7 @@ impl PartialReflect for DynamicStruct { impl_type_path!((in bevy_reflect) DynamicStruct); impl Debug for DynamicStruct { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { self.debug(f) } } @@ -487,7 +486,7 @@ where impl IntoIterator for DynamicStruct { type Item = Box; - type IntoIter = std::vec::IntoIter; + type IntoIter = alloc::vec::IntoIter; fn into_iter(self) -> Self::IntoIter { self.fields.into_iter() @@ -557,7 +556,7 @@ pub fn struct_partial_eq(a: &S, b: &dyn PartialReflect) -> O /// // } /// ``` #[inline] -pub fn struct_debug(dyn_struct: &dyn Struct, f: &mut Formatter<'_>) -> std::fmt::Result { +pub fn struct_debug(dyn_struct: &dyn Struct, f: &mut Formatter<'_>) -> core::fmt::Result { let mut debug = f.debug_struct( dyn_struct .get_represented_type_info() diff --git a/crates/bevy_reflect/src/tuple.rs b/crates/bevy_reflect/src/tuple.rs index 5aabdb67b2c87..6ec53efa514e4 100644 --- a/crates/bevy_reflect/src/tuple.rs +++ b/crates/bevy_reflect/src/tuple.rs @@ -7,7 +7,7 @@ use crate::{ ReflectOwned, ReflectRef, Type, TypeInfo, TypePath, TypeRegistration, TypeRegistry, Typed, UnnamedField, }; -use std::{ +use core::{ any::Any, fmt::{Debug, Formatter}, slice::Iter, @@ -341,7 +341,7 @@ impl PartialReflect for DynamicTuple { tuple_partial_eq(self, value) } - fn debug(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + fn debug(&self, f: &mut Formatter<'_>) -> core::fmt::Result { write!(f, "DynamicTuple(")?; tuple_debug(self, f)?; write!(f, ")") @@ -366,7 +366,7 @@ impl FromIterator> for DynamicTuple { impl IntoIterator for DynamicTuple { type Item = Box; - type IntoIter = std::vec::IntoIter; + type IntoIter = alloc::vec::IntoIter; fn into_iter(self) -> Self::IntoIter { self.fields.into_iter() @@ -460,7 +460,7 @@ pub fn tuple_partial_eq(a: &T, b: &dyn PartialReflect) -> Opt /// // ) /// ``` #[inline] -pub fn tuple_debug(dyn_tuple: &dyn Tuple, f: &mut Formatter<'_>) -> std::fmt::Result { +pub fn tuple_debug(dyn_tuple: &dyn Tuple, f: &mut Formatter<'_>) -> core::fmt::Result { let mut debug = f.debug_tuple(""); for field in dyn_tuple.iter_fields() { debug.field(&field as &dyn Debug); diff --git a/crates/bevy_reflect/src/tuple_struct.rs b/crates/bevy_reflect/src/tuple_struct.rs index ccf4a716e1e11..5fad54562e612 100644 --- a/crates/bevy_reflect/src/tuple_struct.rs +++ b/crates/bevy_reflect/src/tuple_struct.rs @@ -7,10 +7,10 @@ use crate::{ ApplyError, DynamicTuple, PartialReflect, Reflect, ReflectKind, ReflectMut, ReflectOwned, ReflectRef, Tuple, Type, TypeInfo, TypePath, UnnamedField, }; -use std::{ +use alloc::sync::Arc; +use core::{ fmt::{Debug, Formatter}, slice::Iter, - sync::Arc, }; /// A trait used to power [tuple struct-like] operations via [reflection]. @@ -357,7 +357,7 @@ impl PartialReflect for DynamicTupleStruct { tuple_struct_partial_eq(self, value) } - fn debug(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + fn debug(&self, f: &mut Formatter<'_>) -> core::fmt::Result { write!(f, "DynamicTupleStruct(")?; tuple_struct_debug(self, f)?; write!(f, ")") @@ -372,7 +372,7 @@ impl PartialReflect for DynamicTupleStruct { impl_type_path!((in bevy_reflect) DynamicTupleStruct); impl Debug for DynamicTupleStruct { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { self.debug(f) } } @@ -397,7 +397,7 @@ impl FromIterator> for DynamicTupleStruct { impl IntoIterator for DynamicTupleStruct { type Item = Box; - type IntoIter = std::vec::IntoIter; + type IntoIter = alloc::vec::IntoIter; fn into_iter(self) -> Self::IntoIter { self.fields.into_iter() @@ -469,7 +469,7 @@ pub fn tuple_struct_partial_eq( pub fn tuple_struct_debug( dyn_tuple_struct: &dyn TupleStruct, f: &mut Formatter<'_>, -) -> std::fmt::Result { +) -> core::fmt::Result { let mut debug = f.debug_tuple( dyn_tuple_struct .get_represented_type_info() diff --git a/crates/bevy_reflect/src/type_info.rs b/crates/bevy_reflect/src/type_info.rs index 8cfc23814ef52..aaa4b8861cf64 100644 --- a/crates/bevy_reflect/src/type_info.rs +++ b/crates/bevy_reflect/src/type_info.rs @@ -3,10 +3,9 @@ use crate::{ DynamicTupleStruct, EnumInfo, ListInfo, MapInfo, PartialReflect, Reflect, ReflectKind, SetInfo, StructInfo, TupleInfo, TupleStructInfo, TypePath, TypePathTable, }; -use core::fmt::Formatter; -use std::{ +use core::{ any::{Any, TypeId}, - fmt::Debug, + fmt::{Debug, Formatter}, hash::Hash, }; use thiserror::Error; @@ -462,7 +461,7 @@ impl PartialEq for Type { /// [type path]: TypePath impl Hash for Type { #[inline] - fn hash(&self, state: &mut H) { + fn hash(&self, state: &mut H) { self.type_id.hash(state); } } @@ -479,7 +478,7 @@ macro_rules! impl_type_methods { /// The [`TypeId`] of this type. /// /// [`TypeId`]: std::any::TypeId - pub fn type_id(&self) -> ::std::any::TypeId { + pub fn type_id(&self) -> ::core::any::TypeId { self.$field.id() } @@ -510,7 +509,7 @@ macro_rules! impl_type_methods { /// /// [`TypeId`]: std::any::TypeId /// [`TypePath`]: crate::type_path::TypePath - pub fn is(&self) -> bool { + pub fn is(&self) -> bool { self.$field.is::() } }; diff --git a/crates/bevy_reflect/src/type_path.rs b/crates/bevy_reflect/src/type_path.rs index bc685eb9f95cf..1287eeb8822cd 100644 --- a/crates/bevy_reflect/src/type_path.rs +++ b/crates/bevy_reflect/src/type_path.rs @@ -1,4 +1,4 @@ -use std::fmt; +use core::fmt; /// A static accessor to type paths and names. /// @@ -88,7 +88,7 @@ pub trait TypePath: 'static { /// /// Generic parameter types are also fully expanded. /// - /// For `Option>`, this is `"core::option::Option>"`. + /// For `Option>`, this is `"std::option::Option>"`. fn type_path() -> &'static str; /// Returns a short, pretty-print enabled path to the type. @@ -120,7 +120,7 @@ pub trait TypePath: 'static { /// Returns the path to the module the type is in, or [`None`] if it is [anonymous]. /// - /// For `Option>`, this is `"core::option"`. + /// For `Option>`, this is `"std::option"`. /// /// [anonymous]: TypePath#anonymity fn module_path() -> Option<&'static str> { diff --git a/crates/bevy_reflect/src/type_registry.rs b/crates/bevy_reflect/src/type_registry.rs index dfcdf1b4f9a5e..1b0fd84c71e0c 100644 --- a/crates/bevy_reflect/src/type_registry.rs +++ b/crates/bevy_reflect/src/type_registry.rs @@ -1,14 +1,15 @@ use crate::{serde::Serializable, FromReflect, Reflect, TypeInfo, TypePath, Typed}; +use alloc::sync::Arc; use bevy_ptr::{Ptr, PtrMut}; use bevy_utils::{HashMap, HashSet, TypeIdMap}; -use downcast_rs::{impl_downcast, Downcast}; -use serde::Deserialize; -use std::{ +use core::{ any::TypeId, fmt::Debug, ops::{Deref, DerefMut}, - sync::{Arc, PoisonError, RwLock, RwLockReadGuard, RwLockWriteGuard}, }; +use downcast_rs::{impl_downcast, Downcast}; +use serde::Deserialize; +use std::sync::{PoisonError, RwLock, RwLockReadGuard, RwLockWriteGuard}; /// A registry of [reflected] types. /// @@ -38,7 +39,7 @@ pub struct TypeRegistryArc { } impl Debug for TypeRegistryArc { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { self.internal .read() .unwrap_or_else(PoisonError::into_inner) @@ -265,7 +266,7 @@ impl TypeRegistry { panic!( "attempted to call `TypeRegistry::register_type_data` for type `{T}` with data `{D}` without registering `{T}` first", T = T::type_path(), - D = std::any::type_name::(), + D = core::any::type_name::(), ) }); data.insert(D::from_type()); @@ -469,7 +470,7 @@ pub struct TypeRegistration { } impl Debug for TypeRegistration { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { f.debug_struct("TypeRegistration") .field("type_info", &self.type_info) .finish() diff --git a/crates/bevy_reflect/src/utility.rs b/crates/bevy_reflect/src/utility.rs index 6eafc3e7c4287..2457db8faa8d3 100644 --- a/crates/bevy_reflect/src/utility.rs +++ b/crates/bevy_reflect/src/utility.rs @@ -2,11 +2,11 @@ use crate::TypeInfo; use bevy_utils::{FixedState, NoOpHash, TypeIdMap}; -use std::{ +use core::{ any::{Any, TypeId}, hash::BuildHasher, - sync::{OnceLock, PoisonError, RwLock}, }; +use std::sync::{OnceLock, PoisonError, RwLock}; /// A type that can be stored in a ([`Non`])[`GenericTypeCell`]. /// diff --git a/crates/bevy_remote/src/builtin_methods.rs b/crates/bevy_remote/src/builtin_methods.rs index 705b7600d0fc6..67a26e15f6df8 100644 --- a/crates/bevy_remote/src/builtin_methods.rs +++ b/crates/bevy_remote/src/builtin_methods.rs @@ -1,6 +1,6 @@ //! Built-in verbs for the Bevy Remote Protocol. -use std::any::TypeId; +use core::any::TypeId; use anyhow::{anyhow, Result as AnyhowResult}; use bevy_ecs::{ diff --git a/crates/bevy_remote/src/lib.rs b/crates/bevy_remote/src/lib.rs index 7b14b59f9e074..581d9752fbec1 100644 --- a/crates/bevy_remote/src/lib.rs +++ b/crates/bevy_remote/src/lib.rs @@ -247,10 +247,8 @@ #![cfg(not(target_family = "wasm"))] -use std::{ - net::{IpAddr, Ipv4Addr}, - sync::RwLock, -}; +use core::net::{IpAddr, Ipv4Addr}; +use std::sync::RwLock; use anyhow::Result as AnyhowResult; use bevy_app::prelude::*; diff --git a/crates/bevy_render/src/camera/camera.rs b/crates/bevy_render/src/camera/camera.rs index 1964b49562e0b..3fd905bdcf104 100644 --- a/crates/bevy_render/src/camera/camera.rs +++ b/crates/bevy_render/src/camera/camera.rs @@ -33,7 +33,7 @@ use bevy_window::{ NormalizedWindowRef, PrimaryWindow, Window, WindowCreated, WindowRef, WindowResized, WindowScaleFactorChanged, }; -use std::ops::Range; +use core::ops::Range; use wgpu::{BlendState, TextureFormat, TextureUsages}; use super::{ClearColorConfig, Projection}; @@ -1078,7 +1078,7 @@ pub fn sort_cameras( sorted_cameras .0 .sort_by(|c1, c2| match c1.order.cmp(&c2.order) { - std::cmp::Ordering::Equal => c1.target.cmp(&c2.target), + core::cmp::Ordering::Equal => c1.target.cmp(&c2.target), ord => ord, }); let mut previous_order_target = None; diff --git a/crates/bevy_render/src/camera/manual_texture_view.rs b/crates/bevy_render/src/camera/manual_texture_view.rs index 927e27bab66af..a1353b9d0f9c9 100644 --- a/crates/bevy_render/src/camera/manual_texture_view.rs +++ b/crates/bevy_render/src/camera/manual_texture_view.rs @@ -34,7 +34,7 @@ impl ManualTextureView { #[derive(Default, Clone, Resource, ExtractResource)] pub struct ManualTextureViews(HashMap); -impl std::ops::Deref for ManualTextureViews { +impl core::ops::Deref for ManualTextureViews { type Target = HashMap; fn deref(&self) -> &Self::Target { @@ -42,7 +42,7 @@ impl std::ops::Deref for ManualTextureViews { } } -impl std::ops::DerefMut for ManualTextureViews { +impl core::ops::DerefMut for ManualTextureViews { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 } diff --git a/crates/bevy_render/src/camera/projection.rs b/crates/bevy_render/src/camera/projection.rs index addeed4b0d1ae..91c9b9cc8d8ec 100644 --- a/crates/bevy_render/src/camera/projection.rs +++ b/crates/bevy_render/src/camera/projection.rs @@ -1,4 +1,4 @@ -use std::{ +use core::{ marker::PhantomData, ops::{Div, DivAssign, Mul, MulAssign}, }; @@ -221,7 +221,7 @@ impl CameraProjection for PerspectiveProjection { impl Default for PerspectiveProjection { fn default() -> Self { PerspectiveProjection { - fov: std::f32::consts::PI / 4.0, + fov: core::f32::consts::PI / 4.0, near: 0.1, far: 1000.0, aspect_ratio: 1.0, diff --git a/crates/bevy_render/src/diagnostic/internal.rs b/crates/bevy_render/src/diagnostic/internal.rs index 297e09863101b..e023fe9bd2323 100644 --- a/crates/bevy_render/src/diagnostic/internal.rs +++ b/crates/bevy_render/src/diagnostic/internal.rs @@ -1,12 +1,9 @@ -use std::{ - borrow::Cow, +use alloc::{borrow::Cow, sync::Arc}; +use core::{ ops::{DerefMut, Range}, - sync::{ - atomic::{AtomicBool, Ordering}, - Arc, - }, - thread::{self, ThreadId}, + sync::atomic::{AtomicBool, Ordering}, }; +use std::thread::{self, ThreadId}; use bevy_diagnostic::{Diagnostic, DiagnosticMeasurement, DiagnosticPath, DiagnosticsStore}; use bevy_ecs::system::{Res, ResMut, Resource}; @@ -117,7 +114,7 @@ impl DiagnosticsRecorder { None => FrameData::new(device, internal.features), }; - let old_frame = std::mem::replace( + let old_frame = core::mem::replace( internal.current_frame.get_mut().expect("lock poisoned"), new_frame, ); @@ -421,9 +418,9 @@ impl FrameData { fn diagnostic_path(&self, range: &Range, field: &str) -> DiagnosticPath { DiagnosticPath::from_components( - std::iter::once("render") + core::iter::once("render") .chain(self.path_components[range.clone()].iter().map(|v| &**v)) - .chain(std::iter::once(field)), + .chain(core::iter::once(field)), ) } diff --git a/crates/bevy_render/src/diagnostic/mod.rs b/crates/bevy_render/src/diagnostic/mod.rs index f64d17a1884c4..6e91e2a736e79 100644 --- a/crates/bevy_render/src/diagnostic/mod.rs +++ b/crates/bevy_render/src/diagnostic/mod.rs @@ -4,7 +4,8 @@ pub(crate) mod internal; -use std::{borrow::Cow, marker::PhantomData, sync::Arc}; +use alloc::{borrow::Cow, sync::Arc}; +use core::marker::PhantomData; use bevy_app::{App, Plugin, PreUpdate}; @@ -126,7 +127,7 @@ impl TimeSpanGuard<'_, R, E> { /// End the span. You have to provide the same encoder which was used to begin the span. pub fn end(self, encoder: &mut E) { self.recorder.end_time_span(encoder); - std::mem::forget(self); + core::mem::forget(self); } } @@ -148,7 +149,7 @@ impl PassSpanGuard<'_, R, P> { /// End the span. You have to provide the same encoder which was used to begin the span. pub fn end(self, pass: &mut P) { self.recorder.end_pass_span(pass); - std::mem::forget(self); + core::mem::forget(self); } } diff --git a/crates/bevy_render/src/extract_component.rs b/crates/bevy_render/src/extract_component.rs index 4b327cf6af3e8..01b6b06ceacaa 100644 --- a/crates/bevy_render/src/extract_component.rs +++ b/crates/bevy_render/src/extract_component.rs @@ -12,7 +12,7 @@ use bevy_ecs::{ query::{QueryFilter, QueryItem, ReadOnlyQueryData}, system::lifetimeless::Read, }; -use std::{marker::PhantomData, ops::Deref}; +use core::{marker::PhantomData, ops::Deref}; pub use bevy_render_macros::ExtractComponent; diff --git a/crates/bevy_render/src/extract_instances.rs b/crates/bevy_render/src/extract_instances.rs index 537ca5f11e439..37edd85076b03 100644 --- a/crates/bevy_render/src/extract_instances.rs +++ b/crates/bevy_render/src/extract_instances.rs @@ -4,7 +4,7 @@ //! This is essentially the same as the `extract_component` module, but //! higher-performance because it avoids the ECS overhead. -use std::marker::PhantomData; +use core::marker::PhantomData; use bevy_app::{App, Plugin}; use bevy_asset::{Asset, AssetId, Handle}; diff --git a/crates/bevy_render/src/extract_param.rs b/crates/bevy_render/src/extract_param.rs index 6635dd270ce3e..914fe32dfb6e4 100644 --- a/crates/bevy_render/src/extract_param.rs +++ b/crates/bevy_render/src/extract_param.rs @@ -5,7 +5,7 @@ use bevy_ecs::{ system::{ReadOnlySystemParam, SystemMeta, SystemParam, SystemParamItem, SystemState}, world::unsafe_world_cell::UnsafeWorldCell, }; -use std::ops::{Deref, DerefMut}; +use core::ops::{Deref, DerefMut}; /// A helper for accessing [`MainWorld`] content using a system parameter. /// diff --git a/crates/bevy_render/src/extract_resource.rs b/crates/bevy_render/src/extract_resource.rs index 63a6c42dc4a20..2d36e694be7e5 100644 --- a/crates/bevy_render/src/extract_resource.rs +++ b/crates/bevy_render/src/extract_resource.rs @@ -1,4 +1,4 @@ -use std::marker::PhantomData; +use core::marker::PhantomData; use bevy_app::{App, Plugin}; use bevy_ecs::prelude::*; @@ -36,7 +36,7 @@ impl Plugin for ExtractResourcePlugin { } else { bevy_utils::error_once!( "Render app did not exist when trying to add `extract_resource` for <{}>.", - std::any::type_name::() + core::any::type_name::() ); } } @@ -59,7 +59,7 @@ pub fn extract_resource( bevy_utils::warn_once!( "Removing resource {} from render world not expected, adding using `Commands`. This may decrease performance", - std::any::type_name::() + core::any::type_name::() ); } commands.insert_resource(R::extract_resource(main_resource)); diff --git a/crates/bevy_render/src/gpu_component_array_buffer.rs b/crates/bevy_render/src/gpu_component_array_buffer.rs index 44e7d8c14cd7c..ac0f471a4a235 100644 --- a/crates/bevy_render/src/gpu_component_array_buffer.rs +++ b/crates/bevy_render/src/gpu_component_array_buffer.rs @@ -9,7 +9,7 @@ use bevy_ecs::{ schedule::IntoSystemConfigs, system::{Commands, Query, Res, ResMut}, }; -use std::marker::PhantomData; +use core::marker::PhantomData; /// This plugin prepares the components of the corresponding type for the GPU /// by storing them in a [`GpuArrayBuffer`]. diff --git a/crates/bevy_render/src/lib.rs b/crates/bevy_render/src/lib.rs index 1c2b7658e16ce..81ac6eb47c757 100644 --- a/crates/bevy_render/src/lib.rs +++ b/crates/bevy_render/src/lib.rs @@ -12,6 +12,7 @@ #[cfg(target_pointer_width = "16")] compile_error!("bevy_render cannot compile for a 16-bit platform."); +extern crate alloc; extern crate core; pub mod alpha; @@ -81,14 +82,13 @@ use crate::{ storage::StoragePlugin, view::{ViewPlugin, WindowRenderPlugin}, }; +use alloc::sync::Arc; use bevy_app::{App, AppLabel, Plugin, SubApp}; use bevy_asset::{load_internal_asset, AssetApp, AssetServer, Handle}; use bevy_ecs::{prelude::*, schedule::ScheduleLabel, system::SystemState}; use bevy_utils::tracing::debug; -use std::{ - ops::{Deref, DerefMut}, - sync::{Arc, Mutex}, -}; +use core::ops::{Deref, DerefMut}; +use std::sync::Mutex; /// Contains the default Bevy rendering backend based on wgpu. /// @@ -436,13 +436,13 @@ struct ScratchMainWorld(World); fn extract(main_world: &mut World, render_world: &mut World) { // temporarily add the app world to the render world as a resource let scratch_world = main_world.remove_resource::().unwrap(); - let inserted_world = std::mem::replace(main_world, scratch_world.0); + let inserted_world = core::mem::replace(main_world, scratch_world.0); render_world.insert_resource(MainWorld(inserted_world)); render_world.run_schedule(ExtractSchedule); // move the app world back, as if nothing happened. let inserted_world = render_world.remove_resource::().unwrap(); - let scratch_world = std::mem::replace(main_world, inserted_world.0); + let scratch_world = core::mem::replace(main_world, inserted_world.0); main_world.insert_resource(ScratchMainWorld(scratch_world)); } diff --git a/crates/bevy_render/src/mesh/allocator.rs b/crates/bevy_render/src/mesh/allocator.rs index 94186517a4d9f..e20cb1774453e 100644 --- a/crates/bevy_render/src/mesh/allocator.rs +++ b/crates/bevy_render/src/mesh/allocator.rs @@ -1,11 +1,10 @@ //! Manages mesh vertex and index buffers. -use std::{ - borrow::Cow, +use alloc::{borrow::Cow, vec::Vec}; +use core::{ fmt::{self, Display, Formatter}, iter, ops::Range, - vec::Vec, }; use bevy_app::{App, Plugin}; diff --git a/crates/bevy_render/src/mesh/mesh/conversions.rs b/crates/bevy_render/src/mesh/mesh/conversions.rs index f067839b325a2..3f3c8c2ae3243 100644 --- a/crates/bevy_render/src/mesh/mesh/conversions.rs +++ b/crates/bevy_render/src/mesh/mesh/conversions.rs @@ -40,7 +40,7 @@ impl FromVertexAttributeError { fn new(from: VertexAttributeValues) -> Self { Self { variant: from.enum_variant_name(), - into: std::any::type_name::(), + into: core::any::type_name::(), from, } } diff --git a/crates/bevy_render/src/mesh/mesh/mod.rs b/crates/bevy_render/src/mesh/mesh/mod.rs index 954a585b57c99..46faf1908eff5 100644 --- a/crates/bevy_render/src/mesh/mesh/mod.rs +++ b/crates/bevy_render/src/mesh/mesh/mod.rs @@ -11,6 +11,7 @@ use crate::{ render_resource::{TextureView, VertexBufferLayout}, texture::GpuImage, }; +use alloc::collections::BTreeMap; use bevy_asset::{Asset, Handle}; use bevy_derive::EnumVariantMeta; use bevy_ecs::system::{ @@ -21,7 +22,7 @@ use bevy_math::{primitives::Triangle3d, *}; use bevy_reflect::Reflect; use bevy_utils::tracing::{error, warn}; use bytemuck::cast_slice; -use std::{collections::BTreeMap, hash::Hash, iter::FusedIterator}; +use core::{hash::Hash, iter::FusedIterator}; use thiserror::Error; use wgpu::{IndexFormat, VertexAttribute, VertexFormat, VertexStepMode}; @@ -364,7 +365,7 @@ impl Mesh { /// Removes the vertex `indices` from the mesh and returns them. #[inline] pub fn remove_indices(&mut self) -> Option { - std::mem::take(&mut self.indices) + core::mem::take(&mut self.indices) } /// Consumes the mesh and returns a mesh without the vertex `indices` of the mesh. @@ -441,7 +442,7 @@ impl Mesh { warn!("{name} has a different vertex count ({attribute_len}) than other attributes ({previous_vertex_count}) in this mesh, \ all attributes will be truncated to match the smallest."); - vertex_count = Some(std::cmp::min(previous_vertex_count, attribute_len)); + vertex_count = Some(core::cmp::min(previous_vertex_count, attribute_len)); } } else { vertex_count = Some(attribute_len); @@ -570,7 +571,7 @@ impl Mesh { let [_, b, c] = chunk else { return Err(MeshWindingInvertError::AbruptIndicesEnd); }; - std::mem::swap(b, c); + core::mem::swap(b, c); } Ok(()) } @@ -1657,8 +1658,8 @@ impl Indices { /// An Iterator for the [`Indices`]. enum IndicesIter<'a> { - U16(std::slice::Iter<'a, u16>), - U32(std::slice::Iter<'a, u32>), + U16(core::slice::Iter<'a, u16>), + U32(core::slice::Iter<'a, u32>), } impl Iterator for IndicesIter<'_> { diff --git a/crates/bevy_render/src/mesh/mesh/skinning.rs b/crates/bevy_render/src/mesh/mesh/skinning.rs index e7a91252e7f65..016f0b9567264 100644 --- a/crates/bevy_render/src/mesh/mesh/skinning.rs +++ b/crates/bevy_render/src/mesh/mesh/skinning.rs @@ -7,7 +7,7 @@ use bevy_ecs::{ }; use bevy_math::Mat4; use bevy_reflect::prelude::*; -use std::ops::Deref; +use core::ops::Deref; #[derive(Component, Debug, Default, Clone, Reflect)] #[reflect(Component, MapEntities, Default, Debug)] diff --git a/crates/bevy_render/src/mesh/mod.rs b/crates/bevy_render/src/mesh/mod.rs index 84accac658236..6897e1d176f74 100644 --- a/crates/bevy_render/src/mesh/mod.rs +++ b/crates/bevy_render/src/mesh/mod.rs @@ -5,14 +5,12 @@ pub mod allocator; pub mod morph; pub mod primitives; +use alloc::sync::Arc; use allocator::MeshAllocatorPlugin; use bevy_utils::HashSet; +use core::hash::{Hash, Hasher}; pub use mesh::*; pub use primitives::*; -use std::{ - hash::{Hash, Hasher}, - sync::Arc, -}; use crate::{render_asset::RenderAssetPlugin, texture::GpuImage, RenderApp}; use bevy_app::{App, Plugin}; diff --git a/crates/bevy_render/src/mesh/morph.rs b/crates/bevy_render/src/mesh/morph.rs index e44dd65b44e66..db28ed5afea0e 100644 --- a/crates/bevy_render/src/mesh/morph.rs +++ b/crates/bevy_render/src/mesh/morph.rs @@ -11,7 +11,7 @@ use bevy_hierarchy::Children; use bevy_math::Vec3; use bevy_reflect::prelude::*; use bytemuck::{Pod, Zeroable}; -use std::iter; +use core::iter; use thiserror::Error; const MAX_TEXTURE_WIDTH: u32 = 2048; diff --git a/crates/bevy_render/src/mesh/primitives/dim2.rs b/crates/bevy_render/src/mesh/primitives/dim2.rs index a7183f99f2fc5..fc117a6f5dae5 100644 --- a/crates/bevy_render/src/mesh/primitives/dim2.rs +++ b/crates/bevy_render/src/mesh/primitives/dim2.rs @@ -1,4 +1,4 @@ -use std::f32::consts::FRAC_PI_2; +use core::f32::consts::FRAC_PI_2; use crate::{ mesh::{primitives::dim3::triangle3d, Indices, Mesh, PerimeterSegment}, @@ -489,7 +489,7 @@ impl MeshBuilder for EllipseMeshBuilder { // Add pi/2 so that there is a vertex at the top (sin is 1.0 and cos is 0.0) let start_angle = FRAC_PI_2; - let step = std::f32::consts::TAU / self.resolution as f32; + let step = core::f32::consts::TAU / self.resolution as f32; for i in 0..self.resolution { // Compute vertex position at angle theta @@ -597,7 +597,7 @@ impl MeshBuilder for AnnulusMeshBuilder { // mapping. Here, each iteration places a pair of vertices at a fixed // angle from the center of the annulus. let start_angle = FRAC_PI_2; - let step = std::f32::consts::TAU / self.resolution as f32; + let step = core::f32::consts::TAU / self.resolution as f32; for i in 0..=self.resolution { let theta = start_angle + (i % self.resolution) as f32 * step; let (sin, cos) = ops::sin_cos(theta); @@ -898,7 +898,7 @@ impl MeshBuilder for Capsule2dMeshBuilder { let mut uvs = Vec::with_capacity(vertex_count as usize); let radius = self.capsule.radius; - let step = std::f32::consts::TAU / vertex_count as f32; + let step = core::f32::consts::TAU / vertex_count as f32; // If the vertex count is even, offset starting angle of top semicircle by half a step // to position the vertices evenly. diff --git a/crates/bevy_render/src/mesh/primitives/dim3/capsule.rs b/crates/bevy_render/src/mesh/primitives/dim3/capsule.rs index eeea5e906f1eb..33fe54d3d82b3 100644 --- a/crates/bevy_render/src/mesh/primitives/dim3/capsule.rs +++ b/crates/bevy_render/src/mesh/primitives/dim3/capsule.rs @@ -136,8 +136,8 @@ impl MeshBuilder for Capsule3dMeshBuilder { let mut vts: Vec = vec![Vec2::ZERO; vert_len]; let mut vns: Vec = vec![Vec3::ZERO; vert_len]; - let to_theta = 2.0 * std::f32::consts::PI / longitudes as f32; - let to_phi = std::f32::consts::PI / latitudes as f32; + let to_theta = 2.0 * core::f32::consts::PI / longitudes as f32; + let to_phi = core::f32::consts::PI / latitudes as f32; let to_tex_horizontal = 1.0 / longitudes as f32; let to_tex_vertical = 1.0 / half_lats as f32; diff --git a/crates/bevy_render/src/mesh/primitives/dim3/cone.rs b/crates/bevy_render/src/mesh/primitives/dim3/cone.rs index 7ad5394a3c055..51e18e20c40d4 100644 --- a/crates/bevy_render/src/mesh/primitives/dim3/cone.rs +++ b/crates/bevy_render/src/mesh/primitives/dim3/cone.rs @@ -111,7 +111,7 @@ impl MeshBuilder for ConeMeshBuilder { let normalization_factor = (1.0 + normal_slope * normal_slope).sqrt().recip(); // How much the angle changes at each step - let step_theta = std::f32::consts::TAU / self.resolution as f32; + let step_theta = core::f32::consts::TAU / self.resolution as f32; // Add vertices for the bottom of the lateral surface. for segment in 0..self.resolution { diff --git a/crates/bevy_render/src/mesh/primitives/dim3/conical_frustum.rs b/crates/bevy_render/src/mesh/primitives/dim3/conical_frustum.rs index 3b7da0bea5b57..cf3d160ffb4b1 100644 --- a/crates/bevy_render/src/mesh/primitives/dim3/conical_frustum.rs +++ b/crates/bevy_render/src/mesh/primitives/dim3/conical_frustum.rs @@ -83,7 +83,7 @@ impl MeshBuilder for ConicalFrustumMeshBuilder { let mut uvs = Vec::with_capacity(num_vertices); let mut indices = Vec::with_capacity(num_indices); - let step_theta = std::f32::consts::TAU / self.resolution as f32; + let step_theta = core::f32::consts::TAU / self.resolution as f32; let step_y = height / self.segments as f32; let step_radius = (radius_top - radius_bottom) / self.segments as f32; diff --git a/crates/bevy_render/src/mesh/primitives/dim3/cylinder.rs b/crates/bevy_render/src/mesh/primitives/dim3/cylinder.rs index c6522d98c7808..67a81afc964d3 100644 --- a/crates/bevy_render/src/mesh/primitives/dim3/cylinder.rs +++ b/crates/bevy_render/src/mesh/primitives/dim3/cylinder.rs @@ -112,7 +112,7 @@ impl MeshBuilder for CylinderMeshBuilder { let mut uvs = Vec::with_capacity(num_vertices as usize); let mut indices = Vec::with_capacity(num_indices as usize); - let step_theta = std::f32::consts::TAU / resolution as f32; + let step_theta = core::f32::consts::TAU / resolution as f32; let step_y = 2.0 * self.cylinder.half_height / segments as f32; // rings diff --git a/crates/bevy_render/src/mesh/primitives/dim3/sphere.rs b/crates/bevy_render/src/mesh/primitives/dim3/sphere.rs index 0d2e4e84d8c5a..5ab6257029534 100644 --- a/crates/bevy_render/src/mesh/primitives/dim3/sphere.rs +++ b/crates/bevy_render/src/mesh/primitives/dim3/sphere.rs @@ -1,4 +1,4 @@ -use std::f32::consts::PI; +use core::f32::consts::PI; use crate::{ mesh::{Indices, Mesh, MeshBuilder, Meshable}, @@ -124,7 +124,7 @@ impl SphereMeshBuilder { let azimuth = ops::atan2(point.z, point.x); let norm_inclination = inclination / PI; - let norm_azimuth = 0.5 - (azimuth / std::f32::consts::TAU); + let norm_azimuth = 0.5 - (azimuth / core::f32::consts::TAU); [norm_azimuth, norm_inclination] }); diff --git a/crates/bevy_render/src/mesh/primitives/dim3/torus.rs b/crates/bevy_render/src/mesh/primitives/dim3/torus.rs index 0dcbd68353da9..e0d56a67613a5 100644 --- a/crates/bevy_render/src/mesh/primitives/dim3/torus.rs +++ b/crates/bevy_render/src/mesh/primitives/dim3/torus.rs @@ -1,5 +1,5 @@ use bevy_math::{ops, primitives::Torus, Vec3}; -use std::ops::RangeInclusive; +use core::ops::RangeInclusive; use wgpu::PrimitiveTopology; use crate::{ @@ -34,7 +34,7 @@ impl Default for TorusMeshBuilder { torus: Torus::default(), minor_resolution: 24, major_resolution: 32, - angle_range: (0.0..=2.0 * std::f32::consts::PI), + angle_range: (0.0..=2.0 * core::f32::consts::PI), } } } @@ -91,7 +91,7 @@ impl MeshBuilder for TorusMeshBuilder { let end_angle = self.angle_range.end(); let segment_stride = (end_angle - start_angle) / self.major_resolution as f32; - let side_stride = 2.0 * std::f32::consts::PI / self.minor_resolution as f32; + let side_stride = 2.0 * core::f32::consts::PI / self.minor_resolution as f32; for segment in 0..=self.major_resolution { let theta = start_angle + segment_stride * segment as f32; diff --git a/crates/bevy_render/src/primitives/mod.rs b/crates/bevy_render/src/primitives/mod.rs index b1d2ead40c311..c2909b795b295 100644 --- a/crates/bevy_render/src/primitives/mod.rs +++ b/crates/bevy_render/src/primitives/mod.rs @@ -1,4 +1,4 @@ -use std::borrow::Borrow; +use core::borrow::Borrow; use bevy_ecs::{component::Component, entity::EntityHashMap, reflect::ReflectComponent}; use bevy_math::{Affine3A, Mat3A, Mat4, Vec3, Vec3A, Vec4, Vec4Swizzles}; diff --git a/crates/bevy_render/src/render_asset.rs b/crates/bevy_render/src/render_asset.rs index 5705e0ba71154..46ee40fd20ef8 100644 --- a/crates/bevy_render/src/render_asset.rs +++ b/crates/bevy_render/src/render_asset.rs @@ -15,8 +15,8 @@ use bevy_utils::{ tracing::{debug, error}, HashMap, HashSet, }; +use core::marker::PhantomData; use serde::{Deserialize, Serialize}; -use std::marker::PhantomData; use thiserror::Error; #[derive(Debug, Error)] @@ -337,7 +337,7 @@ pub fn prepare_assets( let mut wrote_asset_count = 0; let mut param = param.into_inner(); - let queued_assets = std::mem::take(&mut prepare_next_frame.assets); + let queued_assets = core::mem::take(&mut prepare_next_frame.assets); for (id, extracted_asset) in queued_assets { if extracted_assets.removed.contains(&id) || extracted_assets.added.contains(&id) { // skip previous frame's assets that have been removed or updated @@ -370,7 +370,7 @@ pub fn prepare_assets( Err(PrepareAssetError::AsBindGroupError(e)) => { error!( "{} Bind group construction failed: {e}", - std::any::type_name::() + core::any::type_name::() ); } } @@ -408,7 +408,7 @@ pub fn prepare_assets( Err(PrepareAssetError::AsBindGroupError(e)) => { error!( "{} Bind group construction failed: {e}", - std::any::type_name::() + core::any::type_name::() ); } } @@ -417,7 +417,7 @@ pub fn prepare_assets( if bpf.exhausted() && !prepare_next_frame.assets.is_empty() { debug!( "{} write budget exhausted with {} assets remaining (wrote {})", - std::any::type_name::(), + core::any::type_name::(), prepare_next_frame.assets.len(), wrote_asset_count ); diff --git a/crates/bevy_render/src/render_graph/context.rs b/crates/bevy_render/src/render_graph/context.rs index 1cf2dc89570fa..c27f269d0ba45 100644 --- a/crates/bevy_render/src/render_graph/context.rs +++ b/crates/bevy_render/src/render_graph/context.rs @@ -2,8 +2,8 @@ use crate::{ render_graph::{NodeState, RenderGraph, SlotInfos, SlotLabel, SlotType, SlotValue}, render_resource::{Buffer, Sampler, TextureView}, }; +use alloc::borrow::Cow; use bevy_ecs::entity::Entity; -use std::borrow::Cow; use thiserror::Error; use super::{InternedRenderSubGraph, RenderSubGraph}; diff --git a/crates/bevy_render/src/render_graph/graph.rs b/crates/bevy_render/src/render_graph/graph.rs index d8af4d9289263..4b315e22a0869 100644 --- a/crates/bevy_render/src/render_graph/graph.rs +++ b/crates/bevy_render/src/render_graph/graph.rs @@ -7,7 +7,7 @@ use crate::{ }; use bevy_ecs::{define_label, intern::Interned, prelude::World, system::Resource}; use bevy_utils::HashMap; -use std::fmt::Debug; +use core::fmt::Debug; use super::{EdgeExistence, InternedRenderLabel, IntoRenderNodeArray}; @@ -627,7 +627,7 @@ impl RenderGraph { } impl Debug for RenderGraph { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { for node in self.iter_nodes() { writeln!(f, "{:?}", node.label)?; writeln!(f, " in: {:?}", node.input_slots)?; diff --git a/crates/bevy_render/src/render_graph/node.rs b/crates/bevy_render/src/render_graph/node.rs index 8528457d420a1..9406baf580d02 100644 --- a/crates/bevy_render/src/render_graph/node.rs +++ b/crates/bevy_render/src/render_graph/node.rs @@ -14,8 +14,8 @@ use bevy_ecs::{ world::{FromWorld, World}, }; use bevy_utils::all_tuples_with_size; +use core::fmt::Debug; use downcast_rs::{impl_downcast, Downcast}; -use std::fmt::Debug; use thiserror::Error; pub use bevy_render_macros::RenderLabel; @@ -229,7 +229,7 @@ pub struct NodeState { } impl Debug for NodeState { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { writeln!(f, "{:?} ({:?})", self.label, self.type_name) } } @@ -246,7 +246,7 @@ impl NodeState { input_slots: node.input().into(), output_slots: node.output().into(), node: Box::new(node), - type_name: std::any::type_name::(), + type_name: core::any::type_name::(), edges: Edges { label, input_edges: Vec::new(), diff --git a/crates/bevy_render/src/render_graph/node_slot.rs b/crates/bevy_render/src/render_graph/node_slot.rs index fd5dc388d3812..81a736754017e 100644 --- a/crates/bevy_render/src/render_graph/node_slot.rs +++ b/crates/bevy_render/src/render_graph/node_slot.rs @@ -1,5 +1,6 @@ +use alloc::borrow::Cow; use bevy_ecs::entity::Entity; -use std::{borrow::Cow, fmt}; +use core::fmt; use crate::render_resource::{Buffer, Sampler, TextureView}; diff --git a/crates/bevy_render/src/render_phase/draw.rs b/crates/bevy_render/src/render_phase/draw.rs index 41a5f49897ec9..2deafa4bf2396 100644 --- a/crates/bevy_render/src/render_phase/draw.rs +++ b/crates/bevy_render/src/render_phase/draw.rs @@ -7,12 +7,8 @@ use bevy_ecs::{ world::World, }; use bevy_utils::{all_tuples, TypeIdMap}; -use std::{ - any::TypeId, - fmt::Debug, - hash::Hash, - sync::{PoisonError, RwLock, RwLockReadGuard, RwLockWriteGuard}, -}; +use core::{any::TypeId, fmt::Debug, hash::Hash}; +use std::sync::{PoisonError, RwLock, RwLockReadGuard, RwLockWriteGuard}; use thiserror::Error; /// A draw function used to draw [`PhaseItem`]s. @@ -102,8 +98,8 @@ impl DrawFunctionsInternal

{ self.get_id::().unwrap_or_else(|| { panic!( "Draw function {} not found for {}", - std::any::type_name::(), - std::any::type_name::

() + core::any::type_name::(), + core::any::type_name::

() ) }) } @@ -168,7 +164,7 @@ impl DrawFunctions

{ /// # use bevy_render::render_phase::SetItemPipeline; /// # struct SetMeshViewBindGroup; /// # struct SetMeshBindGroup; -/// # struct SetMaterialBindGroup(core::marker::PhantomData); +/// # struct SetMaterialBindGroup(std::marker::PhantomData); /// # struct DrawMesh; /// pub type DrawMaterial = ( /// SetItemPipeline, @@ -366,7 +362,7 @@ impl AddRenderCommand for SubApp { panic!( "DrawFunctions<{}> must be added to the world as a resource \ before adding render commands to it", - std::any::type_name::

(), + core::any::type_name::

(), ); }); draw_functions.write().add_with::(draw_function); diff --git a/crates/bevy_render/src/render_phase/draw_state.rs b/crates/bevy_render/src/render_phase/draw_state.rs index f19dff1971b3c..4ba3e410870a5 100644 --- a/crates/bevy_render/src/render_phase/draw_state.rs +++ b/crates/bevy_render/src/render_phase/draw_state.rs @@ -9,7 +9,7 @@ use crate::{ }; use bevy_color::LinearRgba; use bevy_utils::{default, detailed_trace}; -use std::ops::Range; +use core::ops::Range; use wgpu::{IndexFormat, QuerySet, RenderPass}; /// Tracks the state of a [`TrackedRenderPass`]. diff --git a/crates/bevy_render/src/render_phase/mod.rs b/crates/bevy_render/src/render_phase/mod.rs index 1bc1ee52ca687..2fa3e673640e4 100644 --- a/crates/bevy_render/src/render_phase/mod.rs +++ b/crates/bevy_render/src/render_phase/mod.rs @@ -52,8 +52,7 @@ use bevy_ecs::{ prelude::*, system::{lifetimeless::SRes, SystemParamItem}, }; -use smallvec::SmallVec; -use std::{ +use core::{ fmt::{self, Debug, Formatter}, hash::Hash, iter, @@ -61,6 +60,7 @@ use std::{ ops::Range, slice::SliceIndex, }; +use smallvec::SmallVec; /// Stores the rendering instructions for a single phase that uses bins in all /// views. diff --git a/crates/bevy_render/src/render_resource/batched_uniform_buffer.rs b/crates/bevy_render/src/render_resource/batched_uniform_buffer.rs index 75a747cf46fe3..f2d8d430c58fe 100644 --- a/crates/bevy_render/src/render_resource/batched_uniform_buffer.rs +++ b/crates/bevy_render/src/render_resource/batched_uniform_buffer.rs @@ -3,12 +3,12 @@ use crate::{ render_resource::DynamicUniformBuffer, renderer::{RenderDevice, RenderQueue}, }; +use core::{marker::PhantomData, num::NonZero}; use encase::{ private::{ArrayMetadata, BufferMut, Metadata, RuntimeSizedArray, WriteInto, Writer}, ShaderType, }; use nonmax::NonMaxU32; -use std::{marker::PhantomData, num::NonZero}; use wgpu::{BindingResource, Limits}; // 1MB else we will make really large arrays on macOS which reports very large diff --git a/crates/bevy_render/src/render_resource/bind_group.rs b/crates/bevy_render/src/render_resource/bind_group.rs index 0ecca1e43112b..44596d19c8cb5 100644 --- a/crates/bevy_render/src/render_resource/bind_group.rs +++ b/crates/bevy_render/src/render_resource/bind_group.rs @@ -7,8 +7,8 @@ use crate::{ }; use bevy_ecs::system::{SystemParam, SystemParamItem}; pub use bevy_render_macros::AsBindGroup; +use core::ops::Deref; use encase::ShaderType; -use std::ops::Deref; use thiserror::Error; use wgpu::{BindGroupEntry, BindGroupLayoutEntry, BindingResource}; diff --git a/crates/bevy_render/src/render_resource/bind_group_entries.rs b/crates/bevy_render/src/render_resource/bind_group_entries.rs index 33260f985067d..316bfa118546a 100644 --- a/crates/bevy_render/src/render_resource/bind_group_entries.rs +++ b/crates/bevy_render/src/render_resource/bind_group_entries.rs @@ -129,7 +129,7 @@ impl<'b> BindGroupEntries<'b, 1> { } } -impl<'b, const N: usize> std::ops::Deref for BindGroupEntries<'b, N> { +impl<'b, const N: usize> core::ops::Deref for BindGroupEntries<'b, N> { type Target = [BindGroupEntry<'b>]; fn deref(&self) -> &[BindGroupEntry<'b>] { @@ -273,7 +273,7 @@ impl<'b> DynamicBindGroupEntries<'b> { } } -impl<'b> std::ops::Deref for DynamicBindGroupEntries<'b> { +impl<'b> core::ops::Deref for DynamicBindGroupEntries<'b> { type Target = [BindGroupEntry<'b>]; fn deref(&self) -> &[BindGroupEntry<'b>] { diff --git a/crates/bevy_render/src/render_resource/bind_group_layout.rs b/crates/bevy_render/src/render_resource/bind_group_layout.rs index 9793f1391d188..201237a64d537 100644 --- a/crates/bevy_render/src/render_resource/bind_group_layout.rs +++ b/crates/bevy_render/src/render_resource/bind_group_layout.rs @@ -1,5 +1,5 @@ use crate::{define_atomic_id, render_resource::resource_macros::*}; -use std::ops::Deref; +use core::ops::Deref; define_atomic_id!(BindGroupLayoutId); render_resource_wrapper!(ErasedBindGroupLayout, wgpu::BindGroupLayout); diff --git a/crates/bevy_render/src/render_resource/bind_group_layout_entries.rs b/crates/bevy_render/src/render_resource/bind_group_layout_entries.rs index 58d1d62a19889..346019a2fb272 100644 --- a/crates/bevy_render/src/render_resource/bind_group_layout_entries.rs +++ b/crates/bevy_render/src/render_resource/bind_group_layout_entries.rs @@ -1,5 +1,5 @@ use bevy_utils::all_tuples_with_size; -use std::num::NonZero; +use core::num::NonZero; use wgpu::{BindGroupLayoutEntry, BindingType, ShaderStages}; /// Helper for constructing bind group layouts. @@ -198,7 +198,7 @@ impl BindGroupLayoutEntries<1> { } } -impl std::ops::Deref for BindGroupLayoutEntries { +impl core::ops::Deref for BindGroupLayoutEntries { type Target = [BindGroupLayoutEntry]; fn deref(&self) -> &[BindGroupLayoutEntry] { &self.entries @@ -340,7 +340,7 @@ impl DynamicBindGroupLayoutEntries { } } -impl std::ops::Deref for DynamicBindGroupLayoutEntries { +impl core::ops::Deref for DynamicBindGroupLayoutEntries { type Target = [BindGroupLayoutEntry]; fn deref(&self) -> &[BindGroupLayoutEntry] { @@ -352,8 +352,8 @@ pub mod binding_types { use crate::render_resource::{ BufferBindingType, SamplerBindingType, TextureSampleType, TextureViewDimension, }; + use core::num::NonZero; use encase::ShaderType; - use std::num::NonZero; use wgpu::{StorageTextureAccess, TextureFormat}; use super::*; diff --git a/crates/bevy_render/src/render_resource/buffer.rs b/crates/bevy_render/src/render_resource/buffer.rs index cf98fdafb8692..81a8dbc9b7687 100644 --- a/crates/bevy_render/src/render_resource/buffer.rs +++ b/crates/bevy_render/src/render_resource/buffer.rs @@ -1,5 +1,5 @@ use crate::{define_atomic_id, render_resource::resource_macros::render_resource_wrapper}; -use std::ops::{Bound, Deref, RangeBounds}; +use core::ops::{Bound, Deref, RangeBounds}; define_atomic_id!(BufferId); render_resource_wrapper!(ErasedBuffer, wgpu::Buffer); diff --git a/crates/bevy_render/src/render_resource/buffer_vec.rs b/crates/bevy_render/src/render_resource/buffer_vec.rs index c720605d9274f..ab384fadcf100 100644 --- a/crates/bevy_render/src/render_resource/buffer_vec.rs +++ b/crates/bevy_render/src/render_resource/buffer_vec.rs @@ -1,4 +1,4 @@ -use std::{iter, marker::PhantomData}; +use core::{iter, marker::PhantomData}; use crate::{ render_resource::Buffer, diff --git a/crates/bevy_render/src/render_resource/gpu_array_buffer.rs b/crates/bevy_render/src/render_resource/gpu_array_buffer.rs index f1980062bd2b5..c4c5906373029 100644 --- a/crates/bevy_render/src/render_resource/gpu_array_buffer.rs +++ b/crates/bevy_render/src/render_resource/gpu_array_buffer.rs @@ -7,9 +7,9 @@ use crate::{ renderer::{RenderDevice, RenderQueue}, }; use bevy_ecs::{prelude::Component, system::Resource}; +use core::marker::PhantomData; use encase::{private::WriteInto, ShaderSize, ShaderType}; use nonmax::NonMaxU32; -use std::marker::PhantomData; use wgpu::{BindingResource, BufferUsages}; /// Trait for types able to go in a [`GpuArrayBuffer`]. diff --git a/crates/bevy_render/src/render_resource/pipeline.rs b/crates/bevy_render/src/render_resource/pipeline.rs index 93f76d3f56e8a..f81fb57b173e6 100644 --- a/crates/bevy_render/src/render_resource/pipeline.rs +++ b/crates/bevy_render/src/render_resource/pipeline.rs @@ -3,8 +3,9 @@ use crate::{ define_atomic_id, render_resource::{resource_macros::render_resource_wrapper, BindGroupLayout, Shader}, }; +use alloc::borrow::Cow; use bevy_asset::Handle; -use std::{borrow::Cow, ops::Deref}; +use core::ops::Deref; use wgpu::{ BufferAddress, ColorTargetState, DepthStencilState, MultisampleState, PrimitiveState, PushConstantRange, VertexAttribute, VertexFormat, VertexStepMode, diff --git a/crates/bevy_render/src/render_resource/pipeline_cache.rs b/crates/bevy_render/src/render_resource/pipeline_cache.rs index af33e9302b0d0..2222df6098b95 100644 --- a/crates/bevy_render/src/render_resource/pipeline_cache.rs +++ b/crates/bevy_render/src/render_resource/pipeline_cache.rs @@ -3,6 +3,7 @@ use crate::{ renderer::{RenderAdapter, RenderDevice}, Extract, }; +use alloc::{borrow::Cow, sync::Arc}; use bevy_asset::{AssetEvent, AssetId, Assets}; use bevy_ecs::{ event::EventReader, @@ -15,15 +16,9 @@ use bevy_utils::{ tracing::{debug, error}, HashMap, HashSet, }; +use core::{future::Future, hash::Hash, mem, ops::Deref}; use naga::valid::Capabilities; -use std::{ - borrow::Cow, - future::Future, - hash::Hash, - mem, - ops::Deref, - sync::{Arc, Mutex, PoisonError}, -}; +use std::sync::{Mutex, PoisonError}; use thiserror::Error; #[cfg(feature = "shader_format_spirv")] use wgpu::util::make_spirv; diff --git a/crates/bevy_render/src/render_resource/pipeline_specializer.rs b/crates/bevy_render/src/render_resource/pipeline_specializer.rs index 5f9455aa5fc61..0ff2f50cd15ff 100644 --- a/crates/bevy_render/src/render_resource/pipeline_specializer.rs +++ b/crates/bevy_render/src/render_resource/pipeline_specializer.rs @@ -12,7 +12,7 @@ use bevy_utils::{ tracing::error, Entry, HashMap, }; -use std::{fmt::Debug, hash::Hash}; +use core::{fmt::Debug, hash::Hash}; use thiserror::Error; pub trait SpecializedRenderPipeline { @@ -142,7 +142,7 @@ impl SpecializedMeshPipelines { .map_err(|mut err| { { let SpecializedMeshPipelineError::MissingVertexAttribute(err) = &mut err; - err.pipeline_type = Some(std::any::type_name::()); + err.pipeline_type = Some(core::any::type_name::()); } err })?; @@ -171,7 +171,7 @@ impl SpecializedMeshPipelines { unused' MeshVertexBufferLayout information to specialize \ the pipeline. This is not allowed because it would invalidate \ the pipeline cache.", - std::any::type_name::() + core::any::type_name::() ); } } diff --git a/crates/bevy_render/src/render_resource/resource_macros.rs b/crates/bevy_render/src/render_resource/resource_macros.rs index e22c59b1c031f..75580f32a0ee7 100644 --- a/crates/bevy_render/src/render_resource/resource_macros.rs +++ b/crates/bevy_render/src/render_resource/resource_macros.rs @@ -20,8 +20,8 @@ macro_rules! render_resource_wrapper { impl $wrapper_type { pub fn new(value: $wgpu_type) -> Self { - let arc = std::sync::Arc::new(value); - let value_ptr = std::sync::Arc::into_raw(arc); + let arc = alloc::sync::Arc::new(value); + let value_ptr = alloc::sync::Arc::into_raw(arc); let unit_ptr = value_ptr.cast::<()>(); #[cfg(not(all(target_arch = "wasm32", target_feature = "atomics")))] @@ -33,16 +33,16 @@ macro_rules! render_resource_wrapper { pub fn try_unwrap(self) -> Option<$wgpu_type> { let value_ptr = self.0.cast::<$wgpu_type>(); // SAFETY: pointer refers to a valid Arc, and was created from Arc::into_raw. - let arc = unsafe { std::sync::Arc::from_raw(value_ptr) }; + let arc = unsafe { alloc::sync::Arc::from_raw(value_ptr) }; // we forget ourselves here since the reconstructed arc will be dropped/decremented within this scope - std::mem::forget(self); + core::mem::forget(self); - std::sync::Arc::try_unwrap(arc).ok() + alloc::sync::Arc::try_unwrap(arc).ok() } } - impl std::ops::Deref for $wrapper_type { + impl core::ops::Deref for $wrapper_type { type Target = $wgpu_type; fn deref(&self) -> &Self::Target { @@ -58,7 +58,7 @@ macro_rules! render_resource_wrapper { let value_ptr = self.0.cast::<$wgpu_type>(); // SAFETY: pointer refers to a valid Arc, and was created from Arc::into_raw. // this reconstructed arc is dropped/decremented within this scope. - unsafe { std::sync::Arc::from_raw(value_ptr) }; + unsafe { alloc::sync::Arc::from_raw(value_ptr) }; } } @@ -81,11 +81,11 @@ macro_rules! render_resource_wrapper { fn clone(&self) -> Self { let value_ptr = self.0.cast::<$wgpu_type>(); // SAFETY: pointer refers to a valid Arc, and was created from Arc::into_raw. - let arc = unsafe { std::sync::Arc::from_raw(value_ptr.cast::<$wgpu_type>()) }; - let cloned = std::sync::Arc::clone(&arc); + let arc = unsafe { alloc::sync::Arc::from_raw(value_ptr.cast::<$wgpu_type>()) }; + let cloned = alloc::sync::Arc::clone(&arc); // we forget the reconstructed Arc to avoid decrementing the ref counter, as self is still live. - std::mem::forget(arc); - let cloned_value_ptr = std::sync::Arc::into_raw(cloned); + core::mem::forget(arc); + let cloned_value_ptr = alloc::sync::Arc::into_raw(cloned); let cloned_unit_ptr = cloned_value_ptr.cast::<()>(); #[cfg(not(all(target_arch = "wasm32", target_feature = "atomics")))] @@ -129,7 +129,7 @@ macro_rules! render_resource_wrapper { } } - impl std::ops::Deref for $wrapper_type { + impl core::ops::Deref for $wrapper_type { type Target = $wgpu_type; fn deref(&self) -> &Self::Target { @@ -155,7 +155,7 @@ macro_rules! define_atomic_id { #[allow(clippy::new_without_default)] impl $atomic_id_type { pub fn new() -> Self { - use std::sync::atomic::{AtomicU32, Ordering}; + use core::sync::atomic::{AtomicU32, Ordering}; static COUNTER: AtomicU32 = AtomicU32::new(1); diff --git a/crates/bevy_render/src/render_resource/shader.rs b/crates/bevy_render/src/render_resource/shader.rs index 33055de58ccb9..7cb8b8f9ee4c1 100644 --- a/crates/bevy_render/src/render_resource/shader.rs +++ b/crates/bevy_render/src/render_resource/shader.rs @@ -1,9 +1,10 @@ use super::ShaderDefVal; use crate::define_atomic_id; +use alloc::borrow::Cow; use bevy_asset::{io::Reader, Asset, AssetLoader, AssetPath, Handle, LoadContext}; use bevy_reflect::TypePath; use bevy_utils::tracing::error; -use std::{borrow::Cow, marker::Copy}; +use core::marker::Copy; use thiserror::Error; define_atomic_id!(ShaderId); @@ -251,7 +252,7 @@ pub enum ShaderLoaderError { #[error("Could not load shader: {0}")] Io(#[from] std::io::Error), #[error("Could not parse shader: {0}")] - Parse(#[from] std::string::FromUtf8Error), + Parse(#[from] alloc::string::FromUtf8Error), } impl AssetLoader for ShaderLoader { diff --git a/crates/bevy_render/src/render_resource/storage_buffer.rs b/crates/bevy_render/src/render_resource/storage_buffer.rs index 1b244f90327ac..3f65d534ebd7f 100644 --- a/crates/bevy_render/src/render_resource/storage_buffer.rs +++ b/crates/bevy_render/src/render_resource/storage_buffer.rs @@ -1,4 +1,4 @@ -use std::marker::PhantomData; +use core::marker::PhantomData; use super::Buffer; use crate::renderer::{RenderDevice, RenderQueue}; diff --git a/crates/bevy_render/src/render_resource/texture.rs b/crates/bevy_render/src/render_resource/texture.rs index df0df616a6f6c..624935b5a6f62 100644 --- a/crates/bevy_render/src/render_resource/texture.rs +++ b/crates/bevy_render/src/render_resource/texture.rs @@ -1,5 +1,5 @@ use crate::define_atomic_id; -use std::ops::Deref; +use core::ops::Deref; use crate::render_resource::resource_macros::*; diff --git a/crates/bevy_render/src/render_resource/uniform_buffer.rs b/crates/bevy_render/src/render_resource/uniform_buffer.rs index db51653f146ea..95e1a0a56664e 100644 --- a/crates/bevy_render/src/render_resource/uniform_buffer.rs +++ b/crates/bevy_render/src/render_resource/uniform_buffer.rs @@ -1,4 +1,4 @@ -use std::{marker::PhantomData, num::NonZero}; +use core::{marker::PhantomData, num::NonZero}; use crate::{ render_resource::Buffer, diff --git a/crates/bevy_render/src/renderer/graph_runner.rs b/crates/bevy_render/src/renderer/graph_runner.rs index 835144976e47d..15b3240638e7c 100644 --- a/crates/bevy_render/src/renderer/graph_runner.rs +++ b/crates/bevy_render/src/renderer/graph_runner.rs @@ -3,8 +3,8 @@ use bevy_ecs::{prelude::Entity, world::World}; use bevy_utils::tracing::info_span; use bevy_utils::HashMap; +use alloc::{borrow::Cow, collections::VecDeque}; use smallvec::{smallvec, SmallVec}; -use std::{borrow::Cow, collections::VecDeque}; use thiserror::Error; use crate::{ diff --git a/crates/bevy_render/src/renderer/mod.rs b/crates/bevy_render/src/renderer/mod.rs index 50afc95c62a87..c45995ee77aa9 100644 --- a/crates/bevy_render/src/renderer/mod.rs +++ b/crates/bevy_render/src/renderer/mod.rs @@ -15,10 +15,10 @@ use crate::{ settings::{WgpuSettings, WgpuSettingsPriority}, view::{ExtractedWindows, ViewTarget}, }; +use alloc::sync::Arc; use bevy_ecs::{prelude::*, system::SystemState}; use bevy_time::TimeSender; use bevy_utils::Instant; -use std::sync::Arc; use wgpu::{ Adapter, AdapterInfo, CommandBuffer, CommandEncoder, DeviceType, Instance, Queue, RequestAdapterOptions, @@ -57,7 +57,7 @@ pub fn render_system(world: &mut World, state: &mut SystemState { error!("Error running render graph:"); { - let mut src: &dyn std::error::Error = &e; + let mut src: &dyn core::error::Error = &e; loop { error!("> {}", src); match src.source() { diff --git a/crates/bevy_render/src/settings.rs b/crates/bevy_render/src/settings.rs index 7dbf016a8e4c2..bf1db17ff110c 100644 --- a/crates/bevy_render/src/settings.rs +++ b/crates/bevy_render/src/settings.rs @@ -1,7 +1,8 @@ use crate::renderer::{ RenderAdapter, RenderAdapterInfo, RenderDevice, RenderInstance, RenderQueue, }; -use std::{borrow::Cow, path::PathBuf}; +use alloc::borrow::Cow; +use std::path::PathBuf; pub use wgpu::{ Backends, Dx12Compiler, Features as WgpuFeatures, Gles3MinorVersion, InstanceFlags, diff --git a/crates/bevy_render/src/texture/image.rs b/crates/bevy_render/src/texture/image.rs index ade9f968b4d9c..9204cc7d0a9d5 100644 --- a/crates/bevy_render/src/texture/image.rs +++ b/crates/bevy_render/src/texture/image.rs @@ -16,8 +16,8 @@ use bevy_derive::{Deref, DerefMut}; use bevy_ecs::system::{lifetimeless::SRes, Resource, SystemParamItem}; use bevy_math::{AspectRatio, UVec2, Vec2}; use bevy_reflect::prelude::*; +use core::hash::Hash; use serde::{Deserialize, Serialize}; -use std::hash::Hash; use thiserror::Error; use wgpu::{Extent3d, TextureDimension, TextureFormat, TextureViewDescriptor}; diff --git a/crates/bevy_render/src/texture/image_loader.rs b/crates/bevy_render/src/texture/image_loader.rs index 85a97ad431e54..c671108e581c9 100644 --- a/crates/bevy_render/src/texture/image_loader.rs +++ b/crates/bevy_render/src/texture/image_loader.rs @@ -154,8 +154,8 @@ pub struct FileTextureError { error: TextureError, path: String, } -impl std::fmt::Display for FileTextureError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { +impl core::fmt::Display for FileTextureError { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> { write!( f, "Error reading image file {}: {}, this is an error in `bevy_render`.", diff --git a/crates/bevy_render/src/texture/ktx2.rs b/crates/bevy_render/src/texture/ktx2.rs index 941cb4299aba4..8924ea72c4533 100644 --- a/crates/bevy_render/src/texture/ktx2.rs +++ b/crates/bevy_render/src/texture/ktx2.rs @@ -427,7 +427,7 @@ enum DataType { Sint, } -// This can be obtained from std::mem::transmute::(1.0f32). It is used for identifying +// This can be obtained from core::mem::transmute::(1.0f32). It is used for identifying // normalized sample types as in Unorm or Snorm. const F32_1_AS_U32: u32 = 1065353216; diff --git a/crates/bevy_render/src/texture/texture_attachment.rs b/crates/bevy_render/src/texture/texture_attachment.rs index 6681ba9916211..e0947e997207e 100644 --- a/crates/bevy_render/src/texture/texture_attachment.rs +++ b/crates/bevy_render/src/texture/texture_attachment.rs @@ -1,10 +1,8 @@ use super::CachedTexture; use crate::render_resource::{TextureFormat, TextureView}; +use alloc::sync::Arc; use bevy_color::LinearRgba; -use std::sync::{ - atomic::{AtomicBool, Ordering}, - Arc, -}; +use core::sync::atomic::{AtomicBool, Ordering}; use wgpu::{ LoadOp, Operations, RenderPassColorAttachment, RenderPassDepthStencilAttachment, StoreOp, }; diff --git a/crates/bevy_render/src/view/mod.rs b/crates/bevy_render/src/view/mod.rs index 32ab1d3986d28..c8292d4f90ce3 100644 --- a/crates/bevy_render/src/view/mod.rs +++ b/crates/bevy_render/src/view/mod.rs @@ -23,6 +23,7 @@ use crate::{ }, Render, RenderApp, RenderSet, }; +use alloc::sync::Arc; use bevy_app::{App, Plugin}; use bevy_color::LinearRgba; use bevy_derive::{Deref, DerefMut}; @@ -32,12 +33,9 @@ use bevy_reflect::{std_traits::ReflectDefault, Reflect}; use bevy_render_macros::ExtractComponent; use bevy_transform::components::GlobalTransform; use bevy_utils::{hashbrown::hash_map::Entry, HashMap}; -use std::{ +use core::{ ops::Range, - sync::{ - atomic::{AtomicUsize, Ordering}, - Arc, - }, + sync::atomic::{AtomicUsize, Ordering}, }; use wgpu::{ BufferUsages, Extent3d, RenderPassColorAttachment, RenderPassDepthStencilAttachment, StoreOp, diff --git a/crates/bevy_render/src/view/visibility/mod.rs b/crates/bevy_render/src/view/visibility/mod.rs index b219b89f12b65..adef70251bb88 100644 --- a/crates/bevy_render/src/view/visibility/mod.rs +++ b/crates/bevy_render/src/view/visibility/mod.rs @@ -1,7 +1,7 @@ mod range; mod render_layers; -use std::any::TypeId; +use core::any::TypeId; pub use range::*; pub use render_layers::*; diff --git a/crates/bevy_render/src/view/visibility/range.rs b/crates/bevy_render/src/view/visibility/range.rs index 50c49eb657825..cbf93d2b2674a 100644 --- a/crates/bevy_render/src/view/visibility/range.rs +++ b/crates/bevy_render/src/view/visibility/range.rs @@ -1,7 +1,7 @@ //! Specific distances from the camera in which entities are visible, also known //! as *hierarchical levels of detail* or *HLOD*s. -use std::{ +use core::{ hash::{Hash, Hasher}, ops::Range, }; diff --git a/crates/bevy_render/src/view/visibility/render_layers.rs b/crates/bevy_render/src/view/visibility/render_layers.rs index a0f3c1a3910b9..1932abdf71fba 100644 --- a/crates/bevy_render/src/view/visibility/render_layers.rs +++ b/crates/bevy_render/src/view/visibility/render_layers.rs @@ -32,8 +32,8 @@ impl Default for &RenderLayers { } } -impl std::fmt::Debug for RenderLayers { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl core::fmt::Debug for RenderLayers { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { f.debug_tuple("RenderLayers") .field(&self.iter().collect::>()) .finish() @@ -152,7 +152,7 @@ impl RenderLayers { } fn extend_buffer(&mut self, other_len: usize) { - let new_size = std::cmp::max(self.0.len(), other_len); + let new_size = core::cmp::max(self.0.len(), other_len); self.0.reserve_exact(new_size - self.0.len()); self.0.resize(new_size, 0u64); } @@ -160,7 +160,7 @@ impl RenderLayers { fn iter_layers(buffer_and_offset: (u64, usize)) -> impl Iterator + 'static { let (mut buffer, mut layer) = buffer_and_offset; layer *= 64; - std::iter::from_fn(move || { + core::iter::from_fn(move || { if buffer == 0 { return None; } @@ -214,7 +214,7 @@ impl RenderLayers { fn combine_blocks(&self, other: &Self, mut f: impl FnMut(u64, u64) -> u64) -> Self { let mut a = self.0.iter(); let mut b = other.0.iter(); - let mask = std::iter::from_fn(|| { + let mask = core::iter::from_fn(|| { let a = a.next().copied(); let b = b.next().copied(); if a.is_none() && b.is_none() { @@ -226,21 +226,21 @@ impl RenderLayers { } } -impl std::ops::BitAnd for RenderLayers { +impl core::ops::BitAnd for RenderLayers { type Output = Self; fn bitand(self, rhs: Self) -> Self::Output { self.intersection(&rhs) } } -impl std::ops::BitOr for RenderLayers { +impl core::ops::BitOr for RenderLayers { type Output = Self; fn bitor(self, rhs: Self) -> Self::Output { self.union(&rhs) } } -impl std::ops::BitXor for RenderLayers { +impl core::ops::BitXor for RenderLayers { type Output = Self; fn bitxor(self, rhs: Self) -> Self::Output { self.symmetric_difference(&rhs) diff --git a/crates/bevy_render/src/view/window/mod.rs b/crates/bevy_render/src/view/window/mod.rs index 0eb9e95d8718e..1def6df2aee16 100644 --- a/crates/bevy_render/src/view/window/mod.rs +++ b/crates/bevy_render/src/view/window/mod.rs @@ -11,11 +11,11 @@ use bevy_utils::{default, tracing::debug, HashSet}; use bevy_window::{ CompositeAlphaMode, PresentMode, PrimaryWindow, RawHandleWrapper, Window, WindowClosing, }; -use cursor::CursorPlugin; -use std::{ +use core::{ num::NonZero, ops::{Deref, DerefMut}, }; +use cursor::CursorPlugin; use wgpu::{ SurfaceConfiguration, SurfaceTargetUnsafe, TextureFormat, TextureUsages, TextureViewDescriptor, }; diff --git a/crates/bevy_render/src/view/window/screenshot.rs b/crates/bevy_render/src/view/window/screenshot.rs index a81e4607557ec..b17de0d2f2c8f 100644 --- a/crates/bevy_render/src/view/window/screenshot.rs +++ b/crates/bevy_render/src/view/window/screenshot.rs @@ -14,6 +14,7 @@ use crate::{ view::{prepare_view_attachments, prepare_view_targets, ViewTargetAttachments, WindowSurfaces}, ExtractSchedule, MainWorld, Render, RenderApp, RenderSet, }; +use alloc::{borrow::Cow, sync::Arc}; use bevy_app::{First, Plugin, Update}; use bevy_asset::{load_internal_asset, Handle}; use bevy_derive::{Deref, DerefMut}; @@ -29,13 +30,12 @@ use bevy_utils::{ HashSet, }; use bevy_window::{PrimaryWindow, WindowRef}; +use core::ops::Deref; use std::{ - borrow::Cow, - ops::Deref, path::Path, sync::{ mpsc::{Receiver, Sender}, - Arc, Mutex, + Mutex, }, }; use wgpu::{ diff --git a/crates/bevy_scene/src/dynamic_scene_builder.rs b/crates/bevy_scene/src/dynamic_scene_builder.rs index 30fac9e937378..894f300a9b651 100644 --- a/crates/bevy_scene/src/dynamic_scene_builder.rs +++ b/crates/bevy_scene/src/dynamic_scene_builder.rs @@ -1,4 +1,5 @@ use crate::{DynamicEntity, DynamicScene, SceneFilter}; +use alloc::collections::BTreeMap; use bevy_ecs::{ component::{Component, ComponentId}, prelude::Entity, @@ -8,7 +9,6 @@ use bevy_ecs::{ }; use bevy_reflect::{PartialReflect, ReflectFromReflect}; use bevy_utils::default; -use std::collections::BTreeMap; /// A [`DynamicScene`] builder, used to build a scene from a [`World`] by extracting some entities and resources. /// @@ -217,7 +217,7 @@ impl<'w> DynamicSceneBuilder<'w> { /// Re-extracting an entity that was already extracted will have no effect. #[must_use] pub fn extract_entity(self, entity: Entity) -> Self { - self.extract_entities(std::iter::once(entity)) + self.extract_entities(core::iter::once(entity)) } /// Despawns all entities with no components. diff --git a/crates/bevy_scene/src/lib.rs b/crates/bevy_scene/src/lib.rs index 1fbf3b11b0c97..ffbc7af17e790 100644 --- a/crates/bevy_scene/src/lib.rs +++ b/crates/bevy_scene/src/lib.rs @@ -11,6 +11,8 @@ //! instantiated or removed from a world to allow composition. Scenes can be serialized/deserialized, //! for example to save part of the world state to a file. +extern crate alloc; + mod bundle; mod dynamic_scene; mod dynamic_scene_builder; diff --git a/crates/bevy_scene/src/scene_filter.rs b/crates/bevy_scene/src/scene_filter.rs index 01811cb9fd789..eb86984903c79 100644 --- a/crates/bevy_scene/src/scene_filter.rs +++ b/crates/bevy_scene/src/scene_filter.rs @@ -1,5 +1,5 @@ use bevy_utils::{hashbrown::hash_set::IntoIter, HashSet}; -use std::any::{Any, TypeId}; +use core::any::{Any, TypeId}; /// A filter used to control which types can be added to a [`DynamicScene`]. /// diff --git a/crates/bevy_scene/src/scene_spawner.rs b/crates/bevy_scene/src/scene_spawner.rs index 186b38a4224f3..7341d9a250d21 100644 --- a/crates/bevy_scene/src/scene_spawner.rs +++ b/crates/bevy_scene/src/scene_spawner.rs @@ -285,7 +285,7 @@ impl SceneSpawner { /// Immediately despawns all scenes scheduled for despawn by despawning their instances. pub fn despawn_queued_scenes(&mut self, world: &mut World) -> Result<(), SceneSpawnError> { - let scenes_to_despawn = std::mem::take(&mut self.scenes_to_despawn); + let scenes_to_despawn = core::mem::take(&mut self.scenes_to_despawn); for scene_handle in scenes_to_despawn { self.despawn_sync(world, scene_handle)?; @@ -295,7 +295,7 @@ impl SceneSpawner { /// Immediately despawns all scene instances scheduled for despawn. pub fn despawn_queued_instances(&mut self, world: &mut World) { - let instances_to_despawn = std::mem::take(&mut self.instances_to_despawn); + let instances_to_despawn = core::mem::take(&mut self.instances_to_despawn); for instance_id in instances_to_despawn { self.despawn_instance_sync(world, &instance_id); @@ -304,7 +304,7 @@ impl SceneSpawner { /// Immediately spawns all scenes scheduled for spawn. pub fn spawn_queued_scenes(&mut self, world: &mut World) -> Result<(), SceneSpawnError> { - let scenes_to_spawn = std::mem::take(&mut self.dynamic_scenes_to_spawn); + let scenes_to_spawn = core::mem::take(&mut self.dynamic_scenes_to_spawn); for (handle, instance_id, parent) in scenes_to_spawn { let mut entity_map = EntityHashMap::default(); @@ -334,7 +334,7 @@ impl SceneSpawner { } } - let scenes_to_spawn = std::mem::take(&mut self.scenes_to_spawn); + let scenes_to_spawn = core::mem::take(&mut self.scenes_to_spawn); for (scene_handle, instance_id, parent) in scenes_to_spawn { let mut entity_map = EntityHashMap::default(); @@ -363,7 +363,7 @@ impl SceneSpawner { } pub(crate) fn set_scene_instance_parent_sync(&mut self, world: &mut World) { - let scenes_with_parent = std::mem::take(&mut self.scenes_with_parent); + let scenes_with_parent = core::mem::take(&mut self.scenes_with_parent); for (instance_id, parent) in scenes_with_parent { if let Some(instance) = self.spawned_instances.get(&instance_id) { diff --git a/crates/bevy_scene/src/serde.rs b/crates/bevy_scene/src/serde.rs index 67608d98b5209..cdb0db9597343 100644 --- a/crates/bevy_scene/src/serde.rs +++ b/crates/bevy_scene/src/serde.rs @@ -10,12 +10,12 @@ use bevy_reflect::{ PartialReflect, ReflectFromReflect, TypeRegistry, }; use bevy_utils::HashSet; +use core::fmt::Formatter; use serde::{ de::{DeserializeSeed, Error, MapAccess, SeqAccess, Visitor}, ser::{SerializeMap, SerializeStruct}, Deserialize, Deserializer, Serialize, Serializer, }; -use std::fmt::Formatter; /// Name of the serialized scene struct type. pub const SCENE_STRUCT: &str = "Scene"; @@ -237,7 +237,7 @@ struct SceneVisitor<'a> { impl<'a, 'de> Visitor<'de> for SceneVisitor<'a> { type Value = DynamicScene; - fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result { + fn expecting(&self, formatter: &mut Formatter) -> core::fmt::Result { formatter.write_str("scene struct") } @@ -326,7 +326,7 @@ struct SceneEntitiesVisitor<'a> { impl<'a, 'de> Visitor<'de> for SceneEntitiesVisitor<'a> { type Value = Vec; - fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result { + fn expecting(&self, formatter: &mut Formatter) -> core::fmt::Result { formatter.write_str("map of entities") } @@ -381,7 +381,7 @@ struct SceneEntityVisitor<'a> { impl<'a, 'de> Visitor<'de> for SceneEntityVisitor<'a> { type Value = DynamicEntity; - fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result { + fn expecting(&self, formatter: &mut Formatter) -> core::fmt::Result { formatter.write_str("entities") } @@ -456,7 +456,7 @@ struct SceneMapVisitor<'a> { impl<'a, 'de> Visitor<'de> for SceneMapVisitor<'a> { type Value = Vec>; - fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result { + fn expecting(&self, formatter: &mut Formatter) -> core::fmt::Result { formatter.write_str("map of reflect types") } diff --git a/crates/bevy_sprite/src/lib.rs b/crates/bevy_sprite/src/lib.rs index 163d3878bc474..a411cef4afc1f 100644 --- a/crates/bevy_sprite/src/lib.rs +++ b/crates/bevy_sprite/src/lib.rs @@ -8,6 +8,9 @@ )] //! Provides 2D sprite rendering functionality. + +extern crate alloc; + mod bundle; mod dynamic_texture_atlas_builder; mod mesh2d; diff --git a/crates/bevy_sprite/src/mesh2d/material.rs b/crates/bevy_sprite/src/mesh2d/material.rs index 6c91e27ee849f..be3010792a0f4 100644 --- a/crates/bevy_sprite/src/mesh2d/material.rs +++ b/crates/bevy_sprite/src/mesh2d/material.rs @@ -33,7 +33,7 @@ use bevy_render::{ }; use bevy_transform::components::{GlobalTransform, Transform}; use bevy_utils::tracing::error; -use std::{hash::Hash, marker::PhantomData}; +use core::{hash::Hash, marker::PhantomData}; use crate::{ DrawMesh2d, Mesh2dHandle, Mesh2dPipeline, Mesh2dPipelineKey, RenderMesh2dInstances, @@ -268,7 +268,7 @@ impl Hash for Material2dKey where M::Data: Hash, { - fn hash(&self, state: &mut H) { + fn hash(&self, state: &mut H) { self.mesh_key.hash(state); self.bind_group_data.hash(state); } diff --git a/crates/bevy_sprite/src/picking_backend.rs b/crates/bevy_sprite/src/picking_backend.rs index 15fd90b0842ae..baf06d1a143b4 100644 --- a/crates/bevy_sprite/src/picking_backend.rs +++ b/crates/bevy_sprite/src/picking_backend.rs @@ -2,7 +2,7 @@ //! sprites with arbitrary transforms. Picking is done based on sprite bounds, not visible pixels. //! This means a partially transparent sprite is pickable even in its transparent areas. -use std::cmp::Reverse; +use core::cmp::Reverse; use crate::{Sprite, TextureAtlas, TextureAtlasLayout}; use bevy_app::prelude::*; diff --git a/crates/bevy_sprite/src/render/mod.rs b/crates/bevy_sprite/src/render/mod.rs index f4490d76e4615..1efa866ec7e64 100644 --- a/crates/bevy_sprite/src/render/mod.rs +++ b/crates/bevy_sprite/src/render/mod.rs @@ -1,4 +1,4 @@ -use std::ops::Range; +use core::ops::Range; use crate::{ texture_atlas::{TextureAtlas, TextureAtlasLayout}, diff --git a/crates/bevy_sprite/src/texture_atlas_builder.rs b/crates/bevy_sprite/src/texture_atlas_builder.rs index 01d84549bb686..8aad5216c02aa 100644 --- a/crates/bevy_sprite/src/texture_atlas_builder.rs +++ b/crates/bevy_sprite/src/texture_atlas_builder.rs @@ -229,7 +229,7 @@ impl<'a> TextureAtlasBuilder<'a> { let last_attempt = current_height == max_height && current_width == max_width; - let mut target_bins = std::collections::BTreeMap::new(); + let mut target_bins = alloc::collections::BTreeMap::new(); target_bins.insert(0, TargetBin::new(current_width, current_height, 1)); rect_placements = match pack_rects( &rects_to_place, diff --git a/crates/bevy_state/src/app.rs b/crates/bevy_state/src/app.rs index 03df950980eac..666b35ce846a6 100644 --- a/crates/bevy_state/src/app.rs +++ b/crates/bevy_state/src/app.rs @@ -105,7 +105,7 @@ impl AppExtStates for SubApp { entered: Some(state), }); } else { - let name = std::any::type_name::(); + let name = core::any::type_name::(); warn!("State {} is already initialized.", name); } @@ -161,7 +161,7 @@ impl AppExtStates for SubApp { entered: state, }); } else { - let name = std::any::type_name::(); + let name = core::any::type_name::(); warn!("Computed state {} is already initialized.", name); } @@ -189,7 +189,7 @@ impl AppExtStates for SubApp { entered: state, }); } else { - let name = std::any::type_name::(); + let name = core::any::type_name::(); warn!("Sub state {} is already initialized.", name); } @@ -201,7 +201,7 @@ impl AppExtStates for SubApp { .world() .contains_resource::>>() { - let name = std::any::type_name::(); + let name = core::any::type_name::(); warn!("State scoped entities are enabled for state `{}`, but the state isn't installed in the app!", name); } // We work with [`StateTransition`] in set [`StateTransitionSteps::ExitSchedules`] as opposed to [`OnExit`], diff --git a/crates/bevy_state/src/lib.rs b/crates/bevy_state/src/lib.rs index c2aba9c24d1ac..c8cc1855bcc72 100644 --- a/crates/bevy_state/src/lib.rs +++ b/crates/bevy_state/src/lib.rs @@ -59,23 +59,21 @@ pub mod reflect; pub mod prelude { #[cfg(feature = "bevy_app")] #[doc(hidden)] - pub use crate::app::AppExtStates; - #[doc(hidden)] - pub use crate::commands::CommandsStatesExt; - #[doc(hidden)] - pub use crate::condition::*; + pub use crate::{app::AppExtStates, state_scoped_events::StateScopedEventsAppExt}; + #[cfg(feature = "bevy_reflect")] #[doc(hidden)] pub use crate::reflect::{ReflectFreelyMutableState, ReflectState}; + #[doc(hidden)] - pub use crate::state::{ - last_transition, ComputedStates, EnterSchedules, ExitSchedules, NextState, OnEnter, OnExit, - OnTransition, State, StateSet, StateTransition, StateTransitionEvent, States, SubStates, - TransitionSchedules, + pub use crate::{ + commands::CommandsStatesExt, + condition::*, + state::{ + last_transition, ComputedStates, EnterSchedules, ExitSchedules, NextState, OnEnter, + OnExit, OnTransition, State, StateSet, StateTransition, StateTransitionEvent, States, + SubStates, TransitionSchedules, + }, + state_scoped::StateScoped, }; - #[doc(hidden)] - pub use crate::state_scoped::StateScoped; - #[cfg(feature = "bevy_app")] - #[doc(hidden)] - pub use crate::state_scoped_events::StateScopedEventsAppExt; } diff --git a/crates/bevy_state/src/reflect.rs b/crates/bevy_state/src/reflect.rs index 5213681a796bd..c620cd4638466 100644 --- a/crates/bevy_state/src/reflect.rs +++ b/crates/bevy_state/src/reflect.rs @@ -108,7 +108,7 @@ mod tests { use bevy_ecs::prelude::AppTypeRegistry; use bevy_reflect::Reflect; use bevy_state_macros::States; - use std::any::TypeId; + use core::any::TypeId; #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, States, Reflect)] enum StateTest { diff --git a/crates/bevy_state/src/state/computed_states.rs b/crates/bevy_state/src/state/computed_states.rs index b64ad1f4fc0d4..60e7bd79e94f3 100644 --- a/crates/bevy_state/src/state/computed_states.rs +++ b/crates/bevy_state/src/state/computed_states.rs @@ -1,4 +1,4 @@ -use std::{fmt::Debug, hash::Hash}; +use core::{fmt::Debug, hash::Hash}; use bevy_ecs::schedule::Schedule; diff --git a/crates/bevy_state/src/state/resources.rs b/crates/bevy_state/src/state/resources.rs index e4d5804ebf51e..71c192cb2a3e7 100644 --- a/crates/bevy_state/src/state/resources.rs +++ b/crates/bevy_state/src/state/resources.rs @@ -1,4 +1,4 @@ -use std::ops::Deref; +use core::ops::Deref; use bevy_ecs::{ change_detection::DetectChangesMut, @@ -145,7 +145,7 @@ pub(crate) fn take_next_state( ) -> Option { let mut next_state = next_state?; - match std::mem::take(next_state.bypass_change_detection()) { + match core::mem::take(next_state.bypass_change_detection()) { NextState::Pending(x) => { next_state.set_changed(); Some(x) diff --git a/crates/bevy_state/src/state/states.rs b/crates/bevy_state/src/state/states.rs index 057d6fca0e89e..3d315ab202fd8 100644 --- a/crates/bevy_state/src/state/states.rs +++ b/crates/bevy_state/src/state/states.rs @@ -1,6 +1,6 @@ -use std::fmt::Debug; +use core::fmt::Debug; -use std::hash::Hash; +use core::hash::Hash; /// Types that can define world-wide states in a finite-state machine. /// diff --git a/crates/bevy_state/src/state/transitions.rs b/crates/bevy_state/src/state/transitions.rs index 08f3d254acd28..6902a791c5d20 100644 --- a/crates/bevy_state/src/state/transitions.rs +++ b/crates/bevy_state/src/state/transitions.rs @@ -1,4 +1,4 @@ -use std::{marker::PhantomData, mem}; +use core::{marker::PhantomData, mem}; use bevy_ecs::{ event::{Event, EventReader, EventWriter}, diff --git a/crates/bevy_state/src/state_scoped_events.rs b/crates/bevy_state/src/state_scoped_events.rs index 5e2c3f68c45f3..fbeafe545310b 100644 --- a/crates/bevy_state/src/state_scoped_events.rs +++ b/crates/bevy_state/src/state_scoped_events.rs @@ -1,4 +1,4 @@ -use std::marker::PhantomData; +use core::marker::PhantomData; use bevy_app::{App, SubApp}; use bevy_ecs::{ diff --git a/crates/bevy_tasks/src/iter/adapters.rs b/crates/bevy_tasks/src/iter/adapters.rs index 2f8f8b28e1241..617f5bdf868ca 100644 --- a/crates/bevy_tasks/src/iter/adapters.rs +++ b/crates/bevy_tasks/src/iter/adapters.rs @@ -30,13 +30,13 @@ pub struct Map { pub(crate) f: F, } -impl ParallelIterator> for Map +impl ParallelIterator> for Map where B: Iterator + Send, U: ParallelIterator, F: FnMut(B::Item) -> T + Send + Clone, { - fn next_batch(&mut self) -> Option> { + fn next_batch(&mut self) -> Option> { self.iter.next_batch().map(|b| b.map(self.f.clone())) } } @@ -47,13 +47,13 @@ pub struct Filter { pub(crate) predicate: F, } -impl ParallelIterator> for Filter +impl ParallelIterator> for Filter where B: Iterator + Send, P: ParallelIterator, F: FnMut(&B::Item) -> bool + Send + Clone, { - fn next_batch(&mut self) -> Option> { + fn next_batch(&mut self) -> Option> { self.iter .next_batch() .map(|b| b.filter(self.predicate.clone())) @@ -66,13 +66,13 @@ pub struct FilterMap { pub(crate) f: F, } -impl ParallelIterator> for FilterMap +impl ParallelIterator> for FilterMap where B: Iterator + Send, P: ParallelIterator, F: FnMut(B::Item) -> Option + Send + Clone, { - fn next_batch(&mut self) -> Option> { + fn next_batch(&mut self) -> Option> { self.iter.next_batch().map(|b| b.filter_map(self.f.clone())) } } @@ -83,7 +83,7 @@ pub struct FlatMap { pub(crate) f: F, } -impl ParallelIterator> for FlatMap +impl ParallelIterator> for FlatMap where B: Iterator + Send, P: ParallelIterator, @@ -93,7 +93,7 @@ where { // This extends each batch using the flat map. The other option is // to turn each IntoIter into its own batch. - fn next_batch(&mut self) -> Option> { + fn next_batch(&mut self) -> Option> { self.iter.next_batch().map(|b| b.flat_map(self.f.clone())) } } @@ -103,7 +103,7 @@ pub struct Flatten

{ pub(crate) iter: P, } -impl ParallelIterator> for Flatten

+impl ParallelIterator> for Flatten

where B: Iterator + Send, P: ParallelIterator, @@ -112,7 +112,7 @@ where { // This extends each batch using the flatten. The other option is to // turn each IntoIter into its own batch. - fn next_batch(&mut self) -> Option> { + fn next_batch(&mut self) -> Option> { self.iter.next_batch().map(Iterator::flatten) } } @@ -144,13 +144,13 @@ pub struct Inspect { pub(crate) f: F, } -impl ParallelIterator> for Inspect +impl ParallelIterator> for Inspect where B: Iterator + Send, P: ParallelIterator, F: FnMut(&B::Item) + Send + Clone, { - fn next_batch(&mut self) -> Option> { + fn next_batch(&mut self) -> Option> { self.iter.next_batch().map(|b| b.inspect(self.f.clone())) } } @@ -160,13 +160,13 @@ pub struct Copied

{ pub(crate) iter: P, } -impl<'a, B, P, T> ParallelIterator> for Copied

+impl<'a, B, P, T> ParallelIterator> for Copied

where B: Iterator + Send, P: ParallelIterator, T: 'a + Copy, { - fn next_batch(&mut self) -> Option> { + fn next_batch(&mut self) -> Option> { self.iter.next_batch().map(Iterator::copied) } } @@ -176,13 +176,13 @@ pub struct Cloned

{ pub(crate) iter: P, } -impl<'a, B, P, T> ParallelIterator> for Cloned

+impl<'a, B, P, T> ParallelIterator> for Cloned

where B: Iterator + Send, P: ParallelIterator, T: 'a + Copy, { - fn next_batch(&mut self) -> Option> { + fn next_batch(&mut self) -> Option> { self.iter.next_batch().map(Iterator::cloned) } } diff --git a/crates/bevy_tasks/src/iter/mod.rs b/crates/bevy_tasks/src/iter/mod.rs index 6887fa05440a1..3910166904856 100644 --- a/crates/bevy_tasks/src/iter/mod.rs +++ b/crates/bevy_tasks/src/iter/mod.rs @@ -267,7 +267,7 @@ where } }) .into_iter() - .all(std::convert::identity) + .all(core::convert::identity) } /// Tests if any element of the parallel iterator matches a predicate. @@ -286,7 +286,7 @@ where } }) .into_iter() - .any(std::convert::identity) + .any(core::convert::identity) } /// Searches for an element in a parallel iterator, returning its index. @@ -385,7 +385,7 @@ where /// See [`Iterator::max_by()`](https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.max_by) fn max_by(mut self, pool: &TaskPool, f: F) -> Option where - F: FnMut(&BatchIter::Item, &BatchIter::Item) -> std::cmp::Ordering + Send + Sync + Clone, + F: FnMut(&BatchIter::Item, &BatchIter::Item) -> core::cmp::Ordering + Send + Sync + Clone, BatchIter::Item: Send + 'static, { pool.scope(|s| { @@ -425,7 +425,7 @@ where /// See [`Iterator::min_by()`](https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.min_by) fn min_by(mut self, pool: &TaskPool, f: F) -> Option where - F: FnMut(&BatchIter::Item, &BatchIter::Item) -> std::cmp::Ordering + Send + Sync + Clone, + F: FnMut(&BatchIter::Item, &BatchIter::Item) -> core::cmp::Ordering + Send + Sync + Clone, BatchIter::Item: Send + 'static, { pool.scope(|s| { @@ -479,8 +479,8 @@ where /// See [`Iterator::sum()`](https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.sum) fn sum(mut self, pool: &TaskPool) -> R where - S: std::iter::Sum + Send + 'static, - R: std::iter::Sum, + S: core::iter::Sum + Send + 'static, + R: core::iter::Sum, { pool.scope(|s| { while let Some(batch) = self.next_batch() { @@ -496,8 +496,8 @@ where /// See [`Iterator::product()`](https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.product) fn product(mut self, pool: &TaskPool) -> R where - S: std::iter::Product + Send + 'static, - R: std::iter::Product, + S: core::iter::Product + Send + 'static, + R: core::iter::Product, { pool.scope(|s| { while let Some(batch) = self.next_batch() { diff --git a/crates/bevy_tasks/src/lib.rs b/crates/bevy_tasks/src/lib.rs index d8736d55cab07..1d6d35664ed0e 100644 --- a/crates/bevy_tasks/src/lib.rs +++ b/crates/bevy_tasks/src/lib.rs @@ -5,6 +5,8 @@ html_favicon_url = "https://bevyengine.org/assets/icon.png" )] +extern crate alloc; + mod slice; pub use slice::{ParallelSlice, ParallelSliceMut}; @@ -15,11 +17,13 @@ pub use task::Task; #[cfg(all(not(target_arch = "wasm32"), feature = "multi_threaded"))] mod task_pool; + #[cfg(all(not(target_arch = "wasm32"), feature = "multi_threaded"))] pub use task_pool::{Scope, TaskPool, TaskPoolBuilder}; #[cfg(any(target_arch = "wasm32", not(feature = "multi_threaded")))] mod single_threaded_task_pool; + #[cfg(any(target_arch = "wasm32", not(feature = "multi_threaded")))] pub use single_threaded_task_pool::{Scope, TaskPool, TaskPoolBuilder, ThreadExecutor}; @@ -57,7 +61,7 @@ pub mod prelude { }; } -use std::num::NonZero; +use core::num::NonZero; /// Gets the logical CPU core count available to the current process. /// diff --git a/crates/bevy_tasks/src/single_threaded_task_pool.rs b/crates/bevy_tasks/src/single_threaded_task_pool.rs index 795d077476678..d7f994026a678 100644 --- a/crates/bevy_tasks/src/single_threaded_task_pool.rs +++ b/crates/bevy_tasks/src/single_threaded_task_pool.rs @@ -1,4 +1,5 @@ -use std::{cell::RefCell, future::Future, marker::PhantomData, mem, rc::Rc, sync::Arc}; +use alloc::{rc::Rc, sync::Arc}; +use core::{cell::RefCell, future::Future, marker::PhantomData, mem}; use crate::Task; diff --git a/crates/bevy_tasks/src/slice.rs b/crates/bevy_tasks/src/slice.rs index 93568fd15dad0..a8a87c9ce80a0 100644 --- a/crates/bevy_tasks/src/slice.rs +++ b/crates/bevy_tasks/src/slice.rs @@ -86,9 +86,9 @@ pub trait ParallelSlice: AsRef<[T]> { R: Send + 'static, { let slice = self.as_ref(); - let chunk_size = std::cmp::max( + let chunk_size = core::cmp::max( 1, - std::cmp::max( + core::cmp::max( slice.len() / task_pool.thread_num(), slice.len() / max_tasks.unwrap_or(usize::MAX), ), @@ -197,9 +197,9 @@ pub trait ParallelSliceMut: AsMut<[T]> { R: Send + 'static, { let mut slice = self.as_mut(); - let chunk_size = std::cmp::max( + let chunk_size = core::cmp::max( 1, - std::cmp::max( + core::cmp::max( slice.len() / task_pool.thread_num(), slice.len() / max_tasks.unwrap_or(usize::MAX), ), diff --git a/crates/bevy_tasks/src/task.rs b/crates/bevy_tasks/src/task.rs index b16b5a88d8417..53292c7574f44 100644 --- a/crates/bevy_tasks/src/task.rs +++ b/crates/bevy_tasks/src/task.rs @@ -1,4 +1,4 @@ -use std::{ +use core::{ future::Future, pin::Pin, task::{Context, Poll}, diff --git a/crates/bevy_tasks/src/task_pool.rs b/crates/bevy_tasks/src/task_pool.rs index cd395a35fd2ce..9fab3fbbe8317 100644 --- a/crates/bevy_tasks/src/task_pool.rs +++ b/crates/bevy_tasks/src/task_pool.rs @@ -1,11 +1,6 @@ -use std::{ - future::Future, - marker::PhantomData, - mem, - panic::AssertUnwindSafe, - sync::Arc, - thread::{self, JoinHandle}, -}; +use alloc::sync::Arc; +use core::{future::Future, marker::PhantomData, mem, panic::AssertUnwindSafe}; +use std::thread::{self, JoinHandle}; use async_executor::FallibleTask; use concurrent_queue::ConcurrentQueue; @@ -357,12 +352,12 @@ impl TaskPool { unsafe { mem::transmute(external_executor) }; // SAFETY: As above, all futures must complete in this function so we can change the lifetime let scope_executor: &'env ThreadExecutor<'env> = unsafe { mem::transmute(scope_executor) }; - let spawned: ConcurrentQueue>>> = + let spawned: ConcurrentQueue>>> = ConcurrentQueue::unbounded(); // shadow the variable so that the owned value cannot be used for the rest of the function // SAFETY: As above, all futures must complete in this function so we can change the lifetime let spawned: &'env ConcurrentQueue< - FallibleTask>>, + FallibleTask>>, > = unsafe { mem::transmute(&spawned) }; let scope = Scope { @@ -601,7 +596,7 @@ pub struct Scope<'scope, 'env: 'scope, T> { executor: &'scope async_executor::Executor<'scope>, external_executor: &'scope ThreadExecutor<'scope>, scope_executor: &'scope ThreadExecutor<'scope>, - spawned: &'scope ConcurrentQueue>>>, + spawned: &'scope ConcurrentQueue>>>, // make `Scope` invariant over 'scope and 'env scope: PhantomData<&'scope mut &'scope ()>, env: PhantomData<&'env mut &'env ()>, @@ -677,10 +672,8 @@ where #[allow(clippy::disallowed_types)] mod tests { use super::*; - use std::sync::{ - atomic::{AtomicBool, AtomicI32, Ordering}, - Barrier, - }; + use core::sync::atomic::{AtomicBool, AtomicI32, Ordering}; + use std::sync::Barrier; #[test] fn test_spawn() { diff --git a/crates/bevy_tasks/src/thread_executor.rs b/crates/bevy_tasks/src/thread_executor.rs index cc6b272efb4ff..b25811b559341 100644 --- a/crates/bevy_tasks/src/thread_executor.rs +++ b/crates/bevy_tasks/src/thread_executor.rs @@ -1,7 +1,5 @@ -use std::{ - marker::PhantomData, - thread::{self, ThreadId}, -}; +use core::marker::PhantomData; +use std::thread::{self, ThreadId}; use async_executor::{Executor, Task}; use futures_lite::Future; @@ -86,7 +84,7 @@ impl<'task> ThreadExecutor<'task> { /// Returns true if `self` and `other`'s executor is same pub fn is_same(&self, other: &Self) -> bool { - std::ptr::eq(self, other) + core::ptr::eq(self, other) } } @@ -115,7 +113,7 @@ impl<'task, 'ticker> ThreadExecutorTicker<'task, 'ticker> { #[cfg(test)] mod tests { use super::*; - use std::sync::Arc; + use alloc::sync::Arc; #[test] fn test_ticker() { diff --git a/crates/bevy_tasks/src/usages.rs b/crates/bevy_tasks/src/usages.rs index fda3092b8ebc8..b260274a0fb11 100644 --- a/crates/bevy_tasks/src/usages.rs +++ b/crates/bevy_tasks/src/usages.rs @@ -1,5 +1,6 @@ use super::TaskPool; -use std::{ops::Deref, sync::OnceLock}; +use core::ops::Deref; +use std::sync::OnceLock; macro_rules! taskpool { ($(#[$attr:meta])* ($static:ident, $type:ident)) => { diff --git a/crates/bevy_tasks/src/wasm_task.rs b/crates/bevy_tasks/src/wasm_task.rs index 47c082516ad2b..572b381043b27 100644 --- a/crates/bevy_tasks/src/wasm_task.rs +++ b/crates/bevy_tasks/src/wasm_task.rs @@ -1,4 +1,4 @@ -use std::{ +use core::{ any::Any, future::{Future, IntoFuture}, panic::{AssertUnwindSafe, UnwindSafe}, @@ -44,7 +44,7 @@ impl Task { Ok(Err(panic)) => { // drop this to prevent the panic payload from resuming the panic on drop. // this also leaks the box but I'm not sure how to avoid that - std::mem::forget(panic); + core::mem::forget(panic); None } } @@ -54,8 +54,8 @@ impl Task { impl Future for Task { type Output = T; fn poll( - mut self: std::pin::Pin<&mut Self>, - cx: &mut std::task::Context<'_>, + mut self: core::pin::Pin<&mut Self>, + cx: &mut core::task::Context<'_>, ) -> std::task::Poll { match Pin::new(&mut self.0).poll(cx) { Poll::Ready(Ok(Ok(value))) => Poll::Ready(value), @@ -76,7 +76,7 @@ struct CatchUnwind(#[pin] F); impl Future for CatchUnwind { type Output = Result; - fn poll(self: std::pin::Pin<&mut Self>, cx: &mut std::task::Context) -> Poll { + fn poll(self: core::pin::Pin<&mut Self>, cx: &mut core::task::Context) -> Poll { std::panic::catch_unwind(AssertUnwindSafe(|| self.project().0.poll(cx)))?.map(Ok) } } diff --git a/crates/bevy_text/src/font.rs b/crates/bevy_text/src/font.rs index d24d89eea337d..b748f4a111fdd 100644 --- a/crates/bevy_text/src/font.rs +++ b/crates/bevy_text/src/font.rs @@ -1,4 +1,4 @@ -use std::sync::Arc; +use alloc::sync::Arc; use bevy_asset::Asset; use bevy_reflect::TypePath; diff --git a/crates/bevy_text/src/font_atlas.rs b/crates/bevy_text/src/font_atlas.rs index 31c0fec9e844b..8f32dade935f1 100644 --- a/crates/bevy_text/src/font_atlas.rs +++ b/crates/bevy_text/src/font_atlas.rs @@ -116,8 +116,8 @@ impl FontAtlas { } } -impl std::fmt::Debug for FontAtlas { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl core::fmt::Debug for FontAtlas { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { f.debug_struct("FontAtlas") .field("glyph_to_atlas_index", &self.glyph_to_atlas_index) .field("texture_atlas", &self.texture_atlas) diff --git a/crates/bevy_text/src/lib.rs b/crates/bevy_text/src/lib.rs index 0b638cdb1d5e8..136ee7d7e7be6 100644 --- a/crates/bevy_text/src/lib.rs +++ b/crates/bevy_text/src/lib.rs @@ -31,6 +31,8 @@ #![allow(clippy::type_complexity)] +extern crate alloc; + mod bounds; mod error; mod font; diff --git a/crates/bevy_text/src/pipeline.rs b/crates/bevy_text/src/pipeline.rs index 3a6abd6a77d6a..10efe23f748da 100644 --- a/crates/bevy_text/src/pipeline.rs +++ b/crates/bevy_text/src/pipeline.rs @@ -1,4 +1,4 @@ -use std::sync::Arc; +use alloc::sync::Arc; use bevy_asset::{AssetId, Assets}; use bevy_ecs::{ @@ -109,7 +109,7 @@ impl TextPipeline { // The section index is stored in the metadata of the spans, and could be used // to look up the section the span came from and is not used internally // in cosmic-text. - let mut spans: Vec<(&str, Attrs)> = std::mem::take(&mut self.spans_buffer) + let mut spans: Vec<(&str, Attrs)> = core::mem::take(&mut self.spans_buffer) .into_iter() .map(|_| -> (&str, Attrs) { unreachable!() }) .collect(); diff --git a/crates/bevy_time/src/lib.rs b/crates/bevy_time/src/lib.rs index 6e33dd2f63dbd..4637b000fd174 100644 --- a/crates/bevy_time/src/lib.rs +++ b/crates/bevy_time/src/lib.rs @@ -162,7 +162,7 @@ mod tests { system::{Local, Res, ResMut, Resource}, }; use bevy_utils::Duration; - use std::error::Error; + use core::error::Error; #[derive(Event)] struct TestEvent { diff --git a/crates/bevy_time/src/time.rs b/crates/bevy_time/src/time.rs index 36feb7fe70fbc..739f7f674245b 100644 --- a/crates/bevy_time/src/time.rs +++ b/crates/bevy_time/src/time.rs @@ -1,9 +1,10 @@ -#[cfg(feature = "bevy_reflect")] -use bevy_ecs::reflect::ReflectResource; use bevy_ecs::system::Resource; -#[cfg(feature = "bevy_reflect")] -use bevy_reflect::{std_traits::ReflectDefault, Reflect}; use bevy_utils::Duration; +#[cfg(feature = "bevy_reflect")] +use { + bevy_ecs::reflect::ReflectResource, + bevy_reflect::{std_traits::ReflectDefault, Reflect}, +}; /// A generic clock resource that tracks how much it has advanced since its /// previous update and since its creation. diff --git a/crates/bevy_transform/src/components/global_transform.rs b/crates/bevy_transform/src/components/global_transform.rs index 0b377567966d9..b3f4988e4481b 100644 --- a/crates/bevy_transform/src/components/global_transform.rs +++ b/crates/bevy_transform/src/components/global_transform.rs @@ -1,13 +1,14 @@ -use std::ops::Mul; +use core::ops::Mul; use super::Transform; -#[cfg(feature = "bevy-support")] -use bevy_ecs::{component::Component, reflect::ReflectComponent}; use bevy_math::{Affine3A, Dir3, Isometry3d, Mat4, Quat, Vec3, Vec3A}; -#[cfg(feature = "bevy-support")] -use bevy_reflect::{std_traits::ReflectDefault, Reflect}; #[cfg(all(feature = "bevy-support", feature = "serialize"))] use bevy_reflect::{ReflectDeserialize, ReflectSerialize}; +#[cfg(feature = "bevy-support")] +use { + bevy_ecs::{component::Component, reflect::ReflectComponent}, + bevy_reflect::{std_traits::ReflectDefault, Reflect}, +}; /// [`GlobalTransform`] is an affine transformation from entity-local coordinates to worldspace coordinates. /// diff --git a/crates/bevy_transform/src/components/transform.rs b/crates/bevy_transform/src/components/transform.rs index 9202b0618c940..e43b6bf4b43e7 100644 --- a/crates/bevy_transform/src/components/transform.rs +++ b/crates/bevy_transform/src/components/transform.rs @@ -1,10 +1,11 @@ use super::GlobalTransform; -#[cfg(feature = "bevy-support")] -use bevy_ecs::{component::Component, reflect::ReflectComponent}; use bevy_math::{Affine3A, Dir3, Isometry3d, Mat3, Mat4, Quat, Vec3}; +use core::ops::Mul; #[cfg(feature = "bevy-support")] -use bevy_reflect::prelude::*; -use std::ops::Mul; +use { + bevy_ecs::{component::Component, reflect::ReflectComponent}, + bevy_reflect::prelude::*, +}; /// Describe the position of an entity. If the entity has a parent, the position is relative /// to its parent position. diff --git a/crates/bevy_transform/src/helper.rs b/crates/bevy_transform/src/helper.rs index 4a77f3fa72604..7b3b206170d3d 100644 --- a/crates/bevy_transform/src/helper.rs +++ b/crates/bevy_transform/src/helper.rs @@ -80,7 +80,7 @@ pub enum ComputeGlobalTransformError { #[cfg(test)] mod tests { - use std::f32::consts::TAU; + use core::f32::consts::TAU; use bevy_app::App; use bevy_ecs::system::SystemState; diff --git a/crates/bevy_transform/src/lib.rs b/crates/bevy_transform/src/lib.rs index c6f55362924bd..e3705742a004b 100644 --- a/crates/bevy_transform/src/lib.rs +++ b/crates/bevy_transform/src/lib.rs @@ -39,8 +39,11 @@ pub mod prelude { #[cfg(feature = "bevy-support")] #[doc(hidden)] pub use crate::{ - bundles::TransformBundle, commands::BuildChildrenTransformExt, helper::TransformHelper, - plugins::TransformPlugin, plugins::TransformSystem, traits::TransformPoint, + bundles::TransformBundle, + commands::BuildChildrenTransformExt, + helper::TransformHelper, + plugins::{TransformPlugin, TransformSystem}, + traits::TransformPoint, }; } diff --git a/crates/bevy_transform/src/systems.rs b/crates/bevy_transform/src/systems.rs index 12b3e43251664..a06432b0f3d30 100644 --- a/crates/bevy_transform/src/systems.rs +++ b/crates/bevy_transform/src/systems.rs @@ -479,7 +479,7 @@ mod test { app.world_mut() .spawn(TransformBundle::IDENTITY) .add_children(&[child]); - std::mem::swap( + core::mem::swap( &mut *app.world_mut().get_mut::(child).unwrap(), &mut *temp.get_mut::(grandchild).unwrap(), ); diff --git a/crates/bevy_ui/src/geometry.rs b/crates/bevy_ui/src/geometry.rs index d208139aab9e1..1f7a5a02d94de 100644 --- a/crates/bevy_ui/src/geometry.rs +++ b/crates/bevy_ui/src/geometry.rs @@ -1,6 +1,6 @@ use bevy_math::Vec2; use bevy_reflect::{std_traits::ReflectDefault, Reflect}; -use std::ops::{Div, DivAssign, Mul, MulAssign, Neg}; +use core::ops::{Div, DivAssign, Mul, MulAssign, Neg}; use thiserror::Error; #[cfg(feature = "serialize")] diff --git a/crates/bevy_ui/src/layout/debug.rs b/crates/bevy_ui/src/layout/debug.rs index 47b02396a6816..359658f59dbe9 100644 --- a/crates/bevy_ui/src/layout/debug.rs +++ b/crates/bevy_ui/src/layout/debug.rs @@ -1,4 +1,4 @@ -use std::fmt::Write; +use core::fmt::Write; use taffy::{NodeId, TraversePartialTree}; diff --git a/crates/bevy_ui/src/layout/mod.rs b/crates/bevy_ui/src/layout/mod.rs index 233ccd7186bea..8f0de1fd35306 100644 --- a/crates/bevy_ui/src/layout/mod.rs +++ b/crates/bevy_ui/src/layout/mod.rs @@ -15,14 +15,15 @@ use bevy_hierarchy::{Children, Parent}; use bevy_math::{UVec2, Vec2}; use bevy_render::camera::{Camera, NormalizedRenderTarget}; use bevy_sprite::BorderRect; -#[cfg(feature = "bevy_text")] -use bevy_text::{CosmicBuffer, TextPipeline}; use bevy_transform::components::Transform; use bevy_utils::tracing::warn; use bevy_window::{PrimaryWindow, Window, WindowScaleFactorChanged}; use thiserror::Error; use ui_surface::UiSurface; +#[cfg(feature = "bevy_text")] +use bevy_text::{CosmicBuffer, TextPipeline}; + mod convert; pub mod debug; pub(crate) mod ui_surface; diff --git a/crates/bevy_ui/src/layout/ui_surface.rs b/crates/bevy_ui/src/layout/ui_surface.rs index b5f0d29b9e438..ce4f47e0928c9 100644 --- a/crates/bevy_ui/src/layout/ui_surface.rs +++ b/crates/bevy_ui/src/layout/ui_surface.rs @@ -1,4 +1,4 @@ -use std::fmt; +use core::fmt; use taffy::TaffyTree; @@ -248,7 +248,7 @@ without UI components as a child of an entity with UI components, results may be #[cfg(feature = "bevy_text")] buffer, #[cfg(not(feature = "bevy_text"))] - font_system: std::marker::PhantomData, + font_system: core::marker::PhantomData, }, style, ); diff --git a/crates/bevy_ui/src/lib.rs b/crates/bevy_ui/src/lib.rs index 9a840ac7d90d4..0b23f4e0cfed5 100644 --- a/crates/bevy_ui/src/lib.rs +++ b/crates/bevy_ui/src/lib.rs @@ -45,13 +45,14 @@ use widget::UiImageSize; /// This includes the most common types in this crate, re-exported for your convenience. pub mod prelude { #[doc(hidden)] - pub use crate::{ - geometry::*, node_bundles::*, ui_material::*, ui_node::*, widget::Button, widget::Label, - Interaction, UiMaterialPlugin, UiScale, + pub use { + crate::{ + geometry::*, node_bundles::*, ui_material::*, ui_node::*, widget::Button, + widget::Label, Interaction, UiMaterialPlugin, UiScale, + }, + // `bevy_sprite` re-exports for texture slicing + bevy_sprite::{BorderRect, ImageScaleMode, SliceScaleMode, TextureSlicer}, }; - // `bevy_sprite` re-exports for texture slicing - #[doc(hidden)] - pub use bevy_sprite::{BorderRect, ImageScaleMode, SliceScaleMode, TextureSlicer}; } use bevy_app::prelude::*; diff --git a/crates/bevy_ui/src/measurement.rs b/crates/bevy_ui/src/measurement.rs index 9eca9de354f37..c50d81453129d 100644 --- a/crates/bevy_ui/src/measurement.rs +++ b/crates/bevy_ui/src/measurement.rs @@ -1,7 +1,7 @@ use bevy_ecs::{prelude::Component, reflect::ReflectComponent}; use bevy_math::Vec2; use bevy_reflect::{std_traits::ReflectDefault, Reflect}; -use std::fmt::Formatter; +use core::fmt::Formatter; pub use taffy::style::AvailableSpace; use crate::widget::ImageMeasure; @@ -9,8 +9,8 @@ use crate::widget::ImageMeasure; #[cfg(feature = "bevy_text")] use crate::widget::TextMeasure; -impl std::fmt::Debug for ContentSize { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { +impl core::fmt::Debug for ContentSize { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { f.debug_struct("ContentSize").finish() } } @@ -26,7 +26,7 @@ pub struct MeasureArgs<'a> { pub buffer: Option<&'a mut bevy_text::cosmic_text::Buffer>, // When `bevy_text` is disabled, use `PhantomData` in order to keep lifetime in type signature. #[cfg(not(feature = "bevy_text"))] - pub font_system: std::marker::PhantomData<&'a mut ()>, + pub font_system: core::marker::PhantomData<&'a mut ()>, } /// A `Measure` is used to compute the size of a ui node diff --git a/crates/bevy_ui/src/node_bundles.rs b/crates/bevy_ui/src/node_bundles.rs index b99681ff39a0f..e8e2430605cad 100644 --- a/crates/bevy_ui/src/node_bundles.rs +++ b/crates/bevy_ui/src/node_bundles.rs @@ -1,22 +1,23 @@ //! This module contains basic node bundles used to build UIs -#[cfg(feature = "bevy_text")] -use crate::widget::TextFlags; use crate::{ widget::{Button, UiImageSize}, BackgroundColor, BorderColor, BorderRadius, ContentSize, FocusPolicy, Interaction, Node, ScrollPosition, Style, UiImage, UiMaterial, ZIndex, }; use bevy_asset::Handle; -#[cfg(feature = "bevy_text")] -use bevy_color::Color; use bevy_ecs::bundle::Bundle; use bevy_render::view::{InheritedVisibility, ViewVisibility, Visibility}; +use bevy_transform::prelude::{GlobalTransform, Transform}; + #[cfg(feature = "bevy_text")] -use bevy_text::{ - BreakLineOn, CosmicBuffer, JustifyText, Text, TextLayoutInfo, TextSection, TextStyle, +use { + crate::widget::TextFlags, + bevy_color::Color, + bevy_text::{ + BreakLineOn, CosmicBuffer, JustifyText, Text, TextLayoutInfo, TextSection, TextStyle, + }, }; -use bevy_transform::prelude::{GlobalTransform, Transform}; /// The basic UI node. /// diff --git a/crates/bevy_ui/src/render/mod.rs b/crates/bevy_ui/src/render/mod.rs index c3c7fbc8daa28..0026ecbe23a82 100644 --- a/crates/bevy_ui/src/render/mod.rs +++ b/crates/bevy_ui/src/render/mod.rs @@ -38,14 +38,18 @@ use bevy_render::{ use bevy_sprite::TextureAtlasLayout; use bevy_sprite::{BorderRect, ImageScaleMode, SpriteAssetEvents, TextureAtlas}; #[cfg(feature = "bevy_text")] -use bevy_text::{PositionedGlyph, Text, TextLayoutInfo}; +use bevy_text::PositionedGlyph; +#[cfg(feature = "bevy_text")] +use bevy_text::Text; +#[cfg(feature = "bevy_text")] +use bevy_text::TextLayoutInfo; use bevy_transform::components::GlobalTransform; use bevy_utils::HashMap; use bytemuck::{Pod, Zeroable}; +use core::ops::Range; use graph::{NodeUi, SubGraphUi}; pub use pipeline::*; pub use render_pass::*; -use std::ops::Range; pub use ui_material_pipeline::*; use ui_texture_slice_pipeline::UiTextureSlicerPlugin; @@ -901,14 +905,14 @@ pub fn prepare_uinodes( .map(|scaling| image.size.as_vec2() * scaling) .unwrap_or(uinode_rect.max); if extracted_uinode.flip_x { - std::mem::swap(&mut uinode_rect.max.x, &mut uinode_rect.min.x); + core::mem::swap(&mut uinode_rect.max.x, &mut uinode_rect.min.x); positions_diff[0].x *= -1.; positions_diff[1].x *= -1.; positions_diff[2].x *= -1.; positions_diff[3].x *= -1.; } if extracted_uinode.flip_y { - std::mem::swap(&mut uinode_rect.max.y, &mut uinode_rect.min.y); + core::mem::swap(&mut uinode_rect.max.y, &mut uinode_rect.min.y); positions_diff[0].y *= -1.; positions_diff[1].y *= -1.; positions_diff[2].y *= -1.; diff --git a/crates/bevy_ui/src/render/render_pass.rs b/crates/bevy_ui/src/render/render_pass.rs index 7c9931b82f183..08ee870668fcf 100644 --- a/crates/bevy_ui/src/render/render_pass.rs +++ b/crates/bevy_ui/src/render/render_pass.rs @@ -1,4 +1,4 @@ -use std::ops::Range; +use core::ops::Range; use super::{UiBatch, UiImageBindGroups, UiMeta}; use crate::DefaultCameraView; diff --git a/crates/bevy_ui/src/render/ui_material_pipeline.rs b/crates/bevy_ui/src/render/ui_material_pipeline.rs index b8b3d7395fbbd..9c814ab843a12 100644 --- a/crates/bevy_ui/src/render/ui_material_pipeline.rs +++ b/crates/bevy_ui/src/render/ui_material_pipeline.rs @@ -1,4 +1,4 @@ -use std::{hash::Hash, marker::PhantomData, ops::Range}; +use core::{hash::Hash, marker::PhantomData, ops::Range}; use bevy_asset::*; use bevy_ecs::{ diff --git a/crates/bevy_ui/src/render/ui_texture_slice_pipeline.rs b/crates/bevy_ui/src/render/ui_texture_slice_pipeline.rs index 5839f7034ace5..c8b9cfb9b2977 100644 --- a/crates/bevy_ui/src/render/ui_texture_slice_pipeline.rs +++ b/crates/bevy_ui/src/render/ui_texture_slice_pipeline.rs @@ -1,4 +1,4 @@ -use std::{hash::Hash, ops::Range}; +use core::{hash::Hash, ops::Range}; use bevy_asset::*; use bevy_color::{Alpha, ColorToComponents, LinearRgba}; diff --git a/crates/bevy_ui/src/ui_material.rs b/crates/bevy_ui/src/ui_material.rs index dfeb3ee4c19ce..68d727cdb88f7 100644 --- a/crates/bevy_ui/src/ui_material.rs +++ b/crates/bevy_ui/src/ui_material.rs @@ -1,4 +1,4 @@ -use std::hash::Hash; +use core::hash::Hash; use bevy_asset::Asset; use bevy_render::render_resource::{AsBindGroup, RenderPipelineDescriptor, ShaderRef}; @@ -140,7 +140,7 @@ impl Hash for UiMaterialKey where M::Data: Hash, { - fn hash(&self, state: &mut H) { + fn hash(&self, state: &mut H) { self.hdr.hash(state); self.bind_group_data.hash(state); } diff --git a/crates/bevy_ui/src/ui_node.rs b/crates/bevy_ui/src/ui_node.rs index 358e955f0e796..c4af28e4c788e 100644 --- a/crates/bevy_ui/src/ui_node.rs +++ b/crates/bevy_ui/src/ui_node.rs @@ -11,8 +11,8 @@ use bevy_render::{ use bevy_sprite::BorderRect; use bevy_utils::warn_once; use bevy_window::{PrimaryWindow, WindowRef}; +use core::num::NonZero; use smallvec::SmallVec; -use std::num::NonZero; use thiserror::Error; /// Base component for a UI node, which also provides the computed size of the node. diff --git a/crates/bevy_ui/src/widget/text.rs b/crates/bevy_ui/src/widget/text.rs index cb319a288129e..e84ec322dc13f 100644 --- a/crates/bevy_ui/src/widget/text.rs +++ b/crates/bevy_ui/src/widget/text.rs @@ -211,7 +211,7 @@ pub fn measure_text_system( ); } } - std::mem::swap(&mut *last_scale_factors, &mut *scale_factors_buffer); + core::mem::swap(&mut *last_scale_factors, &mut *scale_factors_buffer); } #[allow(clippy::too_many_arguments)] @@ -346,5 +346,5 @@ pub fn text_system( ); } } - std::mem::swap(&mut *last_scale_factors, &mut *scale_factors_buffer); + core::mem::swap(&mut *last_scale_factors, &mut *scale_factors_buffer); } diff --git a/crates/bevy_utils/macros/src/lib.rs b/crates/bevy_utils/macros/src/lib.rs index 78803cf079e9a..b5404d078df5f 100644 --- a/crates/bevy_utils/macros/src/lib.rs +++ b/crates/bevy_utils/macros/src/lib.rs @@ -61,7 +61,7 @@ impl Parse for AllTuples { /// ## Single parameter /// /// ``` -/// # use std::marker::PhantomData; +/// # use core::marker::PhantomData; /// # use bevy_utils_proc_macros::all_tuples; /// # /// struct Foo { @@ -201,7 +201,7 @@ pub fn all_tuples(input: TokenStream) -> TokenStream { /// ## Single parameter /// /// ``` -/// # use std::marker::PhantomData; +/// # use core::marker::PhantomData; /// # use bevy_utils_proc_macros::all_tuples_with_size; /// # /// struct Foo { diff --git a/crates/bevy_utils/src/lib.rs b/crates/bevy_utils/src/lib.rs index b8966e868bd55..9cd1782345e88 100644 --- a/crates/bevy_utils/src/lib.rs +++ b/crates/bevy_utils/src/lib.rs @@ -349,7 +349,7 @@ impl Hasher for NoOpHasher { /// // Make sure the message only gets printed if a panic occurs. /// // If we remove this line, then the message will be printed regardless of whether a panic occurs /// // -- similar to a `try ... finally` block. -/// std::mem::forget(_catch); +/// core::mem::forget(_catch); /// # } /// # /// # test_panic(false, |_| unreachable!()); @@ -431,7 +431,7 @@ mod tests { 0 } fn write(&mut self, _: &[u8]) { - panic!("Hashing of std::any::TypeId changed"); + panic!("Hashing of core::any::TypeId changed"); } fn write_u64(&mut self, _: u64) {} } diff --git a/crates/bevy_utils/src/once.rs b/crates/bevy_utils/src/once.rs index ce25120a5a1ac..68aeb745559da 100644 --- a/crates/bevy_utils/src/once.rs +++ b/crates/bevy_utils/src/once.rs @@ -2,7 +2,7 @@ #[macro_export] macro_rules! once { ($expression:expr) => {{ - use ::std::sync::atomic::{AtomicBool, Ordering}; + use ::core::sync::atomic::{AtomicBool, Ordering}; static SHOULD_FIRE: AtomicBool = AtomicBool::new(true); if SHOULD_FIRE.swap(false, Ordering::Relaxed) { diff --git a/crates/bevy_window/src/lib.rs b/crates/bevy_window/src/lib.rs index e6e06ab49fd42..eb442e7d73812 100644 --- a/crates/bevy_window/src/lib.rs +++ b/crates/bevy_window/src/lib.rs @@ -11,7 +11,10 @@ //! The [`WindowPlugin`] sets up some global window-related parameters and //! is part of the [`DefaultPlugins`](https://docs.rs/bevy/latest/bevy/struct.DefaultPlugins.html). -use std::sync::{Arc, Mutex}; +extern crate alloc; + +use alloc::sync::Arc; +use std::sync::Mutex; use bevy_a11y::Focus; diff --git a/crates/bevy_window/src/raw_handle.rs b/crates/bevy_window/src/raw_handle.rs index 81b9a37096a83..6084bc728f99e 100644 --- a/crates/bevy_window/src/raw_handle.rs +++ b/crates/bevy_window/src/raw_handle.rs @@ -1,16 +1,13 @@ #![allow(unsafe_code)] +use alloc::sync::Arc; use bevy_ecs::prelude::Component; +use core::{any::Any, marker::PhantomData, ops::Deref}; use raw_window_handle::{ DisplayHandle, HandleError, HasDisplayHandle, HasWindowHandle, RawDisplayHandle, RawWindowHandle, WindowHandle, }; -use std::{ - any::Any, - marker::PhantomData, - ops::Deref, - sync::{Arc, Mutex}, -}; +use std::sync::Mutex; /// A wrapper over a window. /// diff --git a/crates/bevy_window/src/window.rs b/crates/bevy_window/src/window.rs index a905107158c71..c0f59675e69f5 100644 --- a/crates/bevy_window/src/window.rs +++ b/crates/bevy_window/src/window.rs @@ -1,4 +1,4 @@ -use std::num::NonZero; +use core::num::NonZero; use bevy_ecs::{ entity::{Entity, EntityMapper, MapEntities}, diff --git a/crates/bevy_winit/src/accessibility.rs b/crates/bevy_winit/src/accessibility.rs index 0ab68eb89199a..b0b88ff220edb 100644 --- a/crates/bevy_winit/src/accessibility.rs +++ b/crates/bevy_winit/src/accessibility.rs @@ -1,9 +1,7 @@ //! Helpers for mapping window entities to accessibility types -use std::{ - collections::VecDeque, - sync::{Arc, Mutex}, -}; +use alloc::{collections::VecDeque, sync::Arc}; +use std::sync::Mutex; use accesskit_winit::Adapter; use bevy_a11y::{ diff --git a/crates/bevy_winit/src/lib.rs b/crates/bevy_winit/src/lib.rs index 7cb31a834f385..bd1cee59c3379 100644 --- a/crates/bevy_winit/src/lib.rs +++ b/crates/bevy_winit/src/lib.rs @@ -12,9 +12,11 @@ //! The app's [runner](bevy_app::App::runner) is set by `WinitPlugin` and handles the `winit` [`EventLoop`]. //! See `winit_runner` for details. +extern crate alloc; + use bevy_derive::Deref; use bevy_window::{RawHandleWrapperHolder, WindowEvent}; -use std::marker::PhantomData; +use core::marker::PhantomData; use winit::event_loop::EventLoop; #[cfg(target_os = "android")] pub use winit::platform::android::activity as android_activity; diff --git a/crates/bevy_winit/src/state.rs b/crates/bevy_winit/src/state.rs index 1ca75d1fbbb5f..53c21e71ec8eb 100644 --- a/crates/bevy_winit/src/state.rs +++ b/crates/bevy_winit/src/state.rs @@ -18,7 +18,7 @@ use bevy_math::{ivec2, DVec2, Vec2}; #[cfg(not(target_arch = "wasm32"))] use bevy_tasks::tick_global_task_pools_on_main_thread; use bevy_utils::{HashMap, Instant}; -use std::marker::PhantomData; +use core::marker::PhantomData; use winit::{ application::ApplicationHandler, dpi::PhysicalSize, diff --git a/crates/bevy_winit/src/winit_windows.rs b/crates/bevy_winit/src/winit_windows.rs index 299d0f92df7d4..bfefae0c87541 100644 --- a/crates/bevy_winit/src/winit_windows.rs +++ b/crates/bevy_winit/src/winit_windows.rs @@ -322,7 +322,7 @@ pub fn get_fitting_videomode(monitor: &MonitorHandle, width: u32, height: u32) - } modes.sort_by(|a, b| { - use std::cmp::Ordering::*; + use core::cmp::Ordering::*; match abs_diff(a.size().width, width).cmp(&abs_diff(b.size().width, width)) { Equal => { match abs_diff(a.size().height, height).cmp(&abs_diff(b.size().height, height)) { @@ -345,7 +345,7 @@ pub fn get_fitting_videomode(monitor: &MonitorHandle, width: u32, height: u32) - pub fn get_best_videomode(monitor: &MonitorHandle) -> VideoModeHandle { let mut modes = monitor.video_modes().collect::>(); modes.sort_by(|a, b| { - use std::cmp::Ordering::*; + use core::cmp::Ordering::*; match b.size().width.cmp(&a.size().width) { Equal => match b.size().height.cmp(&a.size().height) { Equal => b @@ -470,7 +470,7 @@ struct DisplayInfo { } impl core::fmt::Display for DisplayInfo { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { write!(f, "Display information:")?; write!( f, diff --git a/examples/2d/mesh2d_arcs.rs b/examples/2d/mesh2d_arcs.rs index a600c986b6bb2..b9f63ffd5bc18 100644 --- a/examples/2d/mesh2d_arcs.rs +++ b/examples/2d/mesh2d_arcs.rs @@ -1,6 +1,7 @@ //! Demonstrates UV mappings of the [`CircularSector`] and [`CircularSegment`] primitives. //! //! Also draws the bounding boxes and circles of the primitives. + use std::f32::consts::FRAC_PI_2; use bevy::{ diff --git a/examples/animation/animation_graph.rs b/examples/animation/animation_graph.rs index 50423e21fb4fa..94b9a2e52295e 100644 --- a/examples/animation/animation_graph.rs +++ b/examples/animation/animation_graph.rs @@ -3,9 +3,6 @@ //! The animation graph is shown on screen. You can change the weights of the //! playing animations by clicking and dragging left or right within the nodes. -#[cfg(not(target_arch = "wasm32"))] -use std::{fs::File, path::Path}; - use bevy::{ animation::animate_targets, color::palettes::{ @@ -17,12 +14,13 @@ use bevy::{ }; use argh::FromArgs; + #[cfg(not(target_arch = "wasm32"))] -use bevy::asset::io::file::FileAssetReader; -#[cfg(not(target_arch = "wasm32"))] -use bevy::tasks::IoTaskPool; -#[cfg(not(target_arch = "wasm32"))] -use ron::ser::PrettyConfig; +use { + bevy::{asset::io::file::FileAssetReader, tasks::IoTaskPool}, + ron::ser::PrettyConfig, + std::{fs::File, path::Path}, +}; /// Where to find the serialized animation graph. static ANIMATION_GRAPH_PATH: &str = "animation_graphs/Fox.animgraph.ron"; diff --git a/examples/audio/decodable.rs b/examples/audio/decodable.rs index f364314ae17ef..60f0c5443ff3d 100644 --- a/examples/audio/decodable.rs +++ b/examples/audio/decodable.rs @@ -1,4 +1,5 @@ //! Shows how to create a custom [`Decodable`] type by implementing a Sine wave. + use bevy::{ audio::{AddAudioSource, AudioPlugin, Source}, math::ops, diff --git a/examples/ui/overflow_debug.rs b/examples/ui/overflow_debug.rs index 07b479a7cd706..68ccfb0a6dd27 100644 --- a/examples/ui/overflow_debug.rs +++ b/examples/ui/overflow_debug.rs @@ -1,4 +1,5 @@ //! Tests how different transforms behave when clipped with `Overflow::Hidden` + use bevy::{input::common_conditions::input_just_pressed, prelude::*}; use std::f32::consts::{FRAC_PI_2, PI, TAU}; diff --git a/tools/build-templated-pages/src/examples.rs b/tools/build-templated-pages/src/examples.rs index a364d655de18a..318c5e62df9ab 100644 --- a/tools/build-templated-pages/src/examples.rs +++ b/tools/build-templated-pages/src/examples.rs @@ -1,4 +1,5 @@ -use std::{cmp::Ordering, fs::File}; +use core::cmp::Ordering; +use std::fs::File; use hashbrown::HashMap; use serde::Serialize; diff --git a/tools/build-templated-pages/src/features.rs b/tools/build-templated-pages/src/features.rs index 9ab11161a0f4e..eb7478f6c0f66 100644 --- a/tools/build-templated-pages/src/features.rs +++ b/tools/build-templated-pages/src/features.rs @@ -1,4 +1,5 @@ -use std::{cmp::Ordering, fs::File}; +use core::cmp::Ordering; +use std::fs::File; use serde::Serialize; use tera::{Context, Tera}; @@ -37,7 +38,7 @@ fn parse_features(panic_on_missing: bool) -> Vec { .unwrap() .iter() .flat_map(|v| { - std::iter::once(v.as_str().unwrap().to_string()).chain( + core::iter::once(v.as_str().unwrap().to_string()).chain( features .get(v.as_str().unwrap()) .unwrap() diff --git a/tools/example-showcase/disable-audio.patch b/tools/example-showcase/disable-audio.patch index 6fe4295837abb..70abd7d766eb6 100644 --- a/tools/example-showcase/disable-audio.patch +++ b/tools/example-showcase/disable-audio.patch @@ -17,7 +17,7 @@ index 3e8082e23..624769443 100644 fn default() -> Self { - if let Ok((stream, stream_handle)) = OutputStream::try_default() { - // We leak `OutputStream` to prevent the audio from stopping. -- std::mem::forget(stream); +- core::mem::forget(stream); - Self { - stream_handle: Some(stream_handle), - } diff --git a/tools/example-showcase/src/main.rs b/tools/example-showcase/src/main.rs index c9c1d9266f409..af3f4e0f699ce 100644 --- a/tools/example-showcase/src/main.rs +++ b/tools/example-showcase/src/main.rs @@ -1,15 +1,18 @@ //! Tool to run all examples or generate a showcase page for the Bevy website. +use core::{ + fmt::Display, + hash::{Hash, Hasher}, + time::Duration, +}; use std::{ collections::{hash_map::DefaultHasher, HashMap}, - fmt::Display, fs::{self, File}, - hash::{Hash, Hasher}, io::Write, path::{Path, PathBuf}, process::exit, thread, - time::{Duration, Instant}, + time::Instant, }; use clap::{error::ErrorKind, CommandFactory, Parser, ValueEnum}; @@ -119,7 +122,7 @@ enum WebApi { } impl Display for WebApi { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { match self { WebApi::Webgl2 => write!(f, "webgl2"), WebApi::Webgpu => write!(f, "webgpu"), From a0c722ff4ca3f95b44eddee5098b3bdb86e63812 Mon Sep 17 00:00:00 2001 From: Christian Hughes <9044780+ItsDoot@users.noreply.github.com> Date: Fri, 27 Sep 2024 07:06:40 -0700 Subject: [PATCH 09/17] Reduce memory usage in component fetches and change detection filters (#15283) ## Objective - Adopted #6396 ## Solution Same as #6396, we use a compile-time checked `StorageSwitch` union type to select the fetch data based on the component's storage type, saving >= 8 bytes per component fetch in a given query. Note: We forego the Query iteration change as it exists in a slightly different form now on main. ## Testing - All current tests pass locally. --------- Co-authored-by: james7132 Co-authored-by: Chris Russell <8494645+chescock@users.noreply.github.com> --- crates/bevy_ecs/src/query/fetch.rs | 313 +++++++++++++++++----------- crates/bevy_ecs/src/query/filter.rs | 114 ++++++---- 2 files changed, 268 insertions(+), 159 deletions(-) diff --git a/crates/bevy_ecs/src/query/fetch.rs b/crates/bevy_ecs/src/query/fetch.rs index e2140a36912ff..18a2ecda08155 100644 --- a/crates/bevy_ecs/src/query/fetch.rs +++ b/crates/bevy_ecs/src/query/fetch.rs @@ -1058,19 +1058,22 @@ unsafe impl QueryData for &Archetype { unsafe impl ReadOnlyQueryData for &Archetype {} #[doc(hidden)] -pub struct ReadFetch<'w, T> { - // T::STORAGE_TYPE = StorageType::Table - table_components: Option>>, - // T::STORAGE_TYPE = StorageType::SparseSet - sparse_set: Option<&'w ComponentSparseSet>, +pub struct ReadFetch<'w, T: Component> { + components: StorageSwitch< + T, + // T::STORAGE_TYPE = StorageType::Table + Option>>, + // T::STORAGE_TYPE = StorageType::SparseSet + &'w ComponentSparseSet, + >, } -impl Clone for ReadFetch<'_, T> { +impl Clone for ReadFetch<'_, T> { fn clone(&self) -> Self { *self } } -impl Copy for ReadFetch<'_, T> {} +impl Copy for ReadFetch<'_, T> {} /// SAFETY: /// `fetch` accesses a single component in a readonly way. @@ -1098,20 +1101,22 @@ unsafe impl WorldQuery for &T { _this_run: Tick, ) -> ReadFetch<'w, T> { ReadFetch { - table_components: None, - sparse_set: (T::STORAGE_TYPE == StorageType::SparseSet).then(|| { - // SAFETY: The underlying type associated with `component_id` is `T`, - // which we are allowed to access since we registered it in `update_archetype_component_access`. - // Note that we do not actually access any components in this function, we just get a shared - // reference to the sparse set, which is used to access the components in `Self::fetch`. - unsafe { - world - .storages() - .sparse_sets - .get(component_id) - .debug_checked_unwrap() - } - }), + components: StorageSwitch::new( + || None, + || { + // SAFETY: The underlying type associated with `component_id` is `T`, + // which we are allowed to access since we registered it in `update_archetype_component_access`. + // Note that we do not actually access any components in this function, we just get a shared + // reference to the sparse set, which is used to access the components in `Self::fetch`. + unsafe { + world + .storages() + .sparse_sets + .get(component_id) + .debug_checked_unwrap() + } + }, + ), } } @@ -1143,12 +1148,14 @@ unsafe impl WorldQuery for &T { &component_id: &ComponentId, table: &'w Table, ) { - fetch.table_components = Some( + let table_data = Some( table .get_data_slice_for(component_id) .debug_checked_unwrap() .into(), ); + // SAFETY: set_table is only called when T::STORAGE_TYPE = StorageType::Table + unsafe { fetch.components.set_table(table_data) }; } #[inline(always)] @@ -1157,22 +1164,20 @@ unsafe impl WorldQuery for &T { entity: Entity, table_row: TableRow, ) -> Self::Item<'w> { - match T::STORAGE_TYPE { - StorageType::Table => { - // SAFETY: STORAGE_TYPE = Table - let table = unsafe { fetch.table_components.debug_checked_unwrap() }; + fetch.components.extract( + |table| { + // SAFETY: set_table was previously called + let table = unsafe { table.debug_checked_unwrap() }; // SAFETY: Caller ensures `table_row` is in range. let item = unsafe { table.get(table_row.as_usize()) }; item.deref() - } - StorageType::SparseSet => { - // SAFETY: STORAGE_TYPE = SparseSet - let sparse_set = unsafe { fetch.sparse_set.debug_checked_unwrap() }; + }, + |sparse_set| { // SAFETY: Caller ensures `entity` is in range. let item = unsafe { sparse_set.get(entity).debug_checked_unwrap() }; item.deref() - } - } + }, + ) } fn update_component_access( @@ -1212,27 +1217,29 @@ unsafe impl QueryData for &T { unsafe impl ReadOnlyQueryData for &T {} #[doc(hidden)] -pub struct RefFetch<'w, T> { - // T::STORAGE_TYPE = StorageType::Table - table_data: Option<( - ThinSlicePtr<'w, UnsafeCell>, - ThinSlicePtr<'w, UnsafeCell>, - ThinSlicePtr<'w, UnsafeCell>, - MaybeThinSlicePtrLocation<'w>, - )>, - // T::STORAGE_TYPE = StorageType::SparseSet - sparse_set: Option<&'w ComponentSparseSet>, - +pub struct RefFetch<'w, T: Component> { + components: StorageSwitch< + T, + // T::STORAGE_TYPE = StorageType::Table + Option<( + ThinSlicePtr<'w, UnsafeCell>, + ThinSlicePtr<'w, UnsafeCell>, + ThinSlicePtr<'w, UnsafeCell>, + MaybeThinSlicePtrLocation<'w>, + )>, + // T::STORAGE_TYPE = StorageType::SparseSet + &'w ComponentSparseSet, + >, last_run: Tick, this_run: Tick, } -impl Clone for RefFetch<'_, T> { +impl Clone for RefFetch<'_, T> { fn clone(&self) -> Self { *self } } -impl Copy for RefFetch<'_, T> {} +impl Copy for RefFetch<'_, T> {} /// SAFETY: /// `fetch` accesses a single component in a readonly way. @@ -1260,20 +1267,22 @@ unsafe impl<'__w, T: Component> WorldQuery for Ref<'__w, T> { this_run: Tick, ) -> RefFetch<'w, T> { RefFetch { - table_data: None, - sparse_set: (T::STORAGE_TYPE == StorageType::SparseSet).then(|| { - // SAFETY: The underlying type associated with `component_id` is `T`, - // which we are allowed to access since we registered it in `update_archetype_component_access`. - // Note that we do not actually access any components in this function, we just get a shared - // reference to the sparse set, which is used to access the components in `Self::fetch`. - unsafe { - world - .storages() - .sparse_sets - .get(component_id) - .debug_checked_unwrap() - } - }), + components: StorageSwitch::new( + || None, + || { + // SAFETY: The underlying type associated with `component_id` is `T`, + // which we are allowed to access since we registered it in `update_archetype_component_access`. + // Note that we do not actually access any components in this function, we just get a shared + // reference to the sparse set, which is used to access the components in `Self::fetch`. + unsafe { + world + .storages() + .sparse_sets + .get(component_id) + .debug_checked_unwrap() + } + }, + ), last_run, this_run, } @@ -1308,7 +1317,7 @@ unsafe impl<'__w, T: Component> WorldQuery for Ref<'__w, T> { table: &'w Table, ) { let column = table.get_column(component_id).debug_checked_unwrap(); - fetch.table_data = Some(( + let table_data = Some(( column.get_data_slice(table.entity_count()).into(), column.get_added_ticks_slice(table.entity_count()).into(), column.get_changed_ticks_slice(table.entity_count()).into(), @@ -1317,6 +1326,8 @@ unsafe impl<'__w, T: Component> WorldQuery for Ref<'__w, T> { #[cfg(not(feature = "track_change_detection"))] (), )); + // SAFETY: set_table is only called when T::STORAGE_TYPE = StorageType::Table + unsafe { fetch.components.set_table(table_data) }; } #[inline(always)] @@ -1325,11 +1336,11 @@ unsafe impl<'__w, T: Component> WorldQuery for Ref<'__w, T> { entity: Entity, table_row: TableRow, ) -> Self::Item<'w> { - match T::STORAGE_TYPE { - StorageType::Table => { - // SAFETY: STORAGE_TYPE = Table + fetch.components.extract( + |table| { + // SAFETY: set_table was previously called let (table_components, added_ticks, changed_ticks, _callers) = - unsafe { fetch.table_data.debug_checked_unwrap() }; + unsafe { table.debug_checked_unwrap() }; // SAFETY: The caller ensures `table_row` is in range. let component = unsafe { table_components.get(table_row.as_usize()) }; @@ -1352,17 +1363,11 @@ unsafe impl<'__w, T: Component> WorldQuery for Ref<'__w, T> { #[cfg(feature = "track_change_detection")] changed_by: caller.deref(), } - } - StorageType::SparseSet => { - // SAFETY: STORAGE_TYPE = SparseSet - let component_sparse_set = unsafe { fetch.sparse_set.debug_checked_unwrap() }; - + }, + |sparse_set| { // SAFETY: The caller ensures `entity` is in range. - let (component, ticks, _caller) = unsafe { - component_sparse_set - .get_with_ticks(entity) - .debug_checked_unwrap() - }; + let (component, ticks, _caller) = + unsafe { sparse_set.get_with_ticks(entity).debug_checked_unwrap() }; Ref { value: component.deref(), @@ -1370,8 +1375,8 @@ unsafe impl<'__w, T: Component> WorldQuery for Ref<'__w, T> { #[cfg(feature = "track_change_detection")] changed_by: _caller.deref(), } - } - } + }, + ) } fn update_component_access( @@ -1411,27 +1416,29 @@ unsafe impl<'__w, T: Component> QueryData for Ref<'__w, T> { unsafe impl<'__w, T: Component> ReadOnlyQueryData for Ref<'__w, T> {} #[doc(hidden)] -pub struct WriteFetch<'w, T> { - // T::STORAGE_TYPE = StorageType::Table - table_data: Option<( - ThinSlicePtr<'w, UnsafeCell>, - ThinSlicePtr<'w, UnsafeCell>, - ThinSlicePtr<'w, UnsafeCell>, - MaybeThinSlicePtrLocation<'w>, - )>, - // T::STORAGE_TYPE = StorageType::SparseSet - sparse_set: Option<&'w ComponentSparseSet>, - +pub struct WriteFetch<'w, T: Component> { + components: StorageSwitch< + T, + // T::STORAGE_TYPE = StorageType::Table + Option<( + ThinSlicePtr<'w, UnsafeCell>, + ThinSlicePtr<'w, UnsafeCell>, + ThinSlicePtr<'w, UnsafeCell>, + MaybeThinSlicePtrLocation<'w>, + )>, + // T::STORAGE_TYPE = StorageType::SparseSet + &'w ComponentSparseSet, + >, last_run: Tick, this_run: Tick, } -impl Clone for WriteFetch<'_, T> { +impl Clone for WriteFetch<'_, T> { fn clone(&self) -> Self { *self } } -impl Copy for WriteFetch<'_, T> {} +impl Copy for WriteFetch<'_, T> {} /// SAFETY: /// `fetch` accesses a single component mutably. @@ -1459,20 +1466,22 @@ unsafe impl<'__w, T: Component> WorldQuery for &'__w mut T { this_run: Tick, ) -> WriteFetch<'w, T> { WriteFetch { - table_data: None, - sparse_set: (T::STORAGE_TYPE == StorageType::SparseSet).then(|| { - // SAFETY: The underlying type associated with `component_id` is `T`, - // which we are allowed to access since we registered it in `update_archetype_component_access`. - // Note that we do not actually access any components in this function, we just get a shared - // reference to the sparse set, which is used to access the components in `Self::fetch`. - unsafe { - world - .storages() - .sparse_sets - .get(component_id) - .debug_checked_unwrap() - } - }), + components: StorageSwitch::new( + || None, + || { + // SAFETY: The underlying type associated with `component_id` is `T`, + // which we are allowed to access since we registered it in `update_archetype_component_access`. + // Note that we do not actually access any components in this function, we just get a shared + // reference to the sparse set, which is used to access the components in `Self::fetch`. + unsafe { + world + .storages() + .sparse_sets + .get(component_id) + .debug_checked_unwrap() + } + }, + ), last_run, this_run, } @@ -1507,7 +1516,7 @@ unsafe impl<'__w, T: Component> WorldQuery for &'__w mut T { table: &'w Table, ) { let column = table.get_column(component_id).debug_checked_unwrap(); - fetch.table_data = Some(( + let table_data = Some(( column.get_data_slice(table.entity_count()).into(), column.get_added_ticks_slice(table.entity_count()).into(), column.get_changed_ticks_slice(table.entity_count()).into(), @@ -1516,6 +1525,8 @@ unsafe impl<'__w, T: Component> WorldQuery for &'__w mut T { #[cfg(not(feature = "track_change_detection"))] (), )); + // SAFETY: set_table is only called when T::STORAGE_TYPE = StorageType::Table + unsafe { fetch.components.set_table(table_data) }; } #[inline(always)] @@ -1524,11 +1535,11 @@ unsafe impl<'__w, T: Component> WorldQuery for &'__w mut T { entity: Entity, table_row: TableRow, ) -> Self::Item<'w> { - match T::STORAGE_TYPE { - StorageType::Table => { - // SAFETY: STORAGE_TYPE = Table + fetch.components.extract( + |table| { + // SAFETY: set_table was previously called let (table_components, added_ticks, changed_ticks, _callers) = - unsafe { fetch.table_data.debug_checked_unwrap() }; + unsafe { table.debug_checked_unwrap() }; // SAFETY: The caller ensures `table_row` is in range. let component = unsafe { table_components.get(table_row.as_usize()) }; @@ -1551,17 +1562,11 @@ unsafe impl<'__w, T: Component> WorldQuery for &'__w mut T { #[cfg(feature = "track_change_detection")] changed_by: caller.deref_mut(), } - } - StorageType::SparseSet => { - // SAFETY: STORAGE_TYPE = SparseSet - let component_sparse_set = unsafe { fetch.sparse_set.debug_checked_unwrap() }; - + }, + |sparse_set| { // SAFETY: The caller ensures `entity` is in range. - let (component, ticks, _caller) = unsafe { - component_sparse_set - .get_with_ticks(entity) - .debug_checked_unwrap() - }; + let (component, ticks, _caller) = + unsafe { sparse_set.get_with_ticks(entity).debug_checked_unwrap() }; Mut { value: component.assert_unique().deref_mut(), @@ -1569,8 +1574,8 @@ unsafe impl<'__w, T: Component> WorldQuery for &'__w mut T { #[cfg(feature = "track_change_detection")] changed_by: _caller.deref_mut(), } - } - } + }, + ) } fn update_component_access( @@ -2312,6 +2317,74 @@ unsafe impl QueryData for PhantomData { /// SAFETY: `PhantomData` never accesses any world data. unsafe impl ReadOnlyQueryData for PhantomData {} +/// A compile-time checked union of two different types that differs based on the +/// [`StorageType`] of a given component. +pub(super) union StorageSwitch { + /// The table variant. Requires the component to be a table component. + table: T, + /// The sparse set variant. Requires the component to be a sparse set component. + sparse_set: S, + _marker: PhantomData, +} + +impl StorageSwitch { + /// Creates a new [`StorageSwitch`] using the given closures to initialize + /// the variant corresponding to the component's [`StorageType`]. + pub fn new(table: impl FnOnce() -> T, sparse_set: impl FnOnce() -> S) -> Self { + match C::STORAGE_TYPE { + StorageType::Table => Self { table: table() }, + StorageType::SparseSet => Self { + sparse_set: sparse_set(), + }, + } + } + + /// Creates a new [`StorageSwitch`] using a table variant. + /// + /// # Panics + /// + /// This will panic on debug builds if `C` is not a table component. + /// + /// # Safety + /// + /// `C` must be a table component. + #[inline] + pub unsafe fn set_table(&mut self, table: T) { + match C::STORAGE_TYPE { + StorageType::Table => self.table = table, + _ => { + #[cfg(debug_assertions)] + unreachable!(); + #[cfg(not(debug_assertions))] + std::hint::unreachable_unchecked() + } + } + } + + /// Fetches the internal value from the variant that corresponds to the + /// component's [`StorageType`]. + pub fn extract(&self, table: impl FnOnce(T) -> R, sparse_set: impl FnOnce(S) -> R) -> R { + match C::STORAGE_TYPE { + StorageType::Table => table( + // SAFETY: C::STORAGE_TYPE == StorageType::Table + unsafe { self.table }, + ), + StorageType::SparseSet => sparse_set( + // SAFETY: C::STORAGE_TYPE == StorageType::SparseSet + unsafe { self.sparse_set }, + ), + } + } +} + +impl Clone for StorageSwitch { + fn clone(&self) -> Self { + *self + } +} + +impl Copy for StorageSwitch {} + #[cfg(test)] mod tests { use bevy_ecs_macros::QueryData; diff --git a/crates/bevy_ecs/src/query/filter.rs b/crates/bevy_ecs/src/query/filter.rs index 8395d548989ef..e75f506039a29 100644 --- a/crates/bevy_ecs/src/query/filter.rs +++ b/crates/bevy_ecs/src/query/filter.rs @@ -2,7 +2,7 @@ use crate::{ archetype::Archetype, component::{Component, ComponentId, Components, StorageType, Tick}, entity::Entity, - query::{DebugCheckedUnwrap, FilteredAccess, WorldQuery}, + query::{DebugCheckedUnwrap, FilteredAccess, StorageSwitch, WorldQuery}, storage::{ComponentSparseSet, Table, TableRow}, world::{unsafe_world_cell::UnsafeWorldCell, World}, }; @@ -615,14 +615,28 @@ all_tuples!(impl_or_query_filter, 0, 15, F, S); pub struct Added(PhantomData); #[doc(hidden)] -#[derive(Clone)] -pub struct AddedFetch<'w> { - table_ticks: Option>>, - sparse_set: Option<&'w ComponentSparseSet>, +pub struct AddedFetch<'w, T: Component> { + ticks: StorageSwitch< + T, + // T::STORAGE_TYPE = StorageType::Table + Option>>, + // T::STORAGE_TYPE = StorageType::SparseSet + &'w ComponentSparseSet, + >, last_run: Tick, this_run: Tick, } +impl Clone for AddedFetch<'_, T> { + fn clone(&self) -> Self { + Self { + ticks: self.ticks, + last_run: self.last_run, + this_run: self.this_run, + } + } +} + /// SAFETY: /// `fetch` accesses a single component in a readonly way. /// This is sound because `update_component_access` adds read access for that component and panics when appropriate. @@ -630,7 +644,7 @@ pub struct AddedFetch<'w> { /// This is sound because `matches_component_set` returns whether the set contains that component. unsafe impl WorldQuery for Added { type Item<'w> = bool; - type Fetch<'w> = AddedFetch<'w>; + type Fetch<'w> = AddedFetch<'w, T>; type State = ComponentId; fn shrink<'wlong: 'wshort, 'wshort>(item: Self::Item<'wlong>) -> Self::Item<'wshort> { @@ -649,9 +663,16 @@ unsafe impl WorldQuery for Added { this_run: Tick, ) -> Self::Fetch<'w> { Self::Fetch::<'w> { - table_ticks: None, - sparse_set: (T::STORAGE_TYPE == StorageType::SparseSet) - .then(|| world.storages().sparse_sets.get(id).debug_checked_unwrap()), + ticks: StorageSwitch::new( + || None, + || { + // SAFETY: The underlying type associated with `component_id` is `T`, + // which we are allowed to access since we registered it in `update_archetype_component_access`. + // Note that we do not actually access any components' ticks in this function, we just get a shared + // reference to the sparse set, which is used to access the components' ticks in `Self::fetch`. + unsafe { world.storages().sparse_sets.get(id).debug_checked_unwrap() } + }, + ), last_run, this_run, } @@ -685,12 +706,14 @@ unsafe impl WorldQuery for Added { &component_id: &ComponentId, table: &'w Table, ) { - fetch.table_ticks = Some( + let table_ticks = Some( table .get_added_ticks_slice_for(component_id) .debug_checked_unwrap() .into(), ); + // SAFETY: set_table is only called when T::STORAGE_TYPE = StorageType::Table + unsafe { fetch.ticks.set_table(table_ticks) }; } #[inline(always)] @@ -699,26 +722,24 @@ unsafe impl WorldQuery for Added { entity: Entity, table_row: TableRow, ) -> Self::Item<'w> { - match T::STORAGE_TYPE { - StorageType::Table => { - // SAFETY: STORAGE_TYPE = Table - let table = unsafe { fetch.table_ticks.debug_checked_unwrap() }; + fetch.ticks.extract( + |table| { + // SAFETY: set_table was previously called + let table = unsafe { table.debug_checked_unwrap() }; // SAFETY: The caller ensures `table_row` is in range. let tick = unsafe { table.get(table_row.as_usize()) }; tick.deref().is_newer_than(fetch.last_run, fetch.this_run) - } - StorageType::SparseSet => { - // SAFETY: STORAGE_TYPE = SparseSet - let sparse_set = unsafe { &fetch.sparse_set.debug_checked_unwrap() }; + }, + |sparse_set| { // SAFETY: The caller ensures `entity` is in range. let tick = unsafe { ComponentSparseSet::get_added_tick(sparse_set, entity).debug_checked_unwrap() }; tick.deref().is_newer_than(fetch.last_run, fetch.this_run) - } - } + }, + ) } #[inline] @@ -833,14 +854,22 @@ unsafe impl QueryFilter for Added { pub struct Changed(PhantomData); #[doc(hidden)] -#[derive(Clone)] -pub struct ChangedFetch<'w> { - table_ticks: Option>>, - sparse_set: Option<&'w ComponentSparseSet>, +pub struct ChangedFetch<'w, T: Component> { + ticks: StorageSwitch>>, &'w ComponentSparseSet>, last_run: Tick, this_run: Tick, } +impl Clone for ChangedFetch<'_, T> { + fn clone(&self) -> Self { + Self { + ticks: self.ticks, + last_run: self.last_run, + this_run: self.this_run, + } + } +} + /// SAFETY: /// `fetch` accesses a single component in a readonly way. /// This is sound because `update_component_access` add read access for that component and panics when appropriate. @@ -848,7 +877,7 @@ pub struct ChangedFetch<'w> { /// This is sound because `matches_component_set` returns whether the set contains that component. unsafe impl WorldQuery for Changed { type Item<'w> = bool; - type Fetch<'w> = ChangedFetch<'w>; + type Fetch<'w> = ChangedFetch<'w, T>; type State = ComponentId; fn shrink<'wlong: 'wshort, 'wshort>(item: Self::Item<'wlong>) -> Self::Item<'wshort> { @@ -867,9 +896,16 @@ unsafe impl WorldQuery for Changed { this_run: Tick, ) -> Self::Fetch<'w> { Self::Fetch::<'w> { - table_ticks: None, - sparse_set: (T::STORAGE_TYPE == StorageType::SparseSet) - .then(|| world.storages().sparse_sets.get(id).debug_checked_unwrap()), + ticks: StorageSwitch::new( + || None, + || { + // SAFETY: The underlying type associated with `component_id` is `T`, + // which we are allowed to access since we registered it in `update_archetype_component_access`. + // Note that we do not actually access any components' ticks in this function, we just get a shared + // reference to the sparse set, which is used to access the components' ticks in `Self::fetch`. + unsafe { world.storages().sparse_sets.get(id).debug_checked_unwrap() } + }, + ), last_run, this_run, } @@ -903,12 +939,14 @@ unsafe impl WorldQuery for Changed { &component_id: &ComponentId, table: &'w Table, ) { - fetch.table_ticks = Some( + let table_ticks = Some( table .get_changed_ticks_slice_for(component_id) .debug_checked_unwrap() .into(), ); + // SAFETY: set_table is only called when T::STORAGE_TYPE = StorageType::Table + unsafe { fetch.ticks.set_table(table_ticks) }; } #[inline(always)] @@ -917,26 +955,24 @@ unsafe impl WorldQuery for Changed { entity: Entity, table_row: TableRow, ) -> Self::Item<'w> { - match T::STORAGE_TYPE { - StorageType::Table => { - // SAFETY: STORAGE_TYPE = Table - let table = unsafe { fetch.table_ticks.debug_checked_unwrap() }; + fetch.ticks.extract( + |table| { + // SAFETY: set_table was previously called + let table = unsafe { table.debug_checked_unwrap() }; // SAFETY: The caller ensures `table_row` is in range. let tick = unsafe { table.get(table_row.as_usize()) }; tick.deref().is_newer_than(fetch.last_run, fetch.this_run) - } - StorageType::SparseSet => { - // SAFETY: STORAGE_TYPE = SparseSet - let sparse_set = unsafe { &fetch.sparse_set.debug_checked_unwrap() }; + }, + |sparse_set| { // SAFETY: The caller ensures `entity` is in range. let tick = unsafe { ComponentSparseSet::get_changed_tick(sparse_set, entity).debug_checked_unwrap() }; tick.deref().is_newer_than(fetch.last_run, fetch.this_run) - } - } + }, + ) } #[inline] From b04947d44fbaf4bceac2fb9e1fb7ad65e631830a Mon Sep 17 00:00:00 2001 From: Emerson Coskey <56370779+ecoskey@users.noreply.github.com> Date: Fri, 27 Sep 2024 10:06:48 -0700 Subject: [PATCH 10/17] Migrate `bevy_transform` to required components (#14964) The first step in the migration to required components! This PR removes `GlobalTransform` from all user-facing code, since it's now added automatically wherever `Transform` is used. ## Testing - None of the examples I tested were broken, and I assume breaking transforms in any way would be visible *everywhere* --- ## Changelog - Make `Transform` require `GlobalTransform` ~~- Remove `GlobalTransform` from all engine bundles~~ - Remove in-engine insertions of GlobalTransform and TransformBundle - Deprecate `TransformBundle` - update docs to reflect changes ## Migration Guide Replace all insertions of `GlobalTransform` and/or `TransformBundle` with `Transform` alone. --------- Co-authored-by: Alice Cecile Co-authored-by: Tim --- crates/bevy_transform/src/bundles.rs | 5 ++ .../src/components/global_transform.rs | 4 +- .../src/components/transform.rs | 5 +- crates/bevy_transform/src/helper.rs | 3 +- crates/bevy_transform/src/lib.rs | 2 + crates/bevy_transform/src/systems.rs | 61 ++++++------------- errors/B0004.md | 14 ++--- examples/animation/custom_skinned_mesh.rs | 10 +-- examples/asset/asset_decompression.rs | 2 +- examples/stress_tests/transform_hierarchy.rs | 4 +- 10 files changed, 43 insertions(+), 67 deletions(-) diff --git a/crates/bevy_transform/src/bundles.rs b/crates/bevy_transform/src/bundles.rs index dc8931824a7fd..34b05ec6518d9 100644 --- a/crates/bevy_transform/src/bundles.rs +++ b/crates/bevy_transform/src/bundles.rs @@ -1,3 +1,4 @@ +#![expect(deprecated)] use bevy_ecs::bundle::Bundle; use crate::prelude::{GlobalTransform, Transform}; @@ -24,6 +25,10 @@ use crate::prelude::{GlobalTransform, Transform}; /// update the [`Transform`] of an entity in this schedule or after, you will notice a 1 frame lag /// before the [`GlobalTransform`] is updated. #[derive(Clone, Copy, Debug, Default, Bundle)] +#[deprecated( + since = "0.15.0", + note = "Use the `Transform` component instead. Inserting `Transform` will now also insert a `GlobalTransform` automatically." +)] pub struct TransformBundle { /// The transform of the entity. pub local: Transform, diff --git a/crates/bevy_transform/src/components/global_transform.rs b/crates/bevy_transform/src/components/global_transform.rs index b3f4988e4481b..06a89f25556a9 100644 --- a/crates/bevy_transform/src/components/global_transform.rs +++ b/crates/bevy_transform/src/components/global_transform.rs @@ -17,7 +17,9 @@ use { /// /// * To get the global transform of an entity, you should get its [`GlobalTransform`]. /// * For transform hierarchies to work correctly, you must have both a [`Transform`] and a [`GlobalTransform`]. -/// * You may use the [`TransformBundle`](crate::bundles::TransformBundle) to guarantee this. +/// ~* You may use the [`TransformBundle`](crate::bundles::TransformBundle) to guarantee this.~ +/// * [`TransformBundle`](crate::bundles::TransformBundle) is now deprecated. +/// [`GlobalTransform`] is automatically inserted whenever [`Transform`] is inserted. /// /// ## [`Transform`] and [`GlobalTransform`] /// diff --git a/crates/bevy_transform/src/components/transform.rs b/crates/bevy_transform/src/components/transform.rs index e43b6bf4b43e7..5e676b2752824 100644 --- a/crates/bevy_transform/src/components/transform.rs +++ b/crates/bevy_transform/src/components/transform.rs @@ -13,7 +13,9 @@ use { /// * To place or move an entity, you should set its [`Transform`]. /// * To get the global transform of an entity, you should get its [`GlobalTransform`]. /// * To be displayed, an entity must have both a [`Transform`] and a [`GlobalTransform`]. -/// * You may use the [`TransformBundle`](crate::bundles::TransformBundle) to guarantee this. +/// ~* You may use the [`TransformBundle`](crate::bundles::TransformBundle) to guarantee this.~ +/// * [`TransformBundle`](crate::bundles::TransformBundle) is now deprecated. +/// [`GlobalTransform`] is inserted automatically whenever [`Transform`] is inserted. /// /// ## [`Transform`] and [`GlobalTransform`] /// @@ -39,6 +41,7 @@ use { #[cfg_attr( feature = "bevy-support", derive(Component, Reflect), + require(GlobalTransform), reflect(Component, Default, PartialEq, Debug) )] #[cfg_attr( diff --git a/crates/bevy_transform/src/helper.rs b/crates/bevy_transform/src/helper.rs index 7b3b206170d3d..1ae3ca9616a8d 100644 --- a/crates/bevy_transform/src/helper.rs +++ b/crates/bevy_transform/src/helper.rs @@ -88,7 +88,6 @@ mod tests { use bevy_math::{Quat, Vec3}; use crate::{ - bundles::TransformBundle, components::{GlobalTransform, Transform}, helper::TransformHelper, plugins::TransformPlugin, @@ -122,7 +121,7 @@ mod tests { let mut entity = None; for transform in transforms { - let mut e = app.world_mut().spawn(TransformBundle::from(transform)); + let mut e = app.world_mut().spawn(transform); if let Some(entity) = entity { e.set_parent(entity); diff --git a/crates/bevy_transform/src/lib.rs b/crates/bevy_transform/src/lib.rs index e3705742a004b..8aed69e08b4ce 100644 --- a/crates/bevy_transform/src/lib.rs +++ b/crates/bevy_transform/src/lib.rs @@ -32,6 +32,8 @@ pub mod systems; /// The transform prelude. /// /// This includes the most common types in this crate, re-exported for your convenience. +#[doc(hidden)] +#[expect(deprecated)] pub mod prelude { #[doc(hidden)] pub use crate::components::*; diff --git a/crates/bevy_transform/src/systems.rs b/crates/bevy_transform/src/systems.rs index a06432b0f3d30..4935d05f8ffed 100644 --- a/crates/bevy_transform/src/systems.rs +++ b/crates/bevy_transform/src/systems.rs @@ -190,7 +190,7 @@ mod test { use bevy_math::{vec3, Vec3}; use bevy_tasks::{ComputeTaskPool, TaskPool}; - use crate::{bundles::TransformBundle, systems::*}; + use crate::systems::*; use bevy_hierarchy::{BuildChildren, ChildBuild}; #[test] @@ -199,8 +199,7 @@ mod test { let mut world = World::default(); let offset_global_transform = |offset| GlobalTransform::from(Transform::from_xyz(offset, offset, offset)); - let offset_transform = - |offset| TransformBundle::from_transform(Transform::from_xyz(offset, offset, offset)); + let offset_transform = |offset| Transform::from_xyz(offset, offset, offset); let mut schedule = Schedule::default(); schedule.add_systems((sync_simple_transforms, propagate_transforms)); @@ -257,22 +256,14 @@ mod test { schedule.add_systems((sync_simple_transforms, propagate_transforms)); // Root entity - world.spawn(TransformBundle::from(Transform::from_xyz(1.0, 0.0, 0.0))); + world.spawn(Transform::from_xyz(1.0, 0.0, 0.0)); let mut children = Vec::new(); world - .spawn(TransformBundle::from(Transform::from_xyz(1.0, 0.0, 0.0))) + .spawn(Transform::from_xyz(1.0, 0.0, 0.0)) .with_children(|parent| { - children.push( - parent - .spawn(TransformBundle::from(Transform::from_xyz(0.0, 2.0, 0.))) - .id(), - ); - children.push( - parent - .spawn(TransformBundle::from(Transform::from_xyz(0.0, 0.0, 3.))) - .id(), - ); + children.push(parent.spawn(Transform::from_xyz(0.0, 2.0, 0.)).id()); + children.push(parent.spawn(Transform::from_xyz(0.0, 0.0, 3.)).id()); }); schedule.run(&mut world); @@ -299,18 +290,10 @@ mod test { let mut commands = Commands::new(&mut queue, &world); let mut children = Vec::new(); commands - .spawn(TransformBundle::from(Transform::from_xyz(1.0, 0.0, 0.0))) + .spawn(Transform::from_xyz(1.0, 0.0, 0.0)) .with_children(|parent| { - children.push( - parent - .spawn(TransformBundle::from(Transform::from_xyz(0.0, 2.0, 0.0))) - .id(), - ); - children.push( - parent - .spawn(TransformBundle::from(Transform::from_xyz(0.0, 0.0, 3.0))) - .id(), - ); + children.push(parent.spawn(Transform::from_xyz(0.0, 2.0, 0.0)).id()); + children.push(parent.spawn(Transform::from_xyz(0.0, 0.0, 3.0)).id()); }); queue.apply(&mut world); schedule.run(&mut world); @@ -417,15 +400,12 @@ mod test { let mut grandchild = Entity::from_raw(1); let parent = app .world_mut() - .spawn(( - Transform::from_translation(translation), - GlobalTransform::IDENTITY, - )) + .spawn(Transform::from_translation(translation)) .with_children(|builder| { child = builder - .spawn(TransformBundle::IDENTITY) + .spawn(Transform::IDENTITY) .with_children(|builder| { - grandchild = builder.spawn(TransformBundle::IDENTITY).id(); + grandchild = builder.spawn(Transform::IDENTITY).id(); }) .id(); }) @@ -462,9 +442,9 @@ mod test { fn setup_world(world: &mut World) -> (Entity, Entity) { let mut grandchild = Entity::from_raw(0); let child = world - .spawn(TransformBundle::IDENTITY) + .spawn(Transform::IDENTITY) .with_children(|builder| { - grandchild = builder.spawn(TransformBundle::IDENTITY).id(); + grandchild = builder.spawn(Transform::IDENTITY).id(); }) .id(); (child, grandchild) @@ -477,7 +457,7 @@ mod test { assert_eq!(temp_grandchild, grandchild); app.world_mut() - .spawn(TransformBundle::IDENTITY) + .spawn(Transform::IDENTITY) .add_children(&[child]); core::mem::swap( &mut *app.world_mut().get_mut::(child).unwrap(), @@ -496,14 +476,9 @@ mod test { let mut schedule = Schedule::default(); schedule.add_systems((sync_simple_transforms, propagate_transforms)); - // Spawn a `TransformBundle` entity with a local translation of `Vec3::ONE` - let mut spawn_transform_bundle = || { - world - .spawn(TransformBundle::from_transform( - Transform::from_translation(translation), - )) - .id() - }; + // Spawn a `Transform` entity with a local translation of `Vec3::ONE` + let mut spawn_transform_bundle = + || world.spawn(Transform::from_translation(translation)).id(); // Spawn parent and child with identical transform bundles let parent = spawn_transform_bundle(); diff --git a/errors/B0004.md b/errors/B0004.md index 5cf94109bfa51..0d81c0b3cd4e8 100644 --- a/errors/B0004.md +++ b/errors/B0004.md @@ -29,7 +29,7 @@ fn setup_cube( mut materials: ResMut>, ) { commands - .spawn(TransformBundle::default()) + .spawn(Transform::default()) .with_children(|parent| { // cube parent.spawn(PbrBundle { @@ -61,8 +61,7 @@ doesn't have a [`ViewVisibility`] or [`InheritedVisibility`] component. Since the cube is spawned as a child of an entity without the visibility components, it will not be visible at all. -To fix this, you must use [`SpatialBundle`] over [`TransformBundle`], -as follows: +To fix this, you must use [`SpatialBundle`], as follows: ```rust,no_run use bevy::prelude::*; @@ -73,7 +72,7 @@ fn setup_cube( mut materials: ResMut>, ) { commands - // We use SpatialBundle instead of TransformBundle, it contains the + // We use SpatialBundle instead of Transform, it contains the // visibility components needed to display the cube, // In addition to the Transform and GlobalTransform components. .spawn(SpatialBundle::default()) @@ -103,9 +102,8 @@ fn main() { ``` A similar problem occurs when the [`GlobalTransform`] component is missing. -However, when a parent [`GlobalTransform`] is missing, -it will simply prevent all transform propagation, -including when updating the [`Transform`] component of the child. +However, it will be automatically inserted whenever `Transform` is +inserted, as it's a required component. You will most likely encounter this warning when loading a scene as a child of a pre-existing [`Entity`] that does not have the proper components. @@ -113,8 +111,6 @@ as a child of a pre-existing [`Entity`] that does not have the proper components [`InheritedVisibility`]: https://docs.rs/bevy/*/bevy/render/view/struct.InheritedVisibility.html [`ViewVisibility`]: https://docs.rs/bevy/*/bevy/render/view/struct.ViewVisibility.html [`GlobalTransform`]: https://docs.rs/bevy/*/bevy/transform/components/struct.GlobalTransform.html -[`Transform`]: https://docs.rs/bevy/*/bevy/transform/components/struct.Transform.html [`Parent`]: https://docs.rs/bevy/*/bevy/hierarchy/struct.Parent.html [`Entity`]: https://docs.rs/bevy/*/bevy/ecs/entity/struct.Entity.html [`SpatialBundle`]: https://docs.rs/bevy/*/bevy/render/prelude/struct.SpatialBundle.html -[`TransformBundle`]: https://docs.rs/bevy/*/bevy/transform/struct.TransformBundle.html diff --git a/examples/animation/custom_skinned_mesh.rs b/examples/animation/custom_skinned_mesh.rs index 68acfad59b0ef..f80ddf2ffca17 100644 --- a/examples/animation/custom_skinned_mesh.rs +++ b/examples/animation/custom_skinned_mesh.rs @@ -130,15 +130,9 @@ fn setup( for i in -5..5 { // Create joint entities let joint_0 = commands - .spawn(TransformBundle::from(Transform::from_xyz( - i as f32 * 1.5, - 0.0, - i as f32 * 0.1, - ))) - .id(); - let joint_1 = commands - .spawn((AnimatedJoint, TransformBundle::IDENTITY)) + .spawn(Transform::from_xyz(i as f32 * 1.5, 0.0, i as f32 * 0.1)) .id(); + let joint_1 = commands.spawn((AnimatedJoint, Transform::IDENTITY)).id(); // Set joint_1 as a child of joint_0. commands.entity(joint_0).add_children(&[joint_1]); diff --git a/examples/asset/asset_decompression.rs b/examples/asset/asset_decompression.rs index 70c0116d19e2b..09150311696cf 100644 --- a/examples/asset/asset_decompression.rs +++ b/examples/asset/asset_decompression.rs @@ -111,7 +111,7 @@ fn setup(mut commands: Commands, asset_server: Res) { ..default() }, Sprite::default(), - TransformBundle::default(), + Transform::default(), VisibilityBundle::default(), )); } diff --git a/examples/stress_tests/transform_hierarchy.rs b/examples/stress_tests/transform_hierarchy.rs index fb88f76d87f68..39fc5f001f0ca 100644 --- a/examples/stress_tests/transform_hierarchy.rs +++ b/examples/stress_tests/transform_hierarchy.rs @@ -380,7 +380,7 @@ fn spawn_tree( } // insert root - ents.push(commands.spawn(TransformBundle::from(root_transform)).id()); + ents.push(commands.spawn(root_transform).id()); let mut result = InsertResult::default(); let mut rng = rand::thread_rng(); @@ -426,7 +426,7 @@ fn spawn_tree( }; // only insert the components necessary for the transform propagation - cmd = cmd.insert(TransformBundle::from(transform)); + cmd = cmd.insert(transform); cmd.id() }; From 2486343e87319b7675d68f184bdf25268d4fed90 Mon Sep 17 00:00:00 2001 From: Chris Russell <8494645+chescock@users.noreply.github.com> Date: Fri, 27 Sep 2024 14:18:03 -0400 Subject: [PATCH 11/17] Include AnimationTarget directly in the animation query rather than reading it through the EntityMut (#15413) # Objective Improve the performance of animation. `animate_targets` only does work for entities with a `AnimationTarget` component, but the query it uses has no filters and matches all archetypes, resulting in extra work checking and ignoring every other entity in the world. In addition, it uses `EntityMutExcept::get`, which has to look up the `ComponentId` for `AnimationTarget` each time it's used. Fixes #15412 ## Solution Instead of `entity_mut.get::()`, add `&AnimationTarget` to the query and read it directly. This requires adding `AnimationTarget` to the list of exceptions in the `EntityMutExcept`. Since the resulting type is getting long, add an alias for it. This does mean that `AnimationTarget` is no longer available through `entity`, which means it's not possible to animate the `AnimationTarget` component itself. ## Testing I ran performance traces of many_foxes comparing this branch to main. Red is main, yellow is these changes: ![image](https://github.com/user-attachments/assets/93ef7d70-5103-4952-86b9-312aafc53e5f) --- crates/bevy_animation/src/keyframes.rs | 33 +++++++++++--------------- crates/bevy_animation/src/lib.rs | 25 +++++++++++-------- 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/crates/bevy_animation/src/keyframes.rs b/crates/bevy_animation/src/keyframes.rs index 11eca23141c47..8da153aab4b9e 100644 --- a/crates/bevy_animation/src/keyframes.rs +++ b/crates/bevy_animation/src/keyframes.rs @@ -5,12 +5,8 @@ use core::{ fmt::{self, Debug, Formatter}, }; -use bevy_asset::Handle; use bevy_derive::{Deref, DerefMut}; -use bevy_ecs::{ - component::Component, - world::{EntityMutExcept, Mut}, -}; +use bevy_ecs::{component::Component, world::Mut}; use bevy_math::{Quat, Vec3}; use bevy_reflect::{FromReflect, GetTypeRegistration, Reflect, TypePath, Typed}; use bevy_render::mesh::morph::MorphWeights; @@ -18,9 +14,8 @@ use bevy_transform::prelude::Transform; use crate::{ animatable, - graph::AnimationGraph, prelude::{Animatable, GetKeyframe}, - AnimationEvaluationError, AnimationPlayer, Interpolation, + AnimationEntityMut, AnimationEvaluationError, Interpolation, }; /// A value on a component that Bevy can animate. @@ -154,7 +149,7 @@ pub trait Keyframes: Reflect + Debug + Send + Sync { fn apply_single_keyframe<'a>( &self, transform: Option>, - entity: EntityMutExcept<'a, (Transform, AnimationPlayer, Handle)>, + entity: AnimationEntityMut<'a>, weight: f32, ) -> Result<(), AnimationEvaluationError>; @@ -185,7 +180,7 @@ pub trait Keyframes: Reflect + Debug + Send + Sync { fn apply_tweened_keyframes<'a>( &self, transform: Option>, - entity: EntityMutExcept<'a, (Transform, AnimationPlayer, Handle)>, + entity: AnimationEntityMut<'a>, interpolation: Interpolation, step_start: usize, time: f32, @@ -285,7 +280,7 @@ impl Keyframes for TranslationKeyframes { fn apply_single_keyframe<'a>( &self, transform: Option>, - _: EntityMutExcept<'a, (Transform, AnimationPlayer, Handle)>, + _: AnimationEntityMut<'a>, weight: f32, ) -> Result<(), AnimationEvaluationError> { let mut component = transform.ok_or_else(|| { @@ -301,7 +296,7 @@ impl Keyframes for TranslationKeyframes { fn apply_tweened_keyframes<'a>( &self, transform: Option>, - _: EntityMutExcept<'a, (Transform, AnimationPlayer, Handle)>, + _: AnimationEntityMut<'a>, interpolation: Interpolation, step_start: usize, time: f32, @@ -340,7 +335,7 @@ impl Keyframes for ScaleKeyframes { fn apply_single_keyframe<'a>( &self, transform: Option>, - _: EntityMutExcept<'a, (Transform, AnimationPlayer, Handle)>, + _: AnimationEntityMut<'a>, weight: f32, ) -> Result<(), AnimationEvaluationError> { let mut component = transform.ok_or_else(|| { @@ -356,7 +351,7 @@ impl Keyframes for ScaleKeyframes { fn apply_tweened_keyframes<'a>( &self, transform: Option>, - _: EntityMutExcept<'a, (Transform, AnimationPlayer, Handle)>, + _: AnimationEntityMut<'a>, interpolation: Interpolation, step_start: usize, time: f32, @@ -395,7 +390,7 @@ impl Keyframes for RotationKeyframes { fn apply_single_keyframe<'a>( &self, transform: Option>, - _: EntityMutExcept<'a, (Transform, AnimationPlayer, Handle)>, + _: AnimationEntityMut<'a>, weight: f32, ) -> Result<(), AnimationEvaluationError> { let mut component = transform.ok_or_else(|| { @@ -411,7 +406,7 @@ impl Keyframes for RotationKeyframes { fn apply_tweened_keyframes<'a>( &self, transform: Option>, - _: EntityMutExcept<'a, (Transform, AnimationPlayer, Handle)>, + _: AnimationEntityMut<'a>, interpolation: Interpolation, step_start: usize, time: f32, @@ -454,7 +449,7 @@ where fn apply_single_keyframe<'a>( &self, _: Option>, - mut entity: EntityMutExcept<'a, (Transform, AnimationPlayer, Handle)>, + mut entity: AnimationEntityMut<'a>, weight: f32, ) -> Result<(), AnimationEvaluationError> { let mut component = entity.get_mut::().ok_or_else(|| { @@ -472,7 +467,7 @@ where fn apply_tweened_keyframes<'a>( &self, _: Option>, - mut entity: EntityMutExcept<'a, (Transform, AnimationPlayer, Handle)>, + mut entity: AnimationEntityMut<'a>, interpolation: Interpolation, step_start: usize, time: f32, @@ -536,7 +531,7 @@ impl Keyframes for MorphWeightsKeyframes { fn apply_single_keyframe<'a>( &self, _: Option>, - mut entity: EntityMutExcept<'a, (Transform, AnimationPlayer, Handle)>, + mut entity: AnimationEntityMut<'a>, weight: f32, ) -> Result<(), AnimationEvaluationError> { let mut dest = entity.get_mut::().ok_or_else(|| { @@ -555,7 +550,7 @@ impl Keyframes for MorphWeightsKeyframes { fn apply_tweened_keyframes<'a>( &self, _: Option>, - mut entity: EntityMutExcept<'a, (Transform, AnimationPlayer, Handle)>, + mut entity: AnimationEntityMut<'a>, interpolation: Interpolation, step_start: usize, time: f32, diff --git a/crates/bevy_animation/src/lib.rs b/crates/bevy_animation/src/lib.rs index f334ae7811e1a..0b1339d2fb3d9 100755 --- a/crates/bevy_animation/src/lib.rs +++ b/crates/bevy_animation/src/lib.rs @@ -1094,28 +1094,33 @@ pub fn advance_animations( }); } +/// A type alias for [`EntityMutExcept`] as used in animation. +pub type AnimationEntityMut<'w> = EntityMutExcept< + 'w, + ( + AnimationTarget, + Transform, + AnimationPlayer, + Handle, + ), +>; + /// A system that modifies animation targets (e.g. bones in a skinned mesh) /// according to the currently-playing animations. pub fn animate_targets( clips: Res>, graphs: Res>, players: Query<(&AnimationPlayer, &Handle)>, - mut targets: Query<( - Option<&mut Transform>, - EntityMutExcept<(Transform, AnimationPlayer, Handle)>, - )>, + mut targets: Query<(&AnimationTarget, Option<&mut Transform>, AnimationEntityMut)>, ) { // Evaluate all animation targets in parallel. targets .par_iter_mut() - .for_each(|(mut transform, mut entity_mut)| { - let Some(&AnimationTarget { + .for_each(|(target, mut transform, mut entity_mut)| { + let &AnimationTarget { id: target_id, player: player_id, - }) = entity_mut.get::() - else { - return; - }; + } = target; let (animation_player, animation_graph_id) = if let Ok((player, graph_handle)) = players.get(player_id) { From 39d6a745d2c8249b91259cf3bf620435593f42a0 Mon Sep 17 00:00:00 2001 From: Joona Aalto Date: Fri, 27 Sep 2024 22:06:16 +0300 Subject: [PATCH 12/17] Migrate visibility to required components (#15474) # Objective The next step in the migration to required components: Deprecate `VisibilityBundle` and make `Visibility` require `InheritedVisibility` and `ViewVisibility`, as per the [chosen proposal](https://hackmd.io/@bevy/required_components/%2FcO7JPSAQR5G0J_j5wNwtOQ). ## Solution Deprecate `VisibilityBundle` and make `Visibility` require `InheritedVisibility` and `ViewVisibility`. I chose not to deprecate `SpatialBundle` yet, as doing so would mean that we need to manually add `Visibility` to a bunch of places. It will be nicer once meshes, sprites, lights, fog, and cameras have been migrated, since they will require `Transform` and `Visibility` and therefore not need manually added defaults for them. --- ## Migration Guide Replace all insertions of `VisibilityBundle` with the `Visibility` component. The other components required by it will now be inserted automatically. --- crates/bevy_render/src/lib.rs | 1 + crates/bevy_render/src/view/visibility/mod.rs | 70 ++++++++----------- crates/bevy_transform/src/bundles.rs | 4 +- .../src/components/global_transform.rs | 4 +- .../src/components/transform.rs | 6 +- examples/asset/asset_decompression.rs | 2 +- 6 files changed, 41 insertions(+), 46 deletions(-) diff --git a/crates/bevy_render/src/lib.rs b/crates/bevy_render/src/lib.rs index 81ac6eb47c757..9cd0b28d1c1de 100644 --- a/crates/bevy_render/src/lib.rs +++ b/crates/bevy_render/src/lib.rs @@ -43,6 +43,7 @@ pub mod view; /// The render prelude. /// /// This includes the most common types in this crate, re-exported for your convenience. +#[expect(deprecated)] pub mod prelude { #[doc(hidden)] pub use crate::{ diff --git a/crates/bevy_render/src/view/visibility/mod.rs b/crates/bevy_render/src/view/visibility/mod.rs index adef70251bb88..68e784dd09a7c 100644 --- a/crates/bevy_render/src/view/visibility/mod.rs +++ b/crates/bevy_render/src/view/visibility/mod.rs @@ -1,3 +1,5 @@ +#![expect(deprecated)] + mod range; mod render_layers; @@ -32,6 +34,7 @@ use super::NoCpuCulling; /// `Visibility` to set the values of each entity's [`InheritedVisibility`] component. #[derive(Component, Clone, Copy, Reflect, Debug, PartialEq, Eq, Default)] #[reflect(Component, Default, Debug, PartialEq)] +#[require(InheritedVisibility, ViewVisibility)] pub enum Visibility { /// An entity with `Visibility::Inherited` will inherit the Visibility of its [`Parent`]. /// @@ -171,8 +174,13 @@ impl ViewVisibility { /// * To show or hide an entity, you should set its [`Visibility`]. /// * To get the inherited visibility of an entity, you should get its [`InheritedVisibility`]. /// * For visibility hierarchies to work correctly, you must have both all of [`Visibility`], [`InheritedVisibility`], and [`ViewVisibility`]. -/// * You may use the [`VisibilityBundle`] to guarantee this. +/// * ~~You may use the [`VisibilityBundle`] to guarantee this.~~ [`VisibilityBundle`] is now deprecated. +/// [`InheritedVisibility`] and [`ViewVisibility`] are automatically inserted whenever [`Visibility`] is inserted. #[derive(Bundle, Debug, Clone, Default)] +#[deprecated( + since = "0.15.0", + note = "Use the `Visibility` component instead. Inserting it will now also insert `InheritedVisibility` and `ViewVisibility` automatically." +)] pub struct VisibilityBundle { /// The visibility of the entity. pub visibility: Visibility, @@ -538,29 +546,16 @@ mod test { use bevy_app::prelude::*; use bevy_hierarchy::BuildChildren; - fn visibility_bundle(visibility: Visibility) -> VisibilityBundle { - VisibilityBundle { - visibility, - ..Default::default() - } - } - #[test] fn visibility_propagation() { let mut app = App::new(); app.add_systems(Update, visibility_propagate_system); - let root1 = app - .world_mut() - .spawn(visibility_bundle(Visibility::Hidden)) - .id(); - let root1_child1 = app.world_mut().spawn(VisibilityBundle::default()).id(); - let root1_child2 = app - .world_mut() - .spawn(visibility_bundle(Visibility::Hidden)) - .id(); - let root1_child1_grandchild1 = app.world_mut().spawn(VisibilityBundle::default()).id(); - let root1_child2_grandchild1 = app.world_mut().spawn(VisibilityBundle::default()).id(); + let root1 = app.world_mut().spawn(Visibility::Hidden).id(); + let root1_child1 = app.world_mut().spawn(Visibility::default()).id(); + let root1_child2 = app.world_mut().spawn(Visibility::Hidden).id(); + let root1_child1_grandchild1 = app.world_mut().spawn(Visibility::default()).id(); + let root1_child2_grandchild1 = app.world_mut().spawn(Visibility::default()).id(); app.world_mut() .entity_mut(root1) @@ -572,14 +567,11 @@ mod test { .entity_mut(root1_child2) .add_children(&[root1_child2_grandchild1]); - let root2 = app.world_mut().spawn(VisibilityBundle::default()).id(); - let root2_child1 = app.world_mut().spawn(VisibilityBundle::default()).id(); - let root2_child2 = app - .world_mut() - .spawn(visibility_bundle(Visibility::Hidden)) - .id(); - let root2_child1_grandchild1 = app.world_mut().spawn(VisibilityBundle::default()).id(); - let root2_child2_grandchild1 = app.world_mut().spawn(VisibilityBundle::default()).id(); + let root2 = app.world_mut().spawn(Visibility::default()).id(); + let root2_child1 = app.world_mut().spawn(Visibility::default()).id(); + let root2_child2 = app.world_mut().spawn(Visibility::Hidden).id(); + let root2_child1_grandchild1 = app.world_mut().spawn(Visibility::default()).id(); + let root2_child2_grandchild1 = app.world_mut().spawn(Visibility::default()).id(); app.world_mut() .entity_mut(root2) @@ -650,14 +642,14 @@ mod test { let mut app = App::new(); app.add_systems(Update, visibility_propagate_system); - let root1 = app.world_mut().spawn(visibility_bundle(Visible)).id(); - let root1_child1 = app.world_mut().spawn(visibility_bundle(Inherited)).id(); - let root1_child2 = app.world_mut().spawn(visibility_bundle(Hidden)).id(); - let root1_child1_grandchild1 = app.world_mut().spawn(visibility_bundle(Visible)).id(); - let root1_child2_grandchild1 = app.world_mut().spawn(visibility_bundle(Visible)).id(); + let root1 = app.world_mut().spawn(Visible).id(); + let root1_child1 = app.world_mut().spawn(Inherited).id(); + let root1_child2 = app.world_mut().spawn(Hidden).id(); + let root1_child1_grandchild1 = app.world_mut().spawn(Visible).id(); + let root1_child2_grandchild1 = app.world_mut().spawn(Visible).id(); - let root2 = app.world_mut().spawn(visibility_bundle(Inherited)).id(); - let root3 = app.world_mut().spawn(visibility_bundle(Hidden)).id(); + let root2 = app.world_mut().spawn(Inherited).id(); + let root3 = app.world_mut().spawn(Hidden).id(); app.world_mut() .entity_mut(root1) @@ -710,15 +702,15 @@ mod test { // Set up an entity hierarchy. - let id1 = world.spawn(VisibilityBundle::default()).id(); + let id1 = world.spawn(Visibility::default()).id(); - let id2 = world.spawn(VisibilityBundle::default()).id(); + let id2 = world.spawn(Visibility::default()).id(); world.entity_mut(id1).add_children(&[id2]); - let id3 = world.spawn(visibility_bundle(Visibility::Hidden)).id(); + let id3 = world.spawn(Visibility::Hidden).id(); world.entity_mut(id2).add_children(&[id3]); - let id4 = world.spawn(VisibilityBundle::default()).id(); + let id4 = world.spawn(Visibility::default()).id(); world.entity_mut(id3).add_children(&[id4]); // Test the hierarchy. @@ -785,7 +777,7 @@ mod test { schedule.add_systems(visibility_propagate_system); let parent = world.spawn(()).id(); - let child = world.spawn(VisibilityBundle::default()).id(); + let child = world.spawn(Visibility::default()).id(); world.entity_mut(parent).add_children(&[child]); schedule.run(&mut world); diff --git a/crates/bevy_transform/src/bundles.rs b/crates/bevy_transform/src/bundles.rs index 34b05ec6518d9..16a36441a4396 100644 --- a/crates/bevy_transform/src/bundles.rs +++ b/crates/bevy_transform/src/bundles.rs @@ -9,7 +9,9 @@ use crate::prelude::{GlobalTransform, Transform}; /// * To place or move an entity, you should set its [`Transform`]. /// * To get the global transform of an entity, you should get its [`GlobalTransform`]. /// * For transform hierarchies to work correctly, you must have both a [`Transform`] and a [`GlobalTransform`]. -/// * You may use the [`TransformBundle`] to guarantee this. +/// * ~You may use the [`TransformBundle`] to guarantee this.~ +/// [`TransformBundle`] is now deprecated. +/// [`GlobalTransform`] is automatically inserted whenever [`Transform`] is inserted. /// /// ## [`Transform`] and [`GlobalTransform`] /// diff --git a/crates/bevy_transform/src/components/global_transform.rs b/crates/bevy_transform/src/components/global_transform.rs index 06a89f25556a9..17580f94165d1 100644 --- a/crates/bevy_transform/src/components/global_transform.rs +++ b/crates/bevy_transform/src/components/global_transform.rs @@ -17,8 +17,8 @@ use { /// /// * To get the global transform of an entity, you should get its [`GlobalTransform`]. /// * For transform hierarchies to work correctly, you must have both a [`Transform`] and a [`GlobalTransform`]. -/// ~* You may use the [`TransformBundle`](crate::bundles::TransformBundle) to guarantee this.~ -/// * [`TransformBundle`](crate::bundles::TransformBundle) is now deprecated. +/// * ~You may use the [`TransformBundle`](crate::bundles::TransformBundle) to guarantee this.~ +/// [`TransformBundle`](crate::bundles::TransformBundle) is now deprecated. /// [`GlobalTransform`] is automatically inserted whenever [`Transform`] is inserted. /// /// ## [`Transform`] and [`GlobalTransform`] diff --git a/crates/bevy_transform/src/components/transform.rs b/crates/bevy_transform/src/components/transform.rs index 5e676b2752824..9522d3de37d37 100644 --- a/crates/bevy_transform/src/components/transform.rs +++ b/crates/bevy_transform/src/components/transform.rs @@ -13,9 +13,9 @@ use { /// * To place or move an entity, you should set its [`Transform`]. /// * To get the global transform of an entity, you should get its [`GlobalTransform`]. /// * To be displayed, an entity must have both a [`Transform`] and a [`GlobalTransform`]. -/// ~* You may use the [`TransformBundle`](crate::bundles::TransformBundle) to guarantee this.~ -/// * [`TransformBundle`](crate::bundles::TransformBundle) is now deprecated. -/// [`GlobalTransform`] is inserted automatically whenever [`Transform`] is inserted. +/// * ~You may use the [`TransformBundle`](crate::bundles::TransformBundle) to guarantee this.~ +/// [`TransformBundle`](crate::bundles::TransformBundle) is now deprecated. +/// [`GlobalTransform`] is automatically inserted whenever [`Transform`] is inserted. /// /// ## [`Transform`] and [`GlobalTransform`] /// diff --git a/examples/asset/asset_decompression.rs b/examples/asset/asset_decompression.rs index 09150311696cf..65aa97d899a48 100644 --- a/examples/asset/asset_decompression.rs +++ b/examples/asset/asset_decompression.rs @@ -112,7 +112,7 @@ fn setup(mut commands: Commands, asset_server: Res) { }, Sprite::default(), Transform::default(), - VisibilityBundle::default(), + Visibility::default(), )); } From e788e3bc83a6c53f5a6c2490e37f79e989b2e808 Mon Sep 17 00:00:00 2001 From: s-puig <39652109+s-puig@users.noreply.github.com> Date: Fri, 27 Sep 2024 22:07:20 +0200 Subject: [PATCH 13/17] Implement gamepads as entities (#12770) # Objective - Significantly improve the ergonomics of gamepads and allow new features Gamepads are a bit unergonomic to work with, they use resources but unlike other inputs, they are not limited to a single gamepad, to get around this it uses an identifier (Gamepad) to interact with anything causing all sorts of issues. 1. There are too many: Gamepads, GamepadSettings, GamepadInfo, ButtonInput, 2 Axis. 2. ButtonInput/Axis generic methods become really inconvenient to use e.g. any_pressed() 3. GamepadButton/Axis structs are unnecessary boilerplate: ```rust for gamepad in gamepads.iter() { if button_inputs.just_pressed(GamepadButton::new(gamepad, GamepadButtonType::South)) { info!("{:?} just pressed South", gamepad); } else if button_inputs.just_released(GamepadButton::new(gamepad, GamepadButtonType::South)) { info!("{:?} just released South", gamepad); } } ``` 4. Projects often need to create resources to store the selected gamepad and have to manually check if their gamepad is still valid anyways. - Previously attempted by #3419 and #12674 ## Solution - Implement gamepads as entities. Using entities solves all the problems above and opens new possibilities. 1. Reduce boilerplate and allows iteration ```rust let is_pressed = gamepads_buttons.iter().any(|buttons| buttons.pressed(GamepadButtonType::South)) ``` 2. ButtonInput/Axis generic methods become ergonomic again ```rust gamepad_buttons.any_just_pressed([GamepadButtonType::Start, GamepadButtonType::Select]) ``` 3. Reduces the number of public components significantly (Gamepad, GamepadSettings, GamepadButtons, GamepadAxes) 4. Components are highly convenient. Gamepad optional features could now be expressed naturally (`Option or Option`), allows devs to attach their own components and filter them, so code like this becomes possible: ```rust fn move_player( player: Query<&Transform, With>>, gamepads_buttons: Query<&GamepadButtons, With>>, ) { if let Ok(gamepad_buttons) = gamepads_buttons.get_single() { if gamepad_buttons.pressed(GamepadButtonType::South) { // move player } } } ``` --- ## Follow-up - [ ] Run conditions? - [ ] Rumble component # Changelog ## Added TODO ## Changed TODO ## Removed TODO ## Migration Guide TODO --------- Co-authored-by: Carter Anderson --- crates/bevy_gilrs/src/converter.rs | 60 +- crates/bevy_gilrs/src/gilrs_system.rs | 128 +- crates/bevy_gilrs/src/lib.rs | 26 +- crates/bevy_gilrs/src/rumble.rs | 10 +- crates/bevy_input/src/axis.rs | 57 +- crates/bevy_input/src/button_input.rs | 37 +- crates/bevy_input/src/gamepad.rs | 1924 ++++++++++++++++++------ crates/bevy_input/src/lib.rs | 45 +- examples/input/gamepad_input.rs | 33 +- examples/input/gamepad_input_events.rs | 19 +- examples/input/gamepad_rumble.rs | 34 +- examples/tools/gamepad_viewer.rs | 91 +- 12 files changed, 1666 insertions(+), 798 deletions(-) diff --git a/crates/bevy_gilrs/src/converter.rs b/crates/bevy_gilrs/src/converter.rs index e5ce04aa9c302..521d11070c881 100644 --- a/crates/bevy_gilrs/src/converter.rs +++ b/crates/bevy_gilrs/src/converter.rs @@ -1,42 +1,38 @@ -use bevy_input::gamepad::{Gamepad, GamepadAxisType, GamepadButtonType}; +use bevy_input::gamepad::{GamepadAxis, GamepadButton}; -pub fn convert_gamepad_id(gamepad_id: gilrs::GamepadId) -> Gamepad { - Gamepad::new(gamepad_id.into()) -} - -pub fn convert_button(button: gilrs::Button) -> Option { +pub fn convert_button(button: gilrs::Button) -> Option { match button { - gilrs::Button::South => Some(GamepadButtonType::South), - gilrs::Button::East => Some(GamepadButtonType::East), - gilrs::Button::North => Some(GamepadButtonType::North), - gilrs::Button::West => Some(GamepadButtonType::West), - gilrs::Button::C => Some(GamepadButtonType::C), - gilrs::Button::Z => Some(GamepadButtonType::Z), - gilrs::Button::LeftTrigger => Some(GamepadButtonType::LeftTrigger), - gilrs::Button::LeftTrigger2 => Some(GamepadButtonType::LeftTrigger2), - gilrs::Button::RightTrigger => Some(GamepadButtonType::RightTrigger), - gilrs::Button::RightTrigger2 => Some(GamepadButtonType::RightTrigger2), - gilrs::Button::Select => Some(GamepadButtonType::Select), - gilrs::Button::Start => Some(GamepadButtonType::Start), - gilrs::Button::Mode => Some(GamepadButtonType::Mode), - gilrs::Button::LeftThumb => Some(GamepadButtonType::LeftThumb), - gilrs::Button::RightThumb => Some(GamepadButtonType::RightThumb), - gilrs::Button::DPadUp => Some(GamepadButtonType::DPadUp), - gilrs::Button::DPadDown => Some(GamepadButtonType::DPadDown), - gilrs::Button::DPadLeft => Some(GamepadButtonType::DPadLeft), - gilrs::Button::DPadRight => Some(GamepadButtonType::DPadRight), + gilrs::Button::South => Some(GamepadButton::South), + gilrs::Button::East => Some(GamepadButton::East), + gilrs::Button::North => Some(GamepadButton::North), + gilrs::Button::West => Some(GamepadButton::West), + gilrs::Button::C => Some(GamepadButton::C), + gilrs::Button::Z => Some(GamepadButton::Z), + gilrs::Button::LeftTrigger => Some(GamepadButton::LeftTrigger), + gilrs::Button::LeftTrigger2 => Some(GamepadButton::LeftTrigger2), + gilrs::Button::RightTrigger => Some(GamepadButton::RightTrigger), + gilrs::Button::RightTrigger2 => Some(GamepadButton::RightTrigger2), + gilrs::Button::Select => Some(GamepadButton::Select), + gilrs::Button::Start => Some(GamepadButton::Start), + gilrs::Button::Mode => Some(GamepadButton::Mode), + gilrs::Button::LeftThumb => Some(GamepadButton::LeftThumb), + gilrs::Button::RightThumb => Some(GamepadButton::RightThumb), + gilrs::Button::DPadUp => Some(GamepadButton::DPadUp), + gilrs::Button::DPadDown => Some(GamepadButton::DPadDown), + gilrs::Button::DPadLeft => Some(GamepadButton::DPadLeft), + gilrs::Button::DPadRight => Some(GamepadButton::DPadRight), gilrs::Button::Unknown => None, } } -pub fn convert_axis(axis: gilrs::Axis) -> Option { +pub fn convert_axis(axis: gilrs::Axis) -> Option { match axis { - gilrs::Axis::LeftStickX => Some(GamepadAxisType::LeftStickX), - gilrs::Axis::LeftStickY => Some(GamepadAxisType::LeftStickY), - gilrs::Axis::LeftZ => Some(GamepadAxisType::LeftZ), - gilrs::Axis::RightStickX => Some(GamepadAxisType::RightStickX), - gilrs::Axis::RightStickY => Some(GamepadAxisType::RightStickY), - gilrs::Axis::RightZ => Some(GamepadAxisType::RightZ), + gilrs::Axis::LeftStickX => Some(GamepadAxis::LeftStickX), + gilrs::Axis::LeftStickY => Some(GamepadAxis::LeftStickY), + gilrs::Axis::LeftZ => Some(GamepadAxis::LeftZ), + gilrs::Axis::RightStickX => Some(GamepadAxis::RightStickX), + gilrs::Axis::RightStickY => Some(GamepadAxis::RightStickY), + gilrs::Axis::RightZ => Some(GamepadAxis::RightZ), // The `axis_dpad_to_button` gilrs filter should filter out all DPadX and DPadY events. If // it doesn't then we probably need an entry added to the following repo and an update to // GilRs to use the updated database: https://github.com/gabomdq/SDL_GameControllerDB diff --git a/crates/bevy_gilrs/src/gilrs_system.rs b/crates/bevy_gilrs/src/gilrs_system.rs index 6a54249be7508..4ea9d2bf78790 100644 --- a/crates/bevy_gilrs/src/gilrs_system.rs +++ b/crates/bevy_gilrs/src/gilrs_system.rs @@ -1,103 +1,113 @@ use crate::{ - converter::{convert_axis, convert_button, convert_gamepad_id}, - Gilrs, + converter::{convert_axis, convert_button}, + Gilrs, GilrsGamepads, }; +use bevy_ecs::event::EventWriter; +use bevy_ecs::prelude::Commands; #[cfg(target_arch = "wasm32")] use bevy_ecs::system::NonSendMut; -use bevy_ecs::{ - event::EventWriter, - system::{Res, ResMut}, -}; -use bevy_input::{ - gamepad::{ - GamepadAxisChangedEvent, GamepadButtonChangedEvent, GamepadConnection, - GamepadConnectionEvent, GamepadEvent, GamepadInfo, GamepadSettings, - }, - prelude::{GamepadAxis, GamepadButton}, - Axis, +use bevy_ecs::system::ResMut; +use bevy_input::gamepad::{ + GamepadConnection, GamepadConnectionEvent, GamepadInfo, RawGamepadAxisChangedEvent, + RawGamepadButtonChangedEvent, RawGamepadEvent, }; use gilrs::{ev::filter::axis_dpad_to_button, EventType, Filter}; pub fn gilrs_event_startup_system( + mut commands: Commands, #[cfg(target_arch = "wasm32")] mut gilrs: NonSendMut, #[cfg(not(target_arch = "wasm32"))] mut gilrs: ResMut, - mut events: EventWriter, + mut gamepads: ResMut, + mut events: EventWriter, ) { for (id, gamepad) in gilrs.0.get().gamepads() { + // Create entity and add to mapping + let entity = commands.spawn_empty().id(); + gamepads.id_to_entity.insert(id, entity); + gamepads.entity_to_id.insert(entity, id); + let info = GamepadInfo { name: gamepad.name().into(), }; - events.send( - GamepadConnectionEvent { - gamepad: convert_gamepad_id(id), - connection: GamepadConnection::Connected(info), - } - .into(), - ); + events.send(GamepadConnectionEvent { + gamepad: entity, + connection: GamepadConnection::Connected(info), + }); } } pub fn gilrs_event_system( + mut commands: Commands, #[cfg(target_arch = "wasm32")] mut gilrs: NonSendMut, #[cfg(not(target_arch = "wasm32"))] mut gilrs: ResMut, - mut events: EventWriter, - mut gamepad_buttons: ResMut>, - gamepad_axis: Res>, - gamepad_settings: Res, + mut gamepads: ResMut, + mut events: EventWriter, + mut connection_events: EventWriter, + mut button_events: EventWriter, + mut axis_event: EventWriter, ) { let gilrs = gilrs.0.get(); while let Some(gilrs_event) = gilrs.next_event().filter_ev(&axis_dpad_to_button, gilrs) { gilrs.update(&gilrs_event); - - let gamepad = convert_gamepad_id(gilrs_event.id); match gilrs_event.event { EventType::Connected => { let pad = gilrs.gamepad(gilrs_event.id); + let entity = gamepads.get_entity(gilrs_event.id).unwrap_or_else(|| { + let entity = commands.spawn_empty().id(); + gamepads.id_to_entity.insert(gilrs_event.id, entity); + gamepads.entity_to_id.insert(entity, gilrs_event.id); + entity + }); + let info = GamepadInfo { name: pad.name().into(), }; events.send( - GamepadConnectionEvent::new(gamepad, GamepadConnection::Connected(info)).into(), + GamepadConnectionEvent::new(entity, GamepadConnection::Connected(info.clone())) + .into(), ); + connection_events.send(GamepadConnectionEvent::new( + entity, + GamepadConnection::Connected(info), + )); } EventType::Disconnected => { - events.send( - GamepadConnectionEvent::new(gamepad, GamepadConnection::Disconnected).into(), - ); + let gamepad = gamepads + .id_to_entity + .get(&gilrs_event.id) + .copied() + .expect("mapping should exist from connection"); + let event = GamepadConnectionEvent::new(gamepad, GamepadConnection::Disconnected); + events.send(event.clone().into()); + connection_events.send(event); } EventType::ButtonChanged(gilrs_button, raw_value, _) => { - if let Some(button_type) = convert_button(gilrs_button) { - let button = GamepadButton::new(gamepad, button_type); - let old_value = gamepad_buttons.get(button); - let button_settings = gamepad_settings.get_button_axis_settings(button); - - // Only send events that pass the user-defined change threshold - if let Some(filtered_value) = button_settings.filter(raw_value, old_value) { - events.send( - GamepadButtonChangedEvent::new(gamepad, button_type, filtered_value) - .into(), - ); - // Update the current value prematurely so that `old_value` is correct in - // future iterations of the loop. - gamepad_buttons.set(button, filtered_value); - } - } + let Some(button) = convert_button(gilrs_button) else { + continue; + }; + let gamepad = gamepads + .id_to_entity + .get(&gilrs_event.id) + .copied() + .expect("mapping should exist from connection"); + events.send(RawGamepadButtonChangedEvent::new(gamepad, button, raw_value).into()); + button_events.send(RawGamepadButtonChangedEvent::new( + gamepad, button, raw_value, + )); } EventType::AxisChanged(gilrs_axis, raw_value, _) => { - if let Some(axis_type) = convert_axis(gilrs_axis) { - let axis = GamepadAxis::new(gamepad, axis_type); - let old_value = gamepad_axis.get(axis); - let axis_settings = gamepad_settings.get_axis_settings(axis); - - // Only send events that pass the user-defined change threshold - if let Some(filtered_value) = axis_settings.filter(raw_value, old_value) { - events.send( - GamepadAxisChangedEvent::new(gamepad, axis_type, filtered_value).into(), - ); - } - } + let Some(axis) = convert_axis(gilrs_axis) else { + continue; + }; + let gamepad = gamepads + .id_to_entity + .get(&gilrs_event.id) + .copied() + .expect("mapping should exist from connection"); + events.send(RawGamepadAxisChangedEvent::new(gamepad, axis, raw_value).into()); + axis_event.send(RawGamepadAxisChangedEvent::new(gamepad, axis, raw_value)); } _ => (), }; diff --git a/crates/bevy_gilrs/src/lib.rs b/crates/bevy_gilrs/src/lib.rs index 0b03ea23df442..f9e9bc8dfd176 100644 --- a/crates/bevy_gilrs/src/lib.rs +++ b/crates/bevy_gilrs/src/lib.rs @@ -15,9 +15,10 @@ mod gilrs_system; mod rumble; use bevy_app::{App, Plugin, PostUpdate, PreStartup, PreUpdate}; +use bevy_ecs::entity::EntityHashMap; use bevy_ecs::prelude::*; use bevy_input::InputSystem; -use bevy_utils::{synccell::SyncCell, tracing::error}; +use bevy_utils::{synccell::SyncCell, tracing::error, HashMap}; use gilrs::GilrsBuilder; use gilrs_system::{gilrs_event_startup_system, gilrs_event_system}; use rumble::{play_gilrs_rumble, RunningRumbleEffects}; @@ -25,6 +26,27 @@ use rumble::{play_gilrs_rumble, RunningRumbleEffects}; #[cfg_attr(not(target_arch = "wasm32"), derive(Resource))] pub(crate) struct Gilrs(pub SyncCell); +/// A [`resource`](Resource) with the mapping of connected [`gilrs::GamepadId`] and their [`Entity`]. +#[derive(Debug, Default, Resource)] +pub(crate) struct GilrsGamepads { + /// Mapping of [`Entity`] to [`gilrs::GamepadId`]. + pub(crate) entity_to_id: EntityHashMap, + /// Mapping of [`gilrs::GamepadId`] to [`Entity`]. + pub(crate) id_to_entity: HashMap, +} + +impl GilrsGamepads { + /// Returns the [`Entity`] assigned to a connected [`gilrs::GamepadId`]. + pub fn get_entity(&self, gamepad_id: gilrs::GamepadId) -> Option { + self.id_to_entity.get(&gamepad_id).copied() + } + + /// Returns the [`gilrs::GamepadId`] assigned to a gamepad [`Entity`]. + pub fn get_gamepad_id(&self, entity: Entity) -> Option { + self.entity_to_id.get(&entity).copied() + } +} + /// Plugin that provides gamepad handling to an [`App`]. #[derive(Default)] pub struct GilrsPlugin; @@ -45,7 +67,7 @@ impl Plugin for GilrsPlugin { app.insert_non_send_resource(Gilrs(SyncCell::new(gilrs))); #[cfg(not(target_arch = "wasm32"))] app.insert_resource(Gilrs(SyncCell::new(gilrs))); - + app.init_resource::(); app.init_resource::() .add_systems(PreStartup, gilrs_event_startup_system) .add_systems(PreUpdate, gilrs_event_system.before(InputSystem)) diff --git a/crates/bevy_gilrs/src/rumble.rs b/crates/bevy_gilrs/src/rumble.rs index 4d96ca4e307a9..62c6b0dc7d639 100644 --- a/crates/bevy_gilrs/src/rumble.rs +++ b/crates/bevy_gilrs/src/rumble.rs @@ -1,5 +1,5 @@ //! Handle user specified rumble request events. -use crate::Gilrs; +use crate::{Gilrs, GilrsGamepads}; use bevy_ecs::prelude::{EventReader, Res, ResMut, Resource}; #[cfg(target_arch = "wasm32")] use bevy_ecs::system::NonSendMut; @@ -16,8 +16,6 @@ use gilrs::{ }; use thiserror::Error; -use crate::converter::convert_gamepad_id; - /// A rumble effect that is currently in effect. struct RunningRumble { /// Duration from app startup when this effect will be finished @@ -84,6 +82,7 @@ fn get_base_effects( fn handle_rumble_request( running_rumbles: &mut RunningRumbleEffects, gilrs: &mut gilrs::Gilrs, + gamepads: &GilrsGamepads, rumble: GamepadRumbleRequest, current_time: Duration, ) -> Result<(), RumbleError> { @@ -91,7 +90,7 @@ fn handle_rumble_request( let (gamepad_id, _) = gilrs .gamepads() - .find(|(pad_id, _)| convert_gamepad_id(*pad_id) == gamepad) + .find(|(pad_id, _)| *pad_id == gamepads.get_gamepad_id(gamepad).unwrap()) .ok_or(RumbleError::GamepadNotFound)?; match rumble { @@ -129,6 +128,7 @@ pub(crate) fn play_gilrs_rumble( time: Res>, #[cfg(target_arch = "wasm32")] mut gilrs: NonSendMut, #[cfg(not(target_arch = "wasm32"))] mut gilrs: ResMut, + gamepads: Res, mut requests: EventReader, mut running_rumbles: ResMut, ) { @@ -146,7 +146,7 @@ pub(crate) fn play_gilrs_rumble( // Add new effects. for rumble in requests.read().cloned() { let gamepad = rumble.gamepad(); - match handle_rumble_request(&mut running_rumbles, gilrs, rumble, current_time) { + match handle_rumble_request(&mut running_rumbles, gilrs, &gamepads, rumble, current_time) { Ok(()) => {} Err(RumbleError::GilrsError(err)) => { if let ff::Error::FfNotSupported(_) = err { diff --git a/crates/bevy_input/src/axis.rs b/crates/bevy_input/src/axis.rs index 5e84b4bb4a965..df16c0babf76c 100644 --- a/crates/bevy_input/src/axis.rs +++ b/crates/bevy_input/src/axis.rs @@ -57,7 +57,7 @@ where /// Returns the unclamped position data of the provided `input_device`. /// - /// This value may be outside of the [`Axis::MIN`] and [`Axis::MAX`] range. + /// This value may be outside the [`Axis::MIN`] and [`Axis::MAX`] range. /// /// Use for things like camera zoom, where you want devices like mouse wheels to be able to /// exceed the normal range. If being able to move faster on one input device @@ -70,18 +70,11 @@ where pub fn remove(&mut self, input_device: T) -> Option { self.axis_data.remove(&input_device) } - /// Returns an iterator of all the input devices that have position data - pub fn devices(&self) -> impl ExactSizeIterator { - self.axis_data.keys() - } } #[cfg(test)] mod tests { - use crate::{ - gamepad::{Gamepad, GamepadButton, GamepadButtonType}, - Axis, - }; + use crate::{gamepad::GamepadButton, Axis}; #[test] fn test_axis_set() { @@ -100,13 +93,11 @@ mod tests { ]; for (value, expected) in cases { - let gamepad_button = - GamepadButton::new(Gamepad::new(1), GamepadButtonType::RightTrigger); let mut axis = Axis::::default(); - axis.set(gamepad_button, value); + axis.set(GamepadButton::RightTrigger, value); - let actual = axis.get(gamepad_button); + let actual = axis.get(GamepadButton::RightTrigger); assert_eq!(expected, actual); } } @@ -116,48 +107,16 @@ mod tests { let cases = [-1.0, -0.9, -0.1, 0.0, 0.1, 0.9, 1.0]; for value in cases { - let gamepad_button = - GamepadButton::new(Gamepad::new(1), GamepadButtonType::RightTrigger); let mut axis = Axis::::default(); - axis.set(gamepad_button, value); - assert!(axis.get(gamepad_button).is_some()); + axis.set(GamepadButton::RightTrigger, value); + assert!(axis.get(GamepadButton::RightTrigger).is_some()); - axis.remove(gamepad_button); - let actual = axis.get(gamepad_button); + axis.remove(GamepadButton::RightTrigger); + let actual = axis.get(GamepadButton::RightTrigger); let expected = None; assert_eq!(expected, actual); } } - - #[test] - fn test_axis_devices() { - let mut axis = Axis::::default(); - assert_eq!(axis.devices().count(), 0); - - axis.set( - GamepadButton::new(Gamepad::new(1), GamepadButtonType::RightTrigger), - 0.1, - ); - assert_eq!(axis.devices().count(), 1); - - axis.set( - GamepadButton::new(Gamepad::new(1), GamepadButtonType::LeftTrigger), - 0.5, - ); - assert_eq!(axis.devices().count(), 2); - - axis.set( - GamepadButton::new(Gamepad::new(1), GamepadButtonType::RightTrigger), - -0.1, - ); - assert_eq!(axis.devices().count(), 2); - - axis.remove(GamepadButton::new( - Gamepad::new(1), - GamepadButtonType::RightTrigger, - )); - assert_eq!(axis.devices().count(), 1); - } } diff --git a/crates/bevy_input/src/button_input.rs b/crates/bevy_input/src/button_input.rs index 559c7eda90cd8..31c27f7330074 100644 --- a/crates/bevy_input/src/button_input.rs +++ b/crates/bevy_input/src/button_input.rs @@ -73,17 +73,13 @@ use { /// ```no_run /// # use bevy_app::{App, NoopPluginGroup as DefaultPlugins, Update}; /// # use bevy_ecs::{prelude::{IntoSystemConfigs, Res, Resource, resource_changed}, schedule::Condition}; -/// # use bevy_input::{ButtonInput, prelude::{GamepadButton, KeyCode, MouseButton}}; +/// # use bevy_input::{ButtonInput, prelude::{KeyCode, MouseButton}}; /// /// fn main() { /// App::new() /// .add_plugins(DefaultPlugins) /// .add_systems( /// Update, -/// print_gamepad.run_if(resource_changed::>), -/// ) -/// .add_systems( -/// Update, /// print_mouse.run_if(resource_changed::>), /// ) /// .add_systems( @@ -93,10 +89,6 @@ use { /// .run(); /// } /// -/// fn print_gamepad(gamepad: Res>) { -/// println!("Gamepad: {:?}", gamepad.get_pressed().collect::>()); -/// } -/// /// fn print_mouse(mouse: Res>) { /// println!("Mouse: {:?}", mouse.get_pressed().collect::>()); /// } @@ -115,33 +107,6 @@ use { /// } /// ``` /// -/// Accepting input from multiple devices: -/// ```no_run -/// # use bevy_app::{App, NoopPluginGroup as DefaultPlugins, Update}; -/// # use bevy_ecs::{prelude::IntoSystemConfigs, schedule::Condition}; -/// # use bevy_input::{ButtonInput, common_conditions::{input_just_pressed}, prelude::{GamepadButton, Gamepad, GamepadButtonType, KeyCode}}; -/// -/// fn main() { -/// App::new() -/// .add_plugins(DefaultPlugins) -/// .add_systems( -/// Update, -/// something_used.run_if( -/// input_just_pressed(KeyCode::KeyE) -/// .or(input_just_pressed(GamepadButton::new( -/// Gamepad::new(0), -/// GamepadButtonType::West, -/// ))), -/// ), -/// ) -/// .run(); -/// } -/// -/// fn something_used() { -/// println!("Generic use-ish button pressed."); -/// } -/// ``` -/// /// ## Note /// /// When adding this resource for a new input type, you should: diff --git a/crates/bevy_input/src/gamepad.rs b/crates/bevy_input/src/gamepad.rs index 63007631cdf13..2fee5a4db544c 100644 --- a/crates/bevy_input/src/gamepad.rs +++ b/crates/bevy_input/src/gamepad.rs @@ -3,16 +3,282 @@ use crate::{Axis, ButtonInput, ButtonState}; use bevy_ecs::{ change_detection::DetectChangesMut, + component::Component, + entity::Entity, event::{Event, EventReader, EventWriter}, - system::{Res, ResMut, Resource}, + system::{Commands, Query}, }; -use bevy_utils::{tracing::info, Duration, HashMap}; -use thiserror::Error; +use bevy_math::Vec2; #[cfg(feature = "bevy_reflect")] -use { - bevy_ecs::reflect::ReflectResource, - bevy_reflect::{std_traits::ReflectDefault, Reflect}, +use bevy_reflect::{std_traits::ReflectDefault, Reflect}; +#[cfg(all(feature = "serialize", feature = "bevy_reflect"))] +use bevy_reflect::{ReflectDeserialize, ReflectSerialize}; +use bevy_utils::{ + tracing::{info, warn}, + Duration, HashMap, }; +use thiserror::Error; + +/// A gamepad event. +/// +/// This event type is used over the [`GamepadConnectionEvent`], +/// [`GamepadButtonChangedEvent`] and [`GamepadAxisChangedEvent`] when +/// the in-frame relative ordering of events is important. +/// +/// This event is produced by `bevy_input` +#[derive(Event, Debug, Clone, PartialEq)] +#[cfg_attr(feature = "bevy_reflect", derive(Reflect), reflect(Debug, PartialEq))] +#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr( + all(feature = "serialize", feature = "bevy_reflect"), + reflect(Serialize, Deserialize) +)] +pub enum GamepadEvent { + /// A gamepad has been connected or disconnected. + Connection(GamepadConnectionEvent), + /// A button of the gamepad has been triggered. + Button(GamepadButtonChangedEvent), + /// An axis of the gamepad has been triggered. + Axis(GamepadAxisChangedEvent), +} + +impl From for GamepadEvent { + fn from(value: GamepadConnectionEvent) -> Self { + Self::Connection(value) + } +} + +impl From for GamepadEvent { + fn from(value: GamepadButtonChangedEvent) -> Self { + Self::Button(value) + } +} + +impl From for GamepadEvent { + fn from(value: GamepadAxisChangedEvent) -> Self { + Self::Axis(value) + } +} + +/// A raw gamepad event. +/// +/// This event type is used over the [`GamepadConnectionEvent`], +/// [`RawGamepadButtonChangedEvent`] and [`RawGamepadAxisChangedEvent`] when +/// the in-frame relative ordering of events is important. +/// +/// This event type is used by `bevy_input` to feed its components. +#[derive(Event, Debug, Clone, PartialEq, Reflect)] +#[reflect(Debug, PartialEq)] +#[cfg_attr( + feature = "serialize", + derive(serde::Serialize, serde::Deserialize), + reflect(Serialize, Deserialize) +)] +pub enum RawGamepadEvent { + /// A gamepad has been connected or disconnected. + Connection(GamepadConnectionEvent), + /// A button of the gamepad has been triggered. + Button(RawGamepadButtonChangedEvent), + /// An axis of the gamepad has been triggered. + Axis(RawGamepadAxisChangedEvent), +} + +impl From for RawGamepadEvent { + fn from(value: GamepadConnectionEvent) -> Self { + Self::Connection(value) + } +} + +impl From for RawGamepadEvent { + fn from(value: RawGamepadButtonChangedEvent) -> Self { + Self::Button(value) + } +} + +impl From for RawGamepadEvent { + fn from(value: RawGamepadAxisChangedEvent) -> Self { + Self::Axis(value) + } +} + +/// [`GamepadButton`] changed event unfiltered by [`GamepadSettings`] +#[derive(Event, Debug, Copy, Clone, PartialEq, Reflect)] +#[reflect(Debug, PartialEq)] +#[cfg_attr( + feature = "serialize", + derive(serde::Serialize, serde::Deserialize), + reflect(Serialize, Deserialize) +)] +pub struct RawGamepadButtonChangedEvent { + /// The gamepad on which the button is triggered. + pub gamepad: Entity, + /// The type of the triggered button. + pub button: GamepadButton, + /// The value of the button. + pub value: f32, +} + +impl RawGamepadButtonChangedEvent { + /// Creates a [`RawGamepadButtonChangedEvent`]. + pub fn new(gamepad: Entity, button_type: GamepadButton, value: f32) -> Self { + Self { + gamepad, + button: button_type, + value, + } + } +} + +/// [`GamepadAxis`] changed event unfiltered by [`GamepadSettings`] +#[derive(Event, Debug, Copy, Clone, PartialEq, Reflect)] +#[reflect(Debug, PartialEq)] +#[cfg_attr( + feature = "serialize", + derive(serde::Serialize, serde::Deserialize), + reflect(Serialize, Deserialize) +)] +pub struct RawGamepadAxisChangedEvent { + /// The gamepad on which the axis is triggered. + pub gamepad: Entity, + /// The type of the triggered axis. + pub axis: GamepadAxis, + /// The value of the axis. + pub value: f32, +} + +impl RawGamepadAxisChangedEvent { + /// Creates a [`RawGamepadAxisChangedEvent`]. + pub fn new(gamepad: Entity, axis_type: GamepadAxis, value: f32) -> Self { + Self { + gamepad, + axis: axis_type, + value, + } + } +} + +/// A Gamepad connection event. Created when a connection to a gamepad +/// is established and when a gamepad is disconnected. +#[derive(Event, Debug, Clone, PartialEq, Reflect)] +#[reflect(Debug, PartialEq)] +#[cfg_attr( + feature = "serialize", + derive(serde::Serialize, serde::Deserialize), + reflect(Serialize, Deserialize) +)] +pub struct GamepadConnectionEvent { + /// The gamepad whose connection status changed. + pub gamepad: Entity, + /// The change in the gamepads connection. + pub connection: GamepadConnection, +} + +impl GamepadConnectionEvent { + /// Creates a [`GamepadConnectionEvent`]. + pub fn new(gamepad: Entity, connection: GamepadConnection) -> Self { + Self { + gamepad, + connection, + } + } + + /// Is the gamepad connected? + pub fn connected(&self) -> bool { + matches!(self.connection, GamepadConnection::Connected(_)) + } + + /// Is the gamepad disconnected? + pub fn disconnected(&self) -> bool { + !self.connected() + } +} + +/// [`GamepadButton`] event triggered by a digital state change +#[derive(Event, Debug, Clone, Copy, PartialEq, Eq, Reflect)] +#[reflect(Debug, PartialEq)] +#[cfg_attr( + feature = "serialize", + derive(serde::Serialize, serde::Deserialize), + reflect(Serialize, Deserialize) +)] +pub struct GamepadButtonStateChangedEvent { + /// The entity that represents this gamepad. + pub entity: Entity, + /// The gamepad button assigned to the event. + pub button: GamepadButton, + /// The pressed state of the button. + pub state: ButtonState, +} + +impl GamepadButtonStateChangedEvent { + /// Creates a new [`GamepadButtonStateChangedEvent`] + pub fn new(entity: Entity, button: GamepadButton, state: ButtonState) -> Self { + Self { + entity, + button, + state, + } + } +} + +/// [`GamepadButton`] event triggered by an analog state change +#[derive(Event, Debug, Clone, Copy, PartialEq, Reflect)] +#[reflect(Debug, PartialEq)] +#[cfg_attr( + feature = "serialize", + derive(serde::Serialize, serde::Deserialize), + reflect(Serialize, Deserialize) +)] +pub struct GamepadButtonChangedEvent { + /// The entity that represents this gamepad. + pub entity: Entity, + /// The gamepad button assigned to the event. + pub button: GamepadButton, + /// The pressed state of the button. + pub state: ButtonState, + /// The analog value of the button. + pub value: f32, +} + +impl GamepadButtonChangedEvent { + /// Creates a new [`GamepadButtonChangedEvent`] + pub fn new(entity: Entity, button: GamepadButton, state: ButtonState, value: f32) -> Self { + Self { + entity, + button, + state, + value, + } + } +} + +/// [`GamepadAxis`] event triggered by an analog state change +#[derive(Event, Debug, Clone, Copy, PartialEq, Reflect)] +#[reflect(Debug, PartialEq)] +#[cfg_attr( + feature = "serialize", + derive(serde::Serialize, serde::Deserialize), + reflect(Serialize, Deserialize) +)] +pub struct GamepadAxisChangedEvent { + /// The entity that represents this gamepad. + pub entity: Entity, + /// The gamepad axis assigned to the event. + pub axis: GamepadAxis, + /// The value of this axis. + pub value: f32, +} + +impl GamepadAxisChangedEvent { + /// Creates a new [`GamepadAxisChangedEvent`] + pub fn new(entity: Entity, axis: GamepadAxis, value: f32) -> Self { + Self { + entity, + axis, + value, + } + } +} /// Errors that occur when setting axis settings for gamepad input. #[derive(Error, Debug, PartialEq)] @@ -69,111 +335,201 @@ pub enum ButtonSettingsError { }, } -#[cfg(all(feature = "serialize", feature = "bevy_reflect"))] -use bevy_reflect::{ReflectDeserialize, ReflectSerialize}; - -/// A gamepad with an associated `ID`. +/// The [`Gamepad`] [`component`](Component) stores a connected gamepad's metadata such as the `name` and its [`GamepadButton`] and [`GamepadAxis`]. /// -/// ## Usage +/// The [`entity`](Entity) representing a gamepad and its [`minimal components`](GamepadSettings) are automatically managed. /// -/// The primary way to access the individual connected gamepads is done through the [`Gamepads`] -/// `bevy` resource. It is also used inside of [`GamepadConnectionEvent`]s to correspond a gamepad -/// with a connection event. +/// # Usage /// -/// ## Note +/// The only way to obtain a [`Gamepad`] is by [`query`](Query). /// -/// The `ID` of a gamepad is fixed until the gamepad disconnects or the app is restarted. -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -#[cfg_attr( - feature = "bevy_reflect", - derive(Reflect), - reflect(Debug, Hash, PartialEq) -)] -#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr( - all(feature = "serialize", feature = "bevy_reflect"), - reflect(Serialize, Deserialize) -)] +/// # Examples +/// +/// ``` +/// # use bevy_input::gamepad::{Gamepad, GamepadAxis, GamepadButton}; +/// # use bevy_ecs::system::Query; +/// # +/// fn gamepad_usage_system(gamepads: Query<&Gamepad>) { +/// for gamepad in gamepads.iter() { +/// println!("{}", gamepad.name()); +/// +/// if gamepad.just_pressed(GamepadButton::North) { +/// println!("{} just pressed North", gamepad.name()) +/// } +/// +/// if let Some(left_stick_x) = gamepad.get(GamepadAxis::LeftStickX) { +/// println!("left stick X: {}", left_stick_x) +/// } +/// } +/// } +/// ``` +#[derive(Component, Debug)] +#[require(GamepadSettings)] pub struct Gamepad { - /// The `ID` of the gamepad. - pub id: usize, + info: GamepadInfo, + /// [`ButtonInput`] of [`GamepadButton`] representing their digital state + pub(crate) digital: ButtonInput, + /// [`Axis`] of [`GamepadButton`] representing their analog state. + pub(crate) analog: Axis, } impl Gamepad { - /// Creates a new [`Gamepad`]. - pub fn new(id: usize) -> Self { - Self { id } + /// Creates a gamepad with the given metadata + fn new(info: GamepadInfo) -> Self { + let mut analog = Axis::default(); + for button in GamepadButton::all().iter().copied() { + analog.set(button.into(), 0.0); + } + for axis_type in GamepadAxis::all().iter().copied() { + analog.set(axis_type.into(), 0.0); + } + Self { + info, + analog, + digital: ButtonInput::default(), + } } -} -/// Metadata associated with a [`Gamepad`]. -#[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "bevy_reflect", derive(Reflect), reflect(Debug, PartialEq))] -#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr( - all(feature = "serialize", feature = "bevy_reflect"), - reflect(Serialize, Deserialize) -)] -pub struct GamepadInfo { /// The name of the gamepad. /// /// This name is generally defined by the OS. /// /// For example on Windows the name may be "HID-compliant game controller". - pub name: String, -} + pub fn name(&self) -> &str { + self.info.name.as_str() + } -/// A collection of connected [`Gamepad`]s. -/// -/// ## Usage -/// -/// It is stored in a `bevy` resource which tracks all of the currently connected [`Gamepad`]s. -/// -/// ## Updating -/// -/// The [`Gamepad`]s are registered and deregistered in the [`gamepad_connection_system`] -/// whenever a [`GamepadConnectionEvent`] is received. -#[derive(Resource, Default, Debug)] -pub struct Gamepads { - /// The collection of the connected [`Gamepad`]s. - gamepads: HashMap, -} + /// Returns the analog data of the provided [`GamepadAxis`] or [`GamepadButton`]. + /// + /// This will be clamped between [[`Axis::MIN`],[`Axis::MAX`]]. + pub fn get(&self, input: impl Into) -> Option { + self.analog.get(input.into()) + } + + /// Returns the unclamped analog data of the provided [`GamepadAxis`] or [`GamepadButton`]. + /// + /// This value may be outside the [`Axis::MIN`] and [`Axis::MAX`] range. + pub fn get_unclamped(&self, input: impl Into) -> Option { + self.analog.get_unclamped(input.into()) + } + + /// Returns the left stick as a [`Vec2`] + pub fn left_stick(&self) -> Vec2 { + Vec2 { + x: self.get(GamepadAxis::LeftStickX).unwrap_or(0.0), + y: self.get(GamepadAxis::LeftStickY).unwrap_or(0.0), + } + } -impl Gamepads { - /// Returns `true` if the `gamepad` is connected. - pub fn contains(&self, gamepad: Gamepad) -> bool { - self.gamepads.contains_key(&gamepad) + /// Returns the right stick as a [`Vec2`] + pub fn right_stick(&self) -> Vec2 { + Vec2 { + x: self.get(GamepadAxis::RightStickX).unwrap_or(0.0), + y: self.get(GamepadAxis::RightStickY).unwrap_or(0.0), + } } - /// Returns an iterator over registered [`Gamepad`]s in an arbitrary order. - pub fn iter(&self) -> impl Iterator + '_ { - self.gamepads.keys().copied() + /// Returns the directional pad as a [`Vec2`] + pub fn dpad(&self) -> Vec2 { + Vec2 { + x: self.get(GamepadButton::DPadRight).unwrap_or(0.0) + - self.get(GamepadButton::DPadLeft).unwrap_or(0.0), + y: self.get(GamepadButton::DPadUp).unwrap_or(0.0) + - self.get(GamepadButton::DPadDown).unwrap_or(0.0), + } } - /// The name of the gamepad if this one is connected. - pub fn name(&self, gamepad: Gamepad) -> Option<&str> { - self.gamepads.get(&gamepad).map(|g| g.name.as_str()) + /// Returns `true` if the [`GamepadButton`] has been pressed. + pub fn pressed(&self, button_type: GamepadButton) -> bool { + self.digital.pressed(button_type) } - /// Registers the `gamepad`, marking it as connected. - fn register(&mut self, gamepad: Gamepad, info: GamepadInfo) { - self.gamepads.insert(gamepad, info); + /// Returns `true` if any item in [`GamepadButton`] has been pressed. + pub fn any_pressed(&self, button_inputs: impl IntoIterator) -> bool { + button_inputs + .into_iter() + .any(|button_type| self.pressed(button_type)) + } + + /// Returns `true` if all items in [`GamepadButton`] have been pressed. + pub fn all_pressed(&self, button_inputs: impl IntoIterator) -> bool { + button_inputs + .into_iter() + .all(|button_type| self.pressed(button_type)) + } + + /// Returns `true` if the [`GamepadButton`] has been pressed during the current frame. + /// + /// Note: This function does not imply information regarding the current state of [`ButtonInput::pressed`] or [`ButtonInput::just_released`]. + pub fn just_pressed(&self, button_type: GamepadButton) -> bool { + self.digital.just_pressed(button_type) } - /// Deregisters the `gamepad`, marking it as disconnected. - fn deregister(&mut self, gamepad: Gamepad) { - self.gamepads.remove(&gamepad); + /// Returns `true` if any item in [`GamepadButton`] has been pressed during the current frame. + pub fn any_just_pressed(&self, button_inputs: impl IntoIterator) -> bool { + button_inputs + .into_iter() + .any(|button_type| self.just_pressed(button_type)) + } + + /// Returns `true` if all items in [`GamepadButton`] have been just pressed. + pub fn all_just_pressed(&self, button_inputs: impl IntoIterator) -> bool { + button_inputs + .into_iter() + .all(|button_type| self.just_pressed(button_type)) + } + + /// Returns `true` if the [`GamepadButton`] has been released during the current frame. + /// + /// Note: This function does not imply information regarding the current state of [`ButtonInput::pressed`] or [`ButtonInput::just_pressed`]. + pub fn just_released(&self, button_type: GamepadButton) -> bool { + self.digital.just_released(button_type) + } + + /// Returns `true` if any item in [`GamepadButton`] has just been released. + pub fn any_just_released( + &self, + button_inputs: impl IntoIterator, + ) -> bool { + button_inputs + .into_iter() + .any(|button_type| self.just_released(button_type)) + } + + /// Returns `true` if all items in [`GamepadButton`] have just been released. + pub fn all_just_released( + &self, + button_inputs: impl IntoIterator, + ) -> bool { + button_inputs + .into_iter() + .all(|button_type| self.just_released(button_type)) } } -/// A type of a [`GamepadButton`]. +/// Metadata associated with a [`Gamepad`]. +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "bevy_reflect", derive(Reflect), reflect(Debug, PartialEq))] +#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr( + all(feature = "serialize", feature = "bevy_reflect"), + reflect(Serialize, Deserialize) +)] +pub struct GamepadInfo { + /// The name of the gamepad. + /// + /// This name is generally defined by the OS. + /// + /// For example on Windows the name may be "HID-compliant game controller". + pub name: String, +} + +/// Represents gamepad input types that are mapped in the range [0.0, 1.0]. /// /// ## Usage /// -/// This is used to determine which button has changed its value when receiving a -/// [`GamepadButtonChangedEvent`]. It is also used in the [`GamepadButton`] -/// which in turn is used to create the [`ButtonInput`] or -/// [`Axis`] `bevy` resources. +/// This is used to determine which button has changed its value when receiving gamepad button events +/// It is also used in the [`Gamepad`] component. #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] #[cfg_attr( feature = "bevy_reflect", @@ -185,7 +541,7 @@ impl Gamepads { all(feature = "serialize", feature = "bevy_reflect"), reflect(Serialize, Deserialize) )] -pub enum GamepadButtonType { +pub enum GamepadButton { /// The bottom action button of the action pad (i.e. PS: Cross, Xbox: A). South, /// The right action button of the action pad (i.e. PS: Circle, Xbox: B). @@ -233,77 +589,39 @@ pub enum GamepadButtonType { Other(u8), } -/// A button of a [`Gamepad`]. -/// -/// ## Usage -/// -/// It is used as the generic `T` value of an [`ButtonInput`] and [`Axis`] to create `bevy` resources. These -/// resources store the data of the buttons of a gamepad and can be accessed inside of a system. -/// -/// ## Updating -/// -/// The gamepad button resources are updated inside of the [`gamepad_button_event_system`]. -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -#[cfg_attr( - feature = "bevy_reflect", - derive(Reflect), - reflect(Debug, Hash, PartialEq) -)] -#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr( - all(feature = "serialize", feature = "bevy_reflect"), - reflect(Serialize, Deserialize) -)] -pub struct GamepadButton { - /// The gamepad on which the button is located on. - pub gamepad: Gamepad, - /// The type of the button. - pub button_type: GamepadButtonType, -} - impl GamepadButton { - /// Creates a new [`GamepadButton`]. - /// - /// # Examples - /// - /// ``` - /// # use bevy_input::gamepad::{GamepadButton, GamepadButtonType, Gamepad}; - /// # - /// let gamepad_button = GamepadButton::new( - /// Gamepad::new(1), - /// GamepadButtonType::South, - /// ); - /// ``` - pub fn new(gamepad: Gamepad, button_type: GamepadButtonType) -> Self { - Self { - gamepad, - button_type, - } + /// Returns an array of all the standard [`GamepadButton`] + pub const fn all() -> [GamepadButton; 19] { + [ + GamepadButton::South, + GamepadButton::East, + GamepadButton::North, + GamepadButton::West, + GamepadButton::C, + GamepadButton::Z, + GamepadButton::LeftTrigger, + GamepadButton::LeftTrigger2, + GamepadButton::RightTrigger, + GamepadButton::RightTrigger2, + GamepadButton::Select, + GamepadButton::Start, + GamepadButton::Mode, + GamepadButton::LeftThumb, + GamepadButton::RightThumb, + GamepadButton::DPadUp, + GamepadButton::DPadDown, + GamepadButton::DPadLeft, + GamepadButton::DPadRight, + ] } } -/// A gamepad button input event. -#[derive(Event, Debug, Clone, Copy, PartialEq, Eq)] -#[cfg_attr(feature = "bevy_reflect", derive(Reflect), reflect(Debug, PartialEq))] -#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr( - all(feature = "serialize", feature = "bevy_reflect"), - reflect(Serialize, Deserialize) -)] -pub struct GamepadButtonInput { - /// The gamepad button assigned to the event. - pub button: GamepadButton, - /// The pressed state of the button. - pub state: ButtonState, -} - -/// A type of a [`GamepadAxis`]. +/// Represents gamepad input types that are mapped in the range [-1.0, 1.0] /// /// ## Usage /// /// This is used to determine which axis has changed its value when receiving a -/// [`GamepadAxisChangedEvent`]. It is also used in the [`GamepadAxis`] -/// which in turn is used to create the [`Axis`] `bevy` resource. +/// gamepad axis event. It is also used in the [`Gamepad`] component. #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "bevy_reflect", derive(Reflect), reflect(Debug, PartialEq))] #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))] @@ -311,7 +629,7 @@ pub struct GamepadButtonInput { all(feature = "serialize", feature = "bevy_reflect"), reflect(Serialize, Deserialize) )] -pub enum GamepadAxisType { +pub enum GamepadAxis { /// The horizontal value of the left stick. LeftStickX, /// The vertical value of the left stick. @@ -330,68 +648,57 @@ pub enum GamepadAxisType { Other(u8), } -/// An axis of a [`Gamepad`]. -/// -/// ## Usage -/// -/// It is used as the generic `T` value of an [`Axis`] to create `bevy` resources. These -/// resources store the data of the axes of a gamepad and can be accessed inside of a system. -/// -/// ## Updating -/// -/// The gamepad axes resources are updated inside of the [`gamepad_axis_event_system`]. -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "bevy_reflect", derive(Reflect), reflect(Debug, PartialEq))] -#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr( - all(feature = "serialize", feature = "bevy_reflect"), - reflect(Serialize, Deserialize) -)] -pub struct GamepadAxis { - /// The gamepad on which the axis is located on. - pub gamepad: Gamepad, - /// The type of the axis. - pub axis_type: GamepadAxisType, +impl GamepadAxis { + /// Returns an array of all the standard [`GamepadAxis`]. + pub const fn all() -> [GamepadAxis; 6] { + [ + GamepadAxis::LeftStickX, + GamepadAxis::LeftStickY, + GamepadAxis::LeftZ, + GamepadAxis::RightStickX, + GamepadAxis::RightStickY, + GamepadAxis::RightZ, + ] + } } -impl GamepadAxis { - /// Creates a new [`GamepadAxis`]. - /// - /// # Examples - /// - /// ``` - /// # use bevy_input::gamepad::{GamepadAxis, GamepadAxisType, Gamepad}; - /// # - /// let gamepad_axis = GamepadAxis::new( - /// Gamepad::new(1), - /// GamepadAxisType::LeftStickX, - /// ); - /// ``` - pub fn new(gamepad: Gamepad, axis_type: GamepadAxisType) -> Self { - Self { gamepad, axis_type } +/// Encapsulation over [`GamepadAxis`] and [`GamepadButton`] +// This is done so Gamepad can share a single Axis and simplifies the API by having only one get/get_unclamped method +#[derive(Debug, Copy, Clone, Eq, Hash, PartialEq)] +pub enum GamepadInput { + /// A [`GamepadAxis`] + Axis(GamepadAxis), + /// A [`GamepadButton`] + Button(GamepadButton), +} + +impl From for GamepadInput { + fn from(value: GamepadAxis) -> Self { + GamepadInput::Axis(value) } } -/// Settings for all [`Gamepad`]s. +impl From for GamepadInput { + fn from(value: GamepadButton) -> Self { + GamepadInput::Button(value) + } +} + +/// Gamepad settings component. /// /// ## Usage /// -/// It is used to create a `bevy` resource that stores the settings of every [`GamepadButton`] and -/// [`GamepadAxis`]. If no user defined [`ButtonSettings`], [`AxisSettings`], or [`ButtonAxisSettings`] +/// It is used to create a `bevy` component that stores the settings of [`GamepadButton`] and [`GamepadAxis`] in [`Gamepad`]. +/// If no user defined [`ButtonSettings`], [`AxisSettings`], or [`ButtonAxisSettings`] /// are defined, the default settings of each are used as a fallback accordingly. /// /// ## Note /// -/// The [`GamepadSettings`] are used inside of `bevy_gilrs` to determine when raw gamepad events from `gilrs`, -/// should register as a [`GamepadEvent`]. Events that don't meet the change thresholds defined in [`GamepadSettings`] -/// will not register. To modify these settings, mutate the corresponding resource. -#[derive(Resource, Default, Debug)] -#[cfg_attr( - feature = "bevy_reflect", - derive(Reflect), - reflect(Debug, Default, Resource) -)] - +/// The [`GamepadSettings`] are used to determine when raw gamepad events +/// should register. Events that don't meet the change thresholds defined in [`GamepadSettings`] +/// will not register. To modify these settings, mutate the corresponding component. +#[derive(Component, Clone, Default, Debug)] +#[cfg_attr(feature = "bevy_reflect", derive(Reflect), reflect(Debug, Default))] pub struct GamepadSettings { /// The default button settings. pub default_button_settings: ButtonSettings, @@ -408,18 +715,17 @@ pub struct GamepadSettings { } impl GamepadSettings { - /// Returns the [`ButtonSettings`] of the `button`. + /// Returns the [`ButtonSettings`] of the [`GamepadButton`]. /// /// If no user defined [`ButtonSettings`] are specified the default [`ButtonSettings`] get returned. /// /// # Examples /// /// ``` - /// # use bevy_input::gamepad::{GamepadSettings, GamepadButton, Gamepad, GamepadButtonType}; + /// # use bevy_input::gamepad::{GamepadSettings, GamepadButton}; /// # /// # let settings = GamepadSettings::default(); - /// let button = GamepadButton::new(Gamepad::new(1), GamepadButtonType::South); - /// let button_settings = settings.get_button_settings(button); + /// let button_settings = settings.get_button_settings(GamepadButton::South); /// ``` pub fn get_button_settings(&self, button: GamepadButton) -> &ButtonSettings { self.button_settings @@ -427,18 +733,17 @@ impl GamepadSettings { .unwrap_or(&self.default_button_settings) } - /// Returns the [`AxisSettings`] of the `axis`. + /// Returns the [`AxisSettings`] of the [`GamepadAxis`]. /// /// If no user defined [`AxisSettings`] are specified the default [`AxisSettings`] get returned. /// /// # Examples /// /// ``` - /// # use bevy_input::gamepad::{GamepadSettings, GamepadAxis, Gamepad, GamepadAxisType}; + /// # use bevy_input::gamepad::{GamepadSettings, GamepadAxis}; /// # /// # let settings = GamepadSettings::default(); - /// let axis = GamepadAxis::new(Gamepad::new(1), GamepadAxisType::LeftStickX); - /// let axis_settings = settings.get_axis_settings(axis); + /// let axis_settings = settings.get_axis_settings(GamepadAxis::LeftStickX); /// ``` pub fn get_axis_settings(&self, axis: GamepadAxis) -> &AxisSettings { self.axis_settings @@ -446,18 +751,17 @@ impl GamepadSettings { .unwrap_or(&self.default_axis_settings) } - /// Returns the [`ButtonAxisSettings`] of the `button`. + /// Returns the [`ButtonAxisSettings`] of the [`GamepadButton`]. /// /// If no user defined [`ButtonAxisSettings`] are specified the default [`ButtonAxisSettings`] get returned. /// /// # Examples /// /// ``` - /// # use bevy_input::gamepad::{GamepadSettings, GamepadButton, Gamepad, GamepadButtonType}; + /// # use bevy_input::gamepad::{GamepadSettings, GamepadButton}; /// # /// # let settings = GamepadSettings::default(); - /// let button = GamepadButton::new(Gamepad::new(1), GamepadButtonType::South); - /// let button_axis_settings = settings.get_button_axis_settings(button); + /// let button_axis_settings = settings.get_button_axis_settings(GamepadButton::South); /// ``` pub fn get_button_axis_settings(&self, button: GamepadButton) -> &ButtonAxisSettings { self.button_axis_settings @@ -468,12 +772,12 @@ impl GamepadSettings { /// Manages settings for gamepad buttons. /// -/// It is used inside of [`GamepadSettings`] to define the threshold for a gamepad button +/// It is used inside [`GamepadSettings`] to define the threshold for a [`GamepadButton`] /// to be considered pressed or released. A button is considered pressed if the `press_threshold` /// value is surpassed and released if the `release_threshold` value is undercut. /// /// Allowed values: `0.0 <= ``release_threshold`` <= ``press_threshold`` <= 1.0` -#[derive(Debug, Clone)] +#[derive(Debug, PartialEq, Clone)] #[cfg_attr(feature = "bevy_reflect", derive(Reflect), reflect(Debug, Default))] pub struct ButtonSettings { press_threshold: f32, @@ -624,7 +928,7 @@ impl ButtonSettings { /// Settings for a [`GamepadAxis`]. /// -/// It is used inside of the [`GamepadSettings`] to define the sensitivity range and +/// It is used inside the [`GamepadSettings`] to define the sensitivity range and /// threshold for an axis. /// Values that are higher than `livezone_upperbound` will be rounded up to 1.0. /// Values that are lower than `livezone_lowerbound` will be rounded down to -1.0. @@ -951,7 +1255,7 @@ impl AxisSettings { /// Settings for a [`GamepadButton`]. /// -/// It is used inside of the [`GamepadSettings`] to define the sensitivity range and +/// It is used inside the [`GamepadSettings`] to define the sensitivity range and /// threshold for a button axis. /// /// ## Logic @@ -961,10 +1265,6 @@ impl AxisSettings { /// - Otherwise, values will not be rounded. /// /// The valid range is from 0.0 to 1.0, inclusive. -/// -/// ## Updating -/// -/// The current value of a button is received through the [`GamepadButtonChangedEvent`]. #[derive(Debug, Clone)] #[cfg_attr(feature = "bevy_reflect", derive(Reflect), reflect(Debug, Default))] pub struct ButtonAxisSettings { @@ -1028,47 +1328,40 @@ impl ButtonAxisSettings { } } -/// Handles [`GamepadConnectionEvent`]s and updates gamepad resources. +/// Handles [`GamepadConnectionEvent`]s events. /// -/// Updates the [`Gamepads`] resource and resets and/or initializes -/// the [`Axis`] and [`ButtonInput`] resources. +/// On connection, adds the components representing a [`Gamepad`] to the entity. +/// On disconnection, removes the [`Gamepad`] and other related components. +/// Entities are left alive and might leave components like [`GamepadSettings`] to preserve state in the case of a reconnection /// /// ## Note /// /// Whenever a [`Gamepad`] connects or disconnects, an information gets printed to the console using the [`info!`] macro. pub fn gamepad_connection_system( - mut gamepads: ResMut, + mut commands: Commands, mut connection_events: EventReader, - mut axis: ResMut>, - mut button_axis: ResMut>, - mut button_input: ResMut>, ) { for connection_event in connection_events.read() { - let gamepad = connection_event.gamepad; - - if let GamepadConnection::Connected(info) = &connection_event.connection { - gamepads.register(gamepad, info.clone()); - info!("{:?} Connected", gamepad); - - for button_type in &ALL_BUTTON_TYPES { - let gamepad_button = GamepadButton::new(gamepad, *button_type); - button_input.reset(gamepad_button); - button_axis.set(gamepad_button, 0.0); - } - for axis_type in &ALL_AXIS_TYPES { - axis.set(GamepadAxis::new(gamepad, *axis_type), 0.0); - } - } else { - gamepads.deregister(gamepad); - info!("{:?} Disconnected", gamepad); - - for button_type in &ALL_BUTTON_TYPES { - let gamepad_button = GamepadButton::new(gamepad, *button_type); - button_input.reset(gamepad_button); - button_axis.remove(gamepad_button); + let id = connection_event.gamepad; + match &connection_event.connection { + GamepadConnection::Connected(info) => { + let Some(gamepad) = commands.get_entity(id) else { + warn!("Gamepad {:} removed before handling connection event.", id); + continue; + }; + gamepad.insert(Gamepad::new(info.clone())); + info!("Gamepad {:?} connected.", id); } - for axis_type in &ALL_AXIS_TYPES { - axis.remove(GamepadAxis::new(gamepad, *axis_type)); + GamepadConnection::Disconnected => { + let Some(gamepad) = commands.get_entity(id) else { + warn!("Gamepad {:} removed before handling disconnection event. You can ignore this if you manually removed it.", id); + continue; + }; + // Gamepad entities are left alive to preserve their state (e.g. [`GamepadSettings`]). + // Instead of despawning, we remove Gamepad components that don't need to preserve state + // and re-add them if they ever reconnect. + gamepad.remove::(); + info!("Gamepad {:} disconnected.", id); } } } @@ -1089,243 +1382,104 @@ pub enum GamepadConnection { Disconnected, } -/// A Gamepad connection event. Created when a connection to a gamepad -/// is established and when a gamepad is disconnected. -#[derive(Event, Debug, Clone, PartialEq)] -#[cfg_attr(feature = "bevy_reflect", derive(Reflect), reflect(Debug, PartialEq))] -#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr( - all(feature = "serialize", feature = "bevy_reflect"), - reflect(Serialize, Deserialize) -)] -pub struct GamepadConnectionEvent { - /// The gamepad whose connection status changed. - pub gamepad: Gamepad, - /// The change in the gamepads connection. - pub connection: GamepadConnection, -} - -impl GamepadConnectionEvent { - /// Creates a [`GamepadConnectionEvent`]. - pub fn new(gamepad: Gamepad, connection: GamepadConnection) -> Self { - Self { - gamepad, - connection, - } - } - - /// Is the gamepad connected? - pub fn connected(&self) -> bool { - matches!(self.connection, GamepadConnection::Connected(_)) - } - - /// Is the gamepad disconnected? - pub fn disconnected(&self) -> bool { - !self.connected() - } -} - -/// Gamepad event for when the "value" on the axis changes -/// by an amount larger than the threshold defined in [`GamepadSettings`]. -#[derive(Event, Debug, Clone, PartialEq)] -#[cfg_attr(feature = "bevy_reflect", derive(Reflect), reflect(Debug, PartialEq))] -#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr( - all(feature = "serialize", feature = "bevy_reflect"), - reflect(Serialize, Deserialize) -)] -pub struct GamepadAxisChangedEvent { - /// The gamepad on which the axis is triggered. - pub gamepad: Gamepad, - /// The type of the triggered axis. - pub axis_type: GamepadAxisType, - /// The value of the axis. - pub value: f32, -} - -impl GamepadAxisChangedEvent { - /// Creates a [`GamepadAxisChangedEvent`]. - pub fn new(gamepad: Gamepad, axis_type: GamepadAxisType, value: f32) -> Self { - Self { - gamepad, - axis_type, - value, - } - } -} - -/// Gamepad event for when the "value" (amount of pressure) on the button -/// changes by an amount larger than the threshold defined in [`GamepadSettings`]. -#[derive(Event, Debug, Clone, PartialEq)] -#[cfg_attr(feature = "bevy_reflect", derive(Reflect), reflect(Debug, PartialEq))] -#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr( - all(feature = "serialize", feature = "bevy_reflect"), - reflect(Serialize, Deserialize) -)] -pub struct GamepadButtonChangedEvent { - /// The gamepad on which the button is triggered. - pub gamepad: Gamepad, - /// The type of the triggered button. - pub button_type: GamepadButtonType, - /// The value of the button. - pub value: f32, -} - -impl GamepadButtonChangedEvent { - /// Creates a [`GamepadButtonChangedEvent`]. - pub fn new(gamepad: Gamepad, button_type: GamepadButtonType, value: f32) -> Self { - Self { - gamepad, - button_type, - value, - } - } -} - -/// Uses [`GamepadAxisChangedEvent`]s to update the relevant [`ButtonInput`] and [`Axis`] values. -pub fn gamepad_axis_event_system( - mut gamepad_axis: ResMut>, - mut axis_events: EventReader, -) { - for axis_event in axis_events.read() { - let axis = GamepadAxis::new(axis_event.gamepad, axis_event.axis_type); - gamepad_axis.set(axis, axis_event.value); - } -} - -/// Uses [`GamepadButtonChangedEvent`]s to update the relevant [`ButtonInput`] and [`Axis`] values. -pub fn gamepad_button_event_system( - mut button_changed_events: EventReader, - mut button_input: ResMut>, - mut button_input_events: EventWriter, - settings: Res, +/// Consumes [`RawGamepadEvent`] events, filters them using their [`GamepadSettings`] and if successful, +/// updates the [`Gamepad`] and sends [`GamepadAxisChangedEvent`], [`GamepadButtonStateChangedEvent`], [`GamepadButtonChangedEvent`] events. +pub fn gamepad_event_processing_system( + mut gamepads: Query<(&mut Gamepad, &GamepadSettings)>, + mut raw_events: EventReader, + mut processed_events: EventWriter, + mut processed_axis_events: EventWriter, + mut processed_digital_events: EventWriter, + mut processed_analog_events: EventWriter, ) { - for button_event in button_changed_events.read() { - let button = GamepadButton::new(button_event.gamepad, button_event.button_type); - let value = button_event.value; - let button_property = settings.get_button_settings(button); - - if button_property.is_released(value) { - // Check if button was previously pressed - if button_input.pressed(button) { - button_input_events.send(GamepadButtonInput { - button, - state: ButtonState::Released, - }); - } - // We don't have to check if the button was previously pressed here - // because that check is performed within Input::release() - button_input.release(button); - } else if button_property.is_pressed(value) { - // Check if button was previously not pressed - if !button_input.pressed(button) { - button_input_events.send(GamepadButtonInput { - button, - state: ButtonState::Pressed, - }); - } - button_input.press(button); - }; - } -} - -/// A gamepad event. -/// -/// This event type is used over the [`GamepadConnectionEvent`], -/// [`GamepadButtonChangedEvent`] and [`GamepadAxisChangedEvent`] when -/// the in-frame relative ordering of events is important. -#[derive(Event, Debug, Clone, PartialEq)] -#[cfg_attr(feature = "bevy_reflect", derive(Reflect), reflect(Debug, PartialEq))] -#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr( - all(feature = "serialize", feature = "bevy_reflect"), - reflect(Serialize, Deserialize) -)] -pub enum GamepadEvent { - /// A gamepad has been connected or disconnected. - Connection(GamepadConnectionEvent), - /// A button of the gamepad has been triggered. - Button(GamepadButtonChangedEvent), - /// An axis of the gamepad has been triggered. - Axis(GamepadAxisChangedEvent), -} - -impl From for GamepadEvent { - fn from(value: GamepadConnectionEvent) -> Self { - Self::Connection(value) - } -} - -impl From for GamepadEvent { - fn from(value: GamepadButtonChangedEvent) -> Self { - Self::Button(value) - } -} - -impl From for GamepadEvent { - fn from(value: GamepadAxisChangedEvent) -> Self { - Self::Axis(value) + // Clear digital buttons state + for (mut gamepad, _) in gamepads.iter_mut() { + gamepad.bypass_change_detection().digital.clear(); } -} -/// Splits the [`GamepadEvent`] event stream into its component events. -pub fn gamepad_event_system( - mut gamepad_events: EventReader, - mut connection_events: EventWriter, - mut button_events: EventWriter, - mut axis_events: EventWriter, - mut button_input: ResMut>, -) { - button_input.bypass_change_detection().clear(); - for gamepad_event in gamepad_events.read() { - match gamepad_event { - GamepadEvent::Connection(connection_event) => { - connection_events.send(connection_event.clone()); + for event in raw_events.read() { + match event { + // Connections require inserting/removing components so they are done in a separate system + RawGamepadEvent::Connection(send_event) => { + processed_events.send(GamepadEvent::from(send_event.clone())); } - GamepadEvent::Button(button_event) => { - button_events.send(button_event.clone()); + RawGamepadEvent::Axis(RawGamepadAxisChangedEvent { + gamepad, + axis, + value, + }) => { + let (gamepad, axis, value) = (*gamepad, *axis, *value); + let Ok((mut gamepad_axis, gamepad_settings)) = gamepads.get_mut(gamepad) else { + continue; + }; + let Some(filtered_value) = gamepad_settings + .get_axis_settings(axis) + .filter(value, gamepad_axis.get(axis)) + else { + continue; + }; + + gamepad_axis.analog.set(axis.into(), filtered_value); + let send_event = GamepadAxisChangedEvent::new(gamepad, axis, filtered_value); + processed_axis_events.send(send_event); + processed_events.send(GamepadEvent::from(send_event)); } - GamepadEvent::Axis(axis_event) => { - axis_events.send(axis_event.clone()); + RawGamepadEvent::Button(RawGamepadButtonChangedEvent { + gamepad, + button, + value, + }) => { + let (gamepad, button, value) = (*gamepad, *button, *value); + let Ok((mut gamepad_buttons, settings)) = gamepads.get_mut(gamepad) else { + continue; + }; + let Some(filtered_value) = settings + .get_button_axis_settings(button) + .filter(value, gamepad_buttons.get(button)) + else { + continue; + }; + let button_settings = settings.get_button_settings(button); + gamepad_buttons.analog.set(button.into(), filtered_value); + + if button_settings.is_released(filtered_value) { + // Check if button was previously pressed + if gamepad_buttons.pressed(button) { + processed_digital_events.send(GamepadButtonStateChangedEvent::new( + gamepad, + button, + ButtonState::Released, + )); + } + // We don't have to check if the button was previously pressed here + // because that check is performed within Input::release() + gamepad_buttons.digital.release(button); + } else if button_settings.is_pressed(filtered_value) { + // Check if button was previously not pressed + if !gamepad_buttons.pressed(button) { + processed_digital_events.send(GamepadButtonStateChangedEvent::new( + gamepad, + button, + ButtonState::Pressed, + )); + } + gamepad_buttons.digital.press(button); + }; + + let button_state = if gamepad_buttons.digital.pressed(button) { + ButtonState::Pressed + } else { + ButtonState::Released + }; + let send_event = + GamepadButtonChangedEvent::new(gamepad, button, button_state, filtered_value); + processed_analog_events.send(send_event); + processed_events.send(GamepadEvent::from(send_event)); } } } } -/// An array of every [`GamepadButtonType`] variant. -const ALL_BUTTON_TYPES: [GamepadButtonType; 19] = [ - GamepadButtonType::South, - GamepadButtonType::East, - GamepadButtonType::North, - GamepadButtonType::West, - GamepadButtonType::C, - GamepadButtonType::Z, - GamepadButtonType::LeftTrigger, - GamepadButtonType::LeftTrigger2, - GamepadButtonType::RightTrigger, - GamepadButtonType::RightTrigger2, - GamepadButtonType::Select, - GamepadButtonType::Start, - GamepadButtonType::Mode, - GamepadButtonType::LeftThumb, - GamepadButtonType::RightThumb, - GamepadButtonType::DPadUp, - GamepadButtonType::DPadDown, - GamepadButtonType::DPadLeft, - GamepadButtonType::DPadRight, -]; - -/// An array of every [`GamepadAxisType`] variant. -const ALL_AXIS_TYPES: [GamepadAxisType; 6] = [ - GamepadAxisType::LeftStickX, - GamepadAxisType::LeftStickY, - GamepadAxisType::LeftZ, - GamepadAxisType::RightStickX, - GamepadAxisType::RightStickY, - GamepadAxisType::RightZ, -]; - /// The intensity at which a gamepad's force-feedback motors may rumble. #[derive(Clone, Copy, Debug, PartialEq)] pub struct GamepadRumbleIntensity { @@ -1385,7 +1539,7 @@ impl GamepadRumbleIntensity { } } -/// An event that controls force-feedback rumbling of a [`Gamepad`]. +/// An event that controls force-feedback rumbling of a [`Gamepad`] [`entity`](Entity). /// /// # Notes /// @@ -1394,16 +1548,16 @@ impl GamepadRumbleIntensity { /// # Example /// /// ``` -/// # use bevy_input::gamepad::{Gamepad, Gamepads, GamepadRumbleRequest, GamepadRumbleIntensity}; -/// # use bevy_ecs::prelude::{EventWriter, Res}; +/// # use bevy_input::gamepad::{Gamepad, GamepadRumbleRequest, GamepadRumbleIntensity}; +/// # use bevy_ecs::prelude::{EventWriter, Res, Query, Entity, With}; /// # use bevy_utils::Duration; /// fn rumble_gamepad_system( /// mut rumble_requests: EventWriter, -/// gamepads: Res +/// gamepads: Query>, /// ) { -/// for gamepad in gamepads.iter() { +/// for entity in gamepads.iter() { /// rumble_requests.send(GamepadRumbleRequest::Add { -/// gamepad, +/// gamepad: entity, /// intensity: GamepadRumbleIntensity::MAX, /// duration: Duration::from_secs_f32(0.5), /// }); @@ -1432,18 +1586,18 @@ pub enum GamepadRumbleRequest { /// How intense the rumble should be. intensity: GamepadRumbleIntensity, /// The gamepad to rumble. - gamepad: Gamepad, + gamepad: Entity, }, - /// Stop all running rumbles on the given [`Gamepad`]. + /// Stop all running rumbles on the given [`Entity`]. Stop { /// The gamepad to stop rumble. - gamepad: Gamepad, + gamepad: Entity, }, } impl GamepadRumbleRequest { - /// Get the [`Gamepad`] associated with this request. - pub fn gamepad(&self) -> Gamepad { + /// Get the [`Entity`] associated with this request. + pub fn gamepad(&self) -> Entity { match self { Self::Add { gamepad, .. } | Self::Stop { gamepad } => *gamepad, } @@ -1452,9 +1606,20 @@ impl GamepadRumbleRequest { #[cfg(test)] mod tests { - use crate::gamepad::{AxisSettingsError, ButtonSettingsError}; - - use super::{AxisSettings, ButtonAxisSettings, ButtonSettings}; + use super::{ + gamepad_connection_system, gamepad_event_processing_system, AxisSettings, + AxisSettingsError, ButtonAxisSettings, ButtonSettings, ButtonSettingsError, Gamepad, + GamepadAxis, GamepadAxisChangedEvent, GamepadButton, GamepadButtonChangedEvent, + GamepadButtonStateChangedEvent, + GamepadConnection::{Connected, Disconnected}, + GamepadConnectionEvent, GamepadEvent, GamepadInfo, GamepadSettings, + RawGamepadAxisChangedEvent, RawGamepadButtonChangedEvent, RawGamepadEvent, + }; + use crate::ButtonState; + use bevy_app::{App, PreUpdate}; + use bevy_ecs::entity::Entity; + use bevy_ecs::event::Events; + use bevy_ecs::schedule::IntoSystemConfigs; fn test_button_axis_settings_filter( settings: ButtonAxisSettings, @@ -1784,4 +1949,789 @@ mod tests { axis_settings.try_set_livezone_upperbound(0.1) ); } + + struct TestContext { + pub app: App, + } + + impl TestContext { + pub fn new() -> Self { + let mut app = App::new(); + app.add_systems( + PreUpdate, + ( + gamepad_connection_system, + gamepad_event_processing_system.after(gamepad_connection_system), + ), + ) + .add_event::() + .add_event::() + .add_event::() + .add_event::() + .add_event::() + .add_event::() + .add_event::() + .add_event::(); + Self { app } + } + + pub fn update(&mut self) { + self.app.update(); + } + + pub fn send_gamepad_connection_event(&mut self, gamepad: Option) -> Entity { + let gamepad = gamepad.unwrap_or_else(|| self.app.world_mut().spawn_empty().id()); + self.app + .world_mut() + .resource_mut::>() + .send(GamepadConnectionEvent::new( + gamepad, + Connected(GamepadInfo { + name: String::from("Gamepad test"), + }), + )); + gamepad + } + + pub fn send_gamepad_disconnection_event(&mut self, gamepad: Entity) { + self.app + .world_mut() + .resource_mut::>() + .send(GamepadConnectionEvent::new(gamepad, Disconnected)); + } + + pub fn send_raw_gamepad_event(&mut self, event: RawGamepadEvent) { + self.app + .world_mut() + .resource_mut::>() + .send(event); + } + + pub fn send_raw_gamepad_event_batch( + &mut self, + events: impl IntoIterator, + ) { + self.app + .world_mut() + .resource_mut::>() + .send_batch(events); + } + } + + #[test] + fn connection_event() { + let mut ctx = TestContext::new(); + assert_eq!( + ctx.app + .world_mut() + .query::<&Gamepad>() + .iter(ctx.app.world()) + .len(), + 0 + ); + ctx.send_gamepad_connection_event(None); + ctx.update(); + assert_eq!( + ctx.app + .world_mut() + .query::<(&Gamepad, &GamepadSettings)>() + .iter(ctx.app.world()) + .len(), + 1 + ); + } + + #[test] + fn disconnection_event() { + let mut ctx = TestContext::new(); + assert_eq!( + ctx.app + .world_mut() + .query::<&Gamepad>() + .iter(ctx.app.world()) + .len(), + 0 + ); + let entity = ctx.send_gamepad_connection_event(None); + ctx.update(); + assert_eq!( + ctx.app + .world_mut() + .query::<(&Gamepad, &GamepadSettings)>() + .iter(ctx.app.world()) + .len(), + 1 + ); + ctx.send_gamepad_disconnection_event(entity); + ctx.update(); + // Gamepad component should be removed + assert!(ctx + .app + .world_mut() + .query::<&Gamepad>() + .get(ctx.app.world(), entity) + .is_err()); + // Settings should be kept + assert!(ctx + .app + .world_mut() + .query::<&GamepadSettings>() + .get(ctx.app.world(), entity) + .is_ok()); + + // Mistakenly sending a second disconnection event shouldn't break anything + ctx.send_gamepad_disconnection_event(entity); + ctx.update(); + assert!(ctx + .app + .world_mut() + .query::<&Gamepad>() + .get(ctx.app.world(), entity) + .is_err()); + assert!(ctx + .app + .world_mut() + .query::<&GamepadSettings>() + .get(ctx.app.world(), entity) + .is_ok()); + } + + #[test] + fn connection_disconnection_frame_event() { + let mut ctx = TestContext::new(); + assert_eq!( + ctx.app + .world_mut() + .query::<&Gamepad>() + .iter(ctx.app.world()) + .len(), + 0 + ); + let entity = ctx.send_gamepad_connection_event(None); + ctx.send_gamepad_disconnection_event(entity); + ctx.update(); + // Gamepad component should be removed + assert!(ctx + .app + .world_mut() + .query::<&Gamepad>() + .get(ctx.app.world(), entity) + .is_err()); + // Settings should be kept + assert!(ctx + .app + .world_mut() + .query::<&GamepadSettings>() + .get(ctx.app.world(), entity) + .is_ok()); + } + + #[test] + fn reconnection_event() { + let button_settings = ButtonSettings::new(0.7, 0.2).expect("correct parameters"); + let mut ctx = TestContext::new(); + assert_eq!( + ctx.app + .world_mut() + .query::<&Gamepad>() + .iter(ctx.app.world()) + .len(), + 0 + ); + let entity = ctx.send_gamepad_connection_event(None); + ctx.update(); + let mut settings = ctx + .app + .world_mut() + .query::<&mut GamepadSettings>() + .get_mut(ctx.app.world_mut(), entity) + .expect("be alive"); + assert_ne!(settings.default_button_settings, button_settings); + settings.default_button_settings = button_settings.clone(); + ctx.send_gamepad_disconnection_event(entity); + ctx.update(); + assert_eq!( + ctx.app + .world_mut() + .query::<&Gamepad>() + .iter(ctx.app.world()) + .len(), + 0 + ); + ctx.send_gamepad_connection_event(Some(entity)); + ctx.update(); + let settings = ctx + .app + .world_mut() + .query::<&GamepadSettings>() + .get(ctx.app.world(), entity) + .expect("be alive"); + assert_eq!(settings.default_button_settings, button_settings); + } + + #[test] + fn reconnection_same_frame_event() { + let mut ctx = TestContext::new(); + assert_eq!( + ctx.app + .world_mut() + .query::<&Gamepad>() + .iter(ctx.app.world()) + .len(), + 0 + ); + let entity = ctx.send_gamepad_connection_event(None); + ctx.send_gamepad_disconnection_event(entity); + ctx.update(); + assert_eq!( + ctx.app + .world_mut() + .query::<&Gamepad>() + .iter(ctx.app.world()) + .len(), + 0 + ); + assert!(ctx + .app + .world_mut() + .query::<(Entity, &GamepadSettings)>() + .get(ctx.app.world(), entity) + .is_ok()); + } + + #[test] + fn gamepad_axis_valid() { + let mut ctx = TestContext::new(); + + // Create test gamepad + let entity = ctx.send_gamepad_connection_event(None); + ctx.app + .world_mut() + .resource_mut::>() + .send_batch([ + RawGamepadEvent::Axis(RawGamepadAxisChangedEvent::new( + entity, + GamepadAxis::LeftStickY, + 0.5, + )), + RawGamepadEvent::Axis(RawGamepadAxisChangedEvent::new( + entity, + GamepadAxis::RightStickX, + 0.6, + )), + RawGamepadEvent::Axis(RawGamepadAxisChangedEvent::new( + entity, + GamepadAxis::RightZ, + -0.4, + )), + RawGamepadEvent::Axis(RawGamepadAxisChangedEvent::new( + entity, + GamepadAxis::RightStickY, + -0.8, + )), + ]); + ctx.update(); + assert_eq!( + ctx.app + .world() + .resource::>() + .len(), + 4 + ); + } + + #[test] + fn gamepad_axis_threshold_filter() { + let mut ctx = TestContext::new(); + + // Create test gamepad + let entity = ctx.send_gamepad_connection_event(None); + let settings = GamepadSettings::default().default_axis_settings; + // Set of events to ensure they are being properly filtered + let base_value = 0.5; + let events = [ + // Event above threshold + RawGamepadEvent::Axis(RawGamepadAxisChangedEvent::new( + entity, + GamepadAxis::LeftStickX, + base_value, + )), + // Event below threshold, should be filtered + RawGamepadEvent::Axis(RawGamepadAxisChangedEvent::new( + entity, + GamepadAxis::LeftStickX, + base_value + settings.threshold - 0.01, + )), + // Event above threshold + RawGamepadEvent::Axis(RawGamepadAxisChangedEvent::new( + entity, + GamepadAxis::LeftStickX, + base_value + settings.threshold + 0.01, + )), + ]; + ctx.app + .world_mut() + .resource_mut::>() + .send_batch(events); + ctx.update(); + assert_eq!( + ctx.app + .world() + .resource::>() + .len(), + 2 + ); + } + + #[test] + fn gamepad_axis_deadzone_filter() { + let mut ctx = TestContext::new(); + + // Create test gamepad + let entity = ctx.send_gamepad_connection_event(None); + let settings = GamepadSettings::default().default_axis_settings; + + // Set of events to ensure they are being properly filtered + let events = [ + // Event below deadzone upperbound should be filtered + RawGamepadEvent::Axis(RawGamepadAxisChangedEvent::new( + entity, + GamepadAxis::LeftStickX, + settings.deadzone_upperbound - 0.01, + )), + // Event above deadzone lowerbound should be filtered + RawGamepadEvent::Axis(RawGamepadAxisChangedEvent::new( + entity, + GamepadAxis::LeftStickX, + settings.deadzone_lowerbound + 0.01, + )), + ]; + ctx.app + .world_mut() + .resource_mut::>() + .send_batch(events); + ctx.update(); + assert_eq!( + ctx.app + .world() + .resource::>() + .len(), + 0 + ); + } + + #[test] + fn gamepad_axis_deadzone_rounded() { + let mut ctx = TestContext::new(); + + // Create test gamepad + let entity = ctx.send_gamepad_connection_event(None); + let settings = GamepadSettings::default().default_axis_settings; + + // Set of events to ensure they are being properly filtered + let events = [ + RawGamepadEvent::Axis(RawGamepadAxisChangedEvent::new( + entity, + GamepadAxis::LeftStickX, + 1.0, + )), + // Event below deadzone upperbound should be rounded to 0 + RawGamepadEvent::Axis(RawGamepadAxisChangedEvent::new( + entity, + GamepadAxis::LeftStickX, + settings.deadzone_upperbound - 0.01, + )), + RawGamepadEvent::Axis(RawGamepadAxisChangedEvent::new( + entity, + GamepadAxis::LeftStickX, + 1.0, + )), + // Event above deadzone lowerbound should be rounded to 0 + RawGamepadEvent::Axis(RawGamepadAxisChangedEvent::new( + entity, + GamepadAxis::LeftStickX, + settings.deadzone_lowerbound + 0.01, + )), + ]; + let results = [1.0, 0.0, 1.0, 0.0]; + ctx.app + .world_mut() + .resource_mut::>() + .send_batch(events); + ctx.update(); + + let events = ctx + .app + .world() + .resource::>(); + let mut event_reader = events.get_cursor(); + for (event, result) in event_reader.read(events).zip(results) { + assert_eq!(event.value, result); + } + assert_eq!( + ctx.app + .world() + .resource::>() + .len(), + 4 + ); + } + + #[test] + fn gamepad_axis_livezone_filter() { + let mut ctx = TestContext::new(); + + // Create test gamepad + let entity = ctx.send_gamepad_connection_event(None); + let settings = GamepadSettings::default().default_axis_settings; + + // Set of events to ensure they are being properly filtered + let events = [ + RawGamepadEvent::Axis(RawGamepadAxisChangedEvent::new( + entity, + GamepadAxis::LeftStickX, + 1.0, + )), + // Event above livezone upperbound should be filtered + RawGamepadEvent::Axis(RawGamepadAxisChangedEvent::new( + entity, + GamepadAxis::LeftStickX, + settings.livezone_upperbound + 0.01, + )), + RawGamepadEvent::Axis(RawGamepadAxisChangedEvent::new( + entity, + GamepadAxis::LeftStickX, + -1.0, + )), + // Event below livezone lowerbound should be filtered + RawGamepadEvent::Axis(RawGamepadAxisChangedEvent::new( + entity, + GamepadAxis::LeftStickX, + settings.livezone_lowerbound - 0.01, + )), + ]; + ctx.app + .world_mut() + .resource_mut::>() + .send_batch(events); + ctx.update(); + assert_eq!( + ctx.app + .world() + .resource::>() + .len(), + 2 + ); + } + + #[test] + fn gamepad_axis_livezone_rounded() { + let mut ctx = TestContext::new(); + + // Create test gamepad + let entity = ctx.send_gamepad_connection_event(None); + let settings = GamepadSettings::default().default_axis_settings; + + // Set of events to ensure they are being properly filtered + let events = [ + // Event above livezone upperbound should be rounded to 1 + RawGamepadEvent::Axis(RawGamepadAxisChangedEvent::new( + entity, + GamepadAxis::LeftStickX, + settings.livezone_upperbound + 0.01, + )), + // Event below livezone lowerbound should be rounded to -1 + RawGamepadEvent::Axis(RawGamepadAxisChangedEvent::new( + entity, + GamepadAxis::LeftStickX, + settings.livezone_lowerbound - 0.01, + )), + ]; + let results = [1.0, -1.0]; + ctx.app + .world_mut() + .resource_mut::>() + .send_batch(events); + ctx.update(); + + let events = ctx + .app + .world() + .resource::>(); + let mut event_reader = events.get_cursor(); + for (event, result) in event_reader.read(events).zip(results) { + assert_eq!(event.value, result); + } + assert_eq!( + ctx.app + .world() + .resource::>() + .len(), + 2 + ); + } + + #[test] + fn gamepad_buttons_pressed() { + let mut ctx = TestContext::new(); + + // Create test gamepad + let entity = ctx.send_gamepad_connection_event(None); + let digital_settings = GamepadSettings::default().default_button_settings; + + let events = [RawGamepadEvent::Button(RawGamepadButtonChangedEvent::new( + entity, + GamepadButton::DPadDown, + digital_settings.press_threshold, + ))]; + ctx.app + .world_mut() + .resource_mut::>() + .send_batch(events); + ctx.update(); + + assert_eq!( + ctx.app + .world() + .resource::>() + .len(), + 1 + ); + let events = ctx + .app + .world() + .resource::>(); + let mut event_reader = events.get_cursor(); + for event in event_reader.read(events) { + assert_eq!(event.button, GamepadButton::DPadDown); + assert_eq!(event.state, ButtonState::Pressed); + } + assert!(ctx + .app + .world_mut() + .query::<&Gamepad>() + .get(ctx.app.world(), entity) + .unwrap() + .pressed(GamepadButton::DPadDown)); + + ctx.app + .world_mut() + .resource_mut::>() + .clear(); + ctx.update(); + + assert_eq!( + ctx.app + .world() + .resource::>() + .len(), + 0 + ); + assert!(ctx + .app + .world_mut() + .query::<&Gamepad>() + .get(ctx.app.world(), entity) + .unwrap() + .pressed(GamepadButton::DPadDown)); + } + + #[test] + fn gamepad_buttons_just_pressed() { + let mut ctx = TestContext::new(); + + // Create test gamepad + let entity = ctx.send_gamepad_connection_event(None); + let digital_settings = GamepadSettings::default().default_button_settings; + + ctx.send_raw_gamepad_event(RawGamepadEvent::Button(RawGamepadButtonChangedEvent::new( + entity, + GamepadButton::DPadDown, + digital_settings.press_threshold, + ))); + ctx.update(); + + // Check it is flagged for this frame + assert!(ctx + .app + .world_mut() + .query::<&Gamepad>() + .get(ctx.app.world(), entity) + .unwrap() + .just_pressed(GamepadButton::DPadDown)); + ctx.update(); + + //Check it clears next frame + assert!(!ctx + .app + .world_mut() + .query::<&Gamepad>() + .get(ctx.app.world(), entity) + .unwrap() + .just_pressed(GamepadButton::DPadDown)); + } + #[test] + fn gamepad_buttons_released() { + let mut ctx = TestContext::new(); + + // Create test gamepad + let entity = ctx.send_gamepad_connection_event(None); + let digital_settings = GamepadSettings::default().default_button_settings; + + ctx.send_raw_gamepad_event(RawGamepadEvent::Button(RawGamepadButtonChangedEvent::new( + entity, + GamepadButton::DPadDown, + digital_settings.press_threshold, + ))); + ctx.update(); + + ctx.app + .world_mut() + .resource_mut::>() + .clear(); + ctx.send_raw_gamepad_event(RawGamepadEvent::Button(RawGamepadButtonChangedEvent::new( + entity, + GamepadButton::DPadDown, + digital_settings.release_threshold - 0.01, + ))); + ctx.update(); + assert_eq!( + ctx.app + .world() + .resource::>() + .len(), + 1 + ); + let events = ctx + .app + .world() + .resource::>(); + let mut event_reader = events.get_cursor(); + for event in event_reader.read(events) { + assert_eq!(event.button, GamepadButton::DPadDown); + assert_eq!(event.state, ButtonState::Released); + } + assert!(!ctx + .app + .world_mut() + .query::<&Gamepad>() + .get(ctx.app.world(), entity) + .unwrap() + .pressed(GamepadButton::DPadDown)); + ctx.app + .world_mut() + .resource_mut::>() + .clear(); + ctx.update(); + + assert_eq!( + ctx.app + .world() + .resource::>() + .len(), + 0 + ); + } + + #[test] + fn gamepad_buttons_just_released() { + let mut ctx = TestContext::new(); + + // Create test gamepad + let entity = ctx.send_gamepad_connection_event(None); + let digital_settings = GamepadSettings::default().default_button_settings; + + ctx.send_raw_gamepad_event_batch([ + RawGamepadEvent::Button(RawGamepadButtonChangedEvent::new( + entity, + GamepadButton::DPadDown, + digital_settings.press_threshold, + )), + RawGamepadEvent::Button(RawGamepadButtonChangedEvent::new( + entity, + GamepadButton::DPadDown, + digital_settings.release_threshold - 0.01, + )), + ]); + ctx.update(); + + // Check it is flagged for this frame + assert!(ctx + .app + .world_mut() + .query::<&Gamepad>() + .get(ctx.app.world(), entity) + .unwrap() + .just_released(GamepadButton::DPadDown)); + ctx.update(); + + //Check it clears next frame + assert!(!ctx + .app + .world_mut() + .query::<&Gamepad>() + .get(ctx.app.world(), entity) + .unwrap() + .just_released(GamepadButton::DPadDown)); + } + + #[test] + fn gamepad_buttons_axis() { + let mut ctx = TestContext::new(); + + // Create test gamepad + let entity = ctx.send_gamepad_connection_event(None); + let digital_settings = GamepadSettings::default().default_button_settings; + let analog_settings = GamepadSettings::default().default_button_axis_settings; + + // Test events + let events = [ + // Should trigger event + RawGamepadEvent::Button(RawGamepadButtonChangedEvent::new( + entity, + GamepadButton::DPadDown, + digital_settings.press_threshold, + )), + // Should trigger event + RawGamepadEvent::Button(RawGamepadButtonChangedEvent::new( + entity, + GamepadButton::DPadDown, + digital_settings.release_threshold, + )), + // Shouldn't trigger a state changed event + RawGamepadEvent::Button(RawGamepadButtonChangedEvent::new( + entity, + GamepadButton::DPadDown, + digital_settings.release_threshold - analog_settings.threshold * 1.01, + )), + // Shouldn't trigger any event + RawGamepadEvent::Button(RawGamepadButtonChangedEvent::new( + entity, + GamepadButton::DPadDown, + digital_settings.release_threshold - (analog_settings.threshold * 1.5), + )), + // Shouldn't trigger a state changed event + RawGamepadEvent::Button(RawGamepadButtonChangedEvent::new( + entity, + GamepadButton::DPadDown, + digital_settings.release_threshold - (analog_settings.threshold * 2.02), + )), + ]; + ctx.send_raw_gamepad_event_batch(events); + ctx.update(); + assert_eq!( + ctx.app + .world() + .resource::>() + .len(), + 2 + ); + assert_eq!( + ctx.app + .world() + .resource::>() + .len(), + 4 + ); + } } diff --git a/crates/bevy_input/src/lib.rs b/crates/bevy_input/src/lib.rs index b4dac1ee7f934..ddcfa5bf17e89 100644 --- a/crates/bevy_input/src/lib.rs +++ b/crates/bevy_input/src/lib.rs @@ -30,9 +30,7 @@ pub use button_input::*; pub mod prelude { #[doc(hidden)] pub use crate::{ - gamepad::{ - Gamepad, GamepadAxis, GamepadAxisType, GamepadButton, GamepadButtonType, Gamepads, - }, + gamepad::{Gamepad, GamepadAxis, GamepadButton, GamepadSettings}, keyboard::KeyCode, mouse::MouseButton, touch::{TouchInput, Touches}, @@ -54,10 +52,10 @@ use mouse::{ use touch::{touch_screen_input_system, TouchInput, Touches}; use gamepad::{ - gamepad_axis_event_system, gamepad_button_event_system, gamepad_connection_system, - gamepad_event_system, GamepadAxis, GamepadAxisChangedEvent, GamepadButton, - GamepadButtonChangedEvent, GamepadButtonInput, GamepadConnectionEvent, GamepadEvent, - GamepadRumbleRequest, GamepadSettings, Gamepads, + gamepad_connection_system, gamepad_event_processing_system, GamepadAxisChangedEvent, + GamepadButtonChangedEvent, GamepadButtonStateChangedEvent, GamepadConnection, + GamepadConnectionEvent, GamepadEvent, GamepadInfo, GamepadRumbleRequest, GamepadSettings, + RawGamepadAxisChangedEvent, RawGamepadButtonChangedEvent, RawGamepadEvent, }; #[cfg(all(feature = "serialize", feature = "bevy_reflect"))] @@ -98,30 +96,22 @@ impl Plugin for InputPlugin { .add_event::() .add_event::() // gamepad + .add_event::() .add_event::() .add_event::() - .add_event::() + .add_event::() .add_event::() - .add_event::() + .add_event::() + .add_event::() + .add_event::() .add_event::() - .init_resource::() - .init_resource::() - .init_resource::>() - .init_resource::>() - .init_resource::>() .init_resource::() .init_resource::() .add_systems( PreUpdate, ( - gamepad_event_system, - gamepad_connection_system.after(gamepad_event_system), - gamepad_button_event_system - .after(gamepad_event_system) - .after(gamepad_connection_system), - gamepad_axis_event_system - .after(gamepad_event_system) - .after(gamepad_connection_system), + gamepad_connection_system, + gamepad_event_processing_system.after(gamepad_connection_system), ) .in_set(InputSystem), ) @@ -141,8 +131,15 @@ impl Plugin for InputPlugin { .register_type::() .register_type::() .register_type::() - .register_type::() - .register_type::() + .register_type::() + .register_type::() + .register_type::() + .register_type::() + .register_type::() + .register_type::() + .register_type::() + .register_type::() + .register_type::() .register_type::() .register_type::() .register_type::(); diff --git a/examples/input/gamepad_input.rs b/examples/input/gamepad_input.rs index e07b43a5c2e27..4f3dfba4ae4d6 100644 --- a/examples/input/gamepad_input.rs +++ b/examples/input/gamepad_input.rs @@ -9,35 +9,22 @@ fn main() { .run(); } -fn gamepad_system( - gamepads: Res, - button_inputs: Res>, - button_axes: Res>, - axes: Res>, -) { - for gamepad in gamepads.iter() { - if button_inputs.just_pressed(GamepadButton::new(gamepad, GamepadButtonType::South)) { - info!("{:?} just pressed South", gamepad); - } else if button_inputs.just_released(GamepadButton::new(gamepad, GamepadButtonType::South)) - { - info!("{:?} just released South", gamepad); +fn gamepad_system(gamepads: Query<(Entity, &Gamepad)>) { + for (entity, gamepad) in &gamepads { + if gamepad.just_pressed(GamepadButton::South) { + info!("{:?} just pressed South", entity); + } else if gamepad.just_released(GamepadButton::South) { + info!("{:?} just released South", entity); } - let right_trigger = button_axes - .get(GamepadButton::new( - gamepad, - GamepadButtonType::RightTrigger2, - )) - .unwrap(); + let right_trigger = gamepad.get(GamepadButton::RightTrigger2).unwrap(); if right_trigger.abs() > 0.01 { - info!("{:?} RightTrigger2 value is {}", gamepad, right_trigger); + info!("{:?} RightTrigger2 value is {}", entity, right_trigger); } - let left_stick_x = axes - .get(GamepadAxis::new(gamepad, GamepadAxisType::LeftStickX)) - .unwrap(); + let left_stick_x = gamepad.get(GamepadAxis::LeftStickX).unwrap(); if left_stick_x.abs() > 0.01 { - info!("{:?} LeftStickX value is {}", gamepad, left_stick_x); + info!("{:?} LeftStickX value is {}", entity, left_stick_x); } } } diff --git a/examples/input/gamepad_input_events.rs b/examples/input/gamepad_input_events.rs index db1e8fc04d773..4986b98751de9 100644 --- a/examples/input/gamepad_input_events.rs +++ b/examples/input/gamepad_input_events.rs @@ -2,7 +2,7 @@ use bevy::{ input::gamepad::{ - GamepadAxisChangedEvent, GamepadButtonChangedEvent, GamepadButtonInput, + GamepadAxisChangedEvent, GamepadButtonChangedEvent, GamepadButtonStateChangedEvent, GamepadConnectionEvent, GamepadEvent, }, prelude::*, @@ -17,15 +17,14 @@ fn main() { fn gamepad_events( mut connection_events: EventReader, + // Handles the continuous measure of an axis, equivalent to GamepadAxes::get. mut axis_changed_events: EventReader, - // Handles the continuous measure of how far a button has been pressed down, as measured - // by `Axis`. Whenever that value changes, this event is emitted. + // Handles the continuous measure of how far a button has been pressed down, equivalent to `GamepadButtons::get`. mut button_changed_events: EventReader, // Handles the boolean measure of whether a button is considered pressed or unpressed, as - // defined by the thresholds in `GamepadSettings::button_settings` and measured by - // `Input`. When the threshold is crossed and the button state changes, - // this event is emitted. - mut button_input_events: EventReader, + // defined by the thresholds in `GamepadSettings::button_settings`. + // When the threshold is crossed and the button state changes, this event is emitted. + mut button_input_events: EventReader, ) { for connection_event in connection_events.read() { info!("{:?}", connection_event); @@ -33,15 +32,13 @@ fn gamepad_events( for axis_changed_event in axis_changed_events.read() { info!( "{:?} of {:?} is changed to {}", - axis_changed_event.axis_type, axis_changed_event.gamepad, axis_changed_event.value + axis_changed_event.axis, axis_changed_event.entity, axis_changed_event.value ); } for button_changed_event in button_changed_events.read() { info!( "{:?} of {:?} is changed to {}", - button_changed_event.button_type, - button_changed_event.gamepad, - button_changed_event.value + button_changed_event.button, button_changed_event.entity, button_changed_event.value ); } for button_input_event in button_input_events.read() { diff --git a/examples/input/gamepad_rumble.rs b/examples/input/gamepad_rumble.rs index a4d1ca614ba81..cdc5a9c85ede4 100644 --- a/examples/input/gamepad_rumble.rs +++ b/examples/input/gamepad_rumble.rs @@ -2,7 +2,7 @@ //! pressed. use bevy::{ - input::gamepad::{GamepadRumbleIntensity, GamepadRumbleRequest}, + input::gamepad::{Gamepad, GamepadRumbleIntensity, GamepadRumbleRequest}, prelude::*, utils::Duration, }; @@ -15,51 +15,43 @@ fn main() { } fn gamepad_system( - gamepads: Res, - button_inputs: Res>, + gamepads: Query<(Entity, &Gamepad)>, mut rumble_requests: EventWriter, ) { - for gamepad in gamepads.iter() { - let button_pressed = |button| { - button_inputs.just_pressed(GamepadButton { - gamepad, - button_type: button, - }) - }; - - if button_pressed(GamepadButtonType::North) { + for (entity, gamepad) in &gamepads { + if gamepad.just_pressed(GamepadButton::North) { info!( "North face button: strong (low-frequency) with low intensity for rumble for 5 seconds. Press multiple times to increase intensity." ); rumble_requests.send(GamepadRumbleRequest::Add { - gamepad, + gamepad: entity, intensity: GamepadRumbleIntensity::strong_motor(0.1), duration: Duration::from_secs(5), }); } - if button_pressed(GamepadButtonType::East) { + if gamepad.just_pressed(GamepadButton::East) { info!("East face button: maximum rumble on both motors for 5 seconds"); rumble_requests.send(GamepadRumbleRequest::Add { - gamepad, + gamepad: entity, duration: Duration::from_secs(5), intensity: GamepadRumbleIntensity::MAX, }); } - if button_pressed(GamepadButtonType::South) { + if gamepad.just_pressed(GamepadButton::South) { info!("South face button: low-intensity rumble on the weak motor for 0.5 seconds"); rumble_requests.send(GamepadRumbleRequest::Add { - gamepad, + gamepad: entity, duration: Duration::from_secs_f32(0.5), intensity: GamepadRumbleIntensity::weak_motor(0.25), }); } - if button_pressed(GamepadButtonType::West) { + if gamepad.just_pressed(GamepadButton::West) { info!("West face button: custom rumble intensity for 5 second"); rumble_requests.send(GamepadRumbleRequest::Add { - gamepad, + gamepad: entity, intensity: GamepadRumbleIntensity { // intensity low-frequency motor, usually on the left-hand side strong_motor: 0.5, @@ -70,9 +62,9 @@ fn gamepad_system( }); } - if button_pressed(GamepadButtonType::Start) { + if gamepad.just_pressed(GamepadButton::Start) { info!("Start button: Interrupt the current rumble"); - rumble_requests.send(GamepadRumbleRequest::Stop { gamepad }); + rumble_requests.send(GamepadRumbleRequest::Stop { gamepad: entity }); } } } diff --git a/examples/tools/gamepad_viewer.rs b/examples/tools/gamepad_viewer.rs index 7be76fe50a6ad..2689195565b14 100644 --- a/examples/tools/gamepad_viewer.rs +++ b/examples/tools/gamepad_viewer.rs @@ -3,7 +3,7 @@ use std::f32::consts::PI; use bevy::{ - input::gamepad::{GamepadAxisChangedEvent, GamepadButtonChangedEvent, GamepadSettings}, + input::gamepad::{GamepadAxisChangedEvent, GamepadButtonChangedEvent, GamepadConnectionEvent}, prelude::*, sprite::{Anchor, MaterialMesh2dBundle, Mesh2dHandle}, }; @@ -25,20 +25,20 @@ const LIVE_COLOR: Color = Color::srgb(0.4, 0.4, 0.4); const DEAD_COLOR: Color = Color::srgb(0.13, 0.13, 0.13); #[derive(Component, Deref)] -struct ReactTo(GamepadButtonType); +struct ReactTo(GamepadButton); #[derive(Component)] struct MoveWithAxes { - x_axis: GamepadAxisType, - y_axis: GamepadAxisType, + x_axis: GamepadAxis, + y_axis: GamepadAxis, scale: f32, } #[derive(Component)] struct TextWithAxes { - x_axis: GamepadAxisType, - y_axis: GamepadAxisType, + x_axis: GamepadAxis, + y_axis: GamepadAxis, } #[derive(Component, Deref)] -struct TextWithButtonValue(GamepadButtonType); +struct TextWithButtonValue(GamepadButton); #[derive(Component)] struct ConnectedGamepadsText; @@ -84,7 +84,7 @@ struct GamepadButtonBundle { impl GamepadButtonBundle { pub fn new( - button_type: GamepadButtonType, + button_type: GamepadButton, mesh: Mesh2dHandle, material: Handle, x: f32, @@ -140,28 +140,28 @@ fn setup(mut commands: Commands, meshes: Res, materials: Res, materials: Res, materials: Res, materials: Res, materials: Res, materials: Res, materials: Res, materials: Res, materials: Res, materials: Res, - gamepad_settings: Res, ) { + // NOTE: This stops making sense because in entities because there isn't a "global" default, + // instead each gamepad has its own default setting + let gamepad_settings = GamepadSettings::default(); let dead_upper = STICK_BOUNDS_SIZE * gamepad_settings.default_axis_settings.deadzone_upperbound(); let dead_lower = @@ -358,16 +360,16 @@ fn setup_sticks( spawn_stick( -STICKS_X, STICKS_Y, - GamepadAxisType::LeftStickX, - GamepadAxisType::LeftStickY, - GamepadButtonType::LeftThumb, + GamepadAxis::LeftStickX, + GamepadAxis::LeftStickY, + GamepadButton::LeftThumb, ); spawn_stick( STICKS_X, STICKS_Y, - GamepadAxisType::RightStickX, - GamepadAxisType::RightStickY, - GamepadButtonType::RightThumb, + GamepadAxis::RightStickX, + GamepadAxis::RightStickY, + GamepadButton::RightThumb, ); } @@ -403,16 +405,8 @@ fn setup_triggers( }); }; - spawn_trigger( - -BUTTONS_X, - BUTTONS_Y + 145., - GamepadButtonType::LeftTrigger2, - ); - spawn_trigger( - BUTTONS_X, - BUTTONS_Y + 145., - GamepadButtonType::RightTrigger2, - ); + spawn_trigger(-BUTTONS_X, BUTTONS_Y + 145., GamepadButton::LeftTrigger2); + spawn_trigger(BUTTONS_X, BUTTONS_Y + 145., GamepadButton::RightTrigger2); } fn setup_connected(mut commands: Commands) { @@ -443,30 +437,28 @@ fn setup_connected(mut commands: Commands) { } fn update_buttons( - gamepads: Res, - button_inputs: Res>, + gamepads: Query<&Gamepad>, materials: Res, mut query: Query<(&mut Handle, &ReactTo)>, ) { - for gamepad in gamepads.iter() { + for buttons in &gamepads { for (mut handle, react_to) in query.iter_mut() { - if button_inputs.just_pressed(GamepadButton::new(gamepad, **react_to)) { + if buttons.just_pressed(**react_to) { *handle = materials.active.clone(); } - if button_inputs.just_released(GamepadButton::new(gamepad, **react_to)) { + if buttons.just_released(**react_to) { *handle = materials.normal.clone(); } } } } - fn update_button_values( mut events: EventReader, mut query: Query<(&mut Text, &TextWithButtonValue)>, ) { for button_event in events.read() { for (mut text, text_with_button_value) in query.iter_mut() { - if button_event.button_type == **text_with_button_value { + if button_event.button == **text_with_button_value { text.sections[0].value = format!("{:.3}", button_event.value); } } @@ -479,7 +471,7 @@ fn update_axes( mut text_query: Query<(&mut Text, &TextWithAxes)>, ) { for axis_event in axis_events.read() { - let axis_type = axis_event.axis_type; + let axis_type = axis_event.axis; let value = axis_event.value; for (mut transform, move_with) in query.iter_mut() { if axis_type == move_with.x_axis { @@ -501,18 +493,19 @@ fn update_axes( } fn update_connected( - gamepads: Res, + mut connected: EventReader, + gamepads: Query<(Entity, &Gamepad)>, mut query: Query<&mut Text, With>, ) { - if !gamepads.is_changed() { + if connected.is_empty() { return; } - + connected.clear(); let mut text = query.single_mut(); let formatted = gamepads .iter() - .map(|g| format!("- {}", gamepads.name(g).unwrap())) + .map(|(entity, gamepad)| format!("{} - {}", entity, gamepad.name())) .collect::>() .join("\n"); From 60cf7ca0257d1e26419c38999a350ae9933d78b7 Mon Sep 17 00:00:00 2001 From: Liam Gallagher Date: Sat, 28 Sep 2024 08:09:46 +1200 Subject: [PATCH 14/17] Refactor BRP to allow for 3rd-party transports (#15438) ## Objective Closes #15408 (somewhat) ## Solution - Moved the existing HTTP transport to its own module with its own plugin (`RemoteHttpPlugin`) (disabled on WASM) - Swapped out the `smol` crate for the smaller crates it re-exports to make it easier to keep out non-wasm code (HTTP transport needs `async-io` which can't build on WASM) - Added a new public `BrpSender` resource holding the matching sender for the `BrpReceiver`' (formally `BrpMailbox`). This allows other crates to send `BrpMessage`'s to the "mailbox". ## Testing TODO --------- Co-authored-by: Matty --- crates/bevy_remote/Cargo.toml | 3 +- crates/bevy_remote/src/http.rs | 246 +++++++++++++++++++++++++++++++ crates/bevy_remote/src/lib.rs | 259 ++++----------------------------- examples/remote/client.rs | 4 +- examples/remote/server.rs | 6 +- 5 files changed, 285 insertions(+), 233 deletions(-) create mode 100644 crates/bevy_remote/src/http.rs diff --git a/crates/bevy_remote/Cargo.toml b/crates/bevy_remote/Cargo.toml index 7b6a199dad125..471cfe3536c64 100644 --- a/crates/bevy_remote/Cargo.toml +++ b/crates/bevy_remote/Cargo.toml @@ -27,10 +27,11 @@ hyper = { version = "1", features = ["server", "http1"] } serde = { version = "1", features = ["derive"] } serde_json = { version = "1" } http-body-util = "0.1" +async-channel = "2" # dependencies that will not compile on wasm [target.'cfg(not(target_family = "wasm"))'.dependencies] -smol = "2" +async-io = "2" smol-hyper = "0.1" [lints] diff --git a/crates/bevy_remote/src/http.rs b/crates/bevy_remote/src/http.rs new file mode 100644 index 0000000000000..e05c2978104f2 --- /dev/null +++ b/crates/bevy_remote/src/http.rs @@ -0,0 +1,246 @@ +//! The BRP transport using JSON-RPC over HTTP. +//! +//! Adding the [`RemoteHttpPlugin`] to your [`App`] causes Bevy to accept +//! connections over HTTP (by default, on port 15702) while your app is running. +//! +//! Clients are expected to `POST` JSON requests to the root URL; see the `client` +//! example for a trivial example of use. + +#![cfg(not(target_family = "wasm"))] + +use crate::{error_codes, BrpBatch, BrpError, BrpMessage, BrpRequest, BrpResponse, BrpSender}; +use anyhow::Result as AnyhowResult; +use async_channel::Sender; +use async_io::Async; +use bevy_app::{App, Plugin, Startup}; +use bevy_ecs::system::{Res, Resource}; +use bevy_tasks::IoTaskPool; +use core::net::{IpAddr, Ipv4Addr}; +use http_body_util::{BodyExt as _, Full}; +use hyper::{ + body::{Bytes, Incoming}, + server::conn::http1, + service, Request, Response, +}; +use serde_json::Value; +use smol_hyper::rt::{FuturesIo, SmolTimer}; +use std::net::TcpListener; +use std::net::TcpStream; + +/// The default port that Bevy will listen on. +/// +/// This value was chosen randomly. +pub const DEFAULT_PORT: u16 = 15702; + +/// The default host address that Bevy will use for its server. +pub const DEFAULT_ADDR: IpAddr = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)); + +/// Add this plugin to your [`App`] to allow remote connections over HTTP to inspect and modify entities. +/// It requires the [`RemotePlugin`](super::RemotePlugin). +/// +/// This BRP transport cannot be used when targeting WASM. +/// +/// The defaults are: +/// - [`DEFAULT_ADDR`] : 127.0.0.1. +/// - [`DEFAULT_PORT`] : 15702. +pub struct RemoteHttpPlugin { + /// The address that Bevy will bind to. + address: IpAddr, + /// The port that Bevy will listen on. + port: u16, +} + +impl Default for RemoteHttpPlugin { + fn default() -> Self { + Self { + address: DEFAULT_ADDR, + port: DEFAULT_PORT, + } + } +} + +impl Plugin for RemoteHttpPlugin { + fn build(&self, app: &mut App) { + app.insert_resource(HostAddress(self.address)) + .insert_resource(HostPort(self.port)) + .add_systems(Startup, start_http_server); + } +} + +impl RemoteHttpPlugin { + /// Set the IP address that the server will use. + #[must_use] + pub fn with_address(mut self, address: impl Into) -> Self { + self.address = address.into(); + self + } + + /// Set the remote port that the server will listen on. + #[must_use] + pub fn with_port(mut self, port: u16) -> Self { + self.port = port; + self + } +} + +/// A resource containing the IP address that Bevy will host on. +/// +/// Currently, changing this while the application is running has no effect; this merely +/// reflects the IP address that is set during the setup of the [`RemoteHttpPlugin`]. +#[derive(Debug, Resource)] +pub struct HostAddress(pub IpAddr); + +/// A resource containing the port number that Bevy will listen on. +/// +/// Currently, changing this while the application is running has no effect; this merely +/// reflects the host that is set during the setup of the [`RemoteHttpPlugin`]. +#[derive(Debug, Resource)] +pub struct HostPort(pub u16); + +/// A system that starts up the Bevy Remote Protocol HTTP server. +fn start_http_server( + request_sender: Res, + address: Res, + remote_port: Res, +) { + IoTaskPool::get() + .spawn(server_main( + address.0, + remote_port.0, + request_sender.clone(), + )) + .detach(); +} + +/// The Bevy Remote Protocol server main loop. +async fn server_main( + address: IpAddr, + port: u16, + request_sender: Sender, +) -> AnyhowResult<()> { + listen( + Async::::bind((address, port))?, + &request_sender, + ) + .await +} + +async fn listen( + listener: Async, + request_sender: &Sender, +) -> AnyhowResult<()> { + loop { + let (client, _) = listener.accept().await?; + + let request_sender = request_sender.clone(); + IoTaskPool::get() + .spawn(async move { + let _ = handle_client(client, request_sender).await; + }) + .detach(); + } +} + +async fn handle_client( + client: Async, + request_sender: Sender, +) -> AnyhowResult<()> { + http1::Builder::new() + .timer(SmolTimer::new()) + .serve_connection( + FuturesIo::new(client), + service::service_fn(|request| process_request_batch(request, &request_sender)), + ) + .await?; + + Ok(()) +} + +/// A helper function for the Bevy Remote Protocol server that handles a batch +/// of requests coming from a client. +async fn process_request_batch( + request: Request, + request_sender: &Sender, +) -> AnyhowResult>> { + let batch_bytes = request.into_body().collect().await?.to_bytes(); + let batch: Result = serde_json::from_slice(&batch_bytes); + + let serialized = match batch { + Ok(BrpBatch::Single(request)) => { + serde_json::to_string(&process_single_request(request, request_sender).await?)? + } + Ok(BrpBatch::Batch(requests)) => { + let mut responses = Vec::new(); + + for request in requests { + responses.push(process_single_request(request, request_sender).await?); + } + + serde_json::to_string(&responses)? + } + Err(err) => { + let err = BrpResponse::new( + None, + Err(BrpError { + code: error_codes::INVALID_REQUEST, + message: err.to_string(), + data: None, + }), + ); + + serde_json::to_string(&err)? + } + }; + + Ok(Response::new(Full::new(Bytes::from( + serialized.as_bytes().to_owned(), + )))) +} + +/// A helper function for the Bevy Remote Protocol server that processes a single +/// request coming from a client. +async fn process_single_request( + request: Value, + request_sender: &Sender, +) -> AnyhowResult { + // Reach in and get the request ID early so that we can report it even when parsing fails. + let id = request.as_object().and_then(|map| map.get("id")).cloned(); + + let request: BrpRequest = match serde_json::from_value(request) { + Ok(v) => v, + Err(err) => { + return Ok(BrpResponse::new( + id, + Err(BrpError { + code: error_codes::INVALID_REQUEST, + message: err.to_string(), + data: None, + }), + )); + } + }; + + if request.jsonrpc != "2.0" { + return Ok(BrpResponse::new( + id, + Err(BrpError { + code: error_codes::INVALID_REQUEST, + message: String::from("JSON-RPC request requires `\"jsonrpc\": \"2.0\"`"), + data: None, + }), + )); + } + + let (result_sender, result_receiver) = async_channel::bounded(1); + + let _ = request_sender + .send(BrpMessage { + method: request.method, + params: request.params, + sender: result_sender, + }) + .await; + + let result = result_receiver.recv().await?; + Ok(BrpResponse::new(request.id, result)) +} diff --git a/crates/bevy_remote/src/lib.rs b/crates/bevy_remote/src/lib.rs index 581d9752fbec1..8f11a18adb041 100644 --- a/crates/bevy_remote/src/lib.rs +++ b/crates/bevy_remote/src/lib.rs @@ -1,11 +1,10 @@ -//! An implementation of the Bevy Remote Protocol over HTTP and JSON, to allow -//! for remote control of a Bevy app. +//! An implementation of the Bevy Remote Protocol, to allow for remote control of a Bevy app. //! -//! Adding the [`RemotePlugin`] to your [`App`] causes Bevy to accept -//! connections over HTTP (by default, on port 15702) while your app is running. -//! These *remote clients* can inspect and alter the state of the -//! entity-component system. Clients are expected to `POST` JSON requests to the -//! root URL; see the `client` example for a trivial example of use. +//! Adding the [`RemotePlugin`] to your [`App`] will setup everything needed without +//! starting any transports. To start accepting remote connections you will need to +//! add a second plugin like the [`RemoteHttpPlugin`](http::RemoteHttpPlugin) to enable communication +//! over HTTP. These *remote clients* can inspect and alter the state of the +//! entity-component system. //! //! The Bevy Remote Protocol is based on the JSON-RPC 2.0 protocol. //! @@ -245,66 +244,31 @@ //! [fully-qualified type names]: bevy_reflect::TypePath::type_path //! [fully-qualified type name]: bevy_reflect::TypePath::type_path -#![cfg(not(target_family = "wasm"))] - -use core::net::{IpAddr, Ipv4Addr}; -use std::sync::RwLock; - -use anyhow::Result as AnyhowResult; +use async_channel::{Receiver, Sender}; use bevy_app::prelude::*; use bevy_derive::{Deref, DerefMut}; use bevy_ecs::{ entity::Entity, - system::{Commands, In, IntoSystem, Res, Resource, System, SystemId}, + system::{Commands, In, IntoSystem, Resource, System, SystemId}, world::World, }; -use bevy_reflect::Reflect; -use bevy_tasks::IoTaskPool; use bevy_utils::{prelude::default, HashMap}; -use http_body_util::{BodyExt as _, Full}; -use hyper::{ - body::{Bytes, Incoming}, - server::conn::http1, - service, Request, Response, -}; use serde::{Deserialize, Serialize}; use serde_json::Value; -use smol::{ - channel::{self, Receiver, Sender}, - Async, -}; -use smol_hyper::rt::{FuturesIo, SmolTimer}; -use std::net::{TcpListener, TcpStream}; +use std::sync::RwLock; pub mod builtin_methods; - -/// The default port that Bevy will listen on. -/// -/// This value was chosen randomly. -pub const DEFAULT_PORT: u16 = 15702; - -/// The default host address that Bevy will use for its server. -pub const DEFAULT_ADDR: IpAddr = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)); +pub mod http; const CHANNEL_SIZE: usize = 16; /// Add this plugin to your [`App`] to allow remote connections to inspect and modify entities. /// /// This the main plugin for `bevy_remote`. See the [crate-level documentation] for details on -/// the protocol and its default methods. -/// -/// The defaults are: -/// - [`DEFAULT_ADDR`] : 127.0.0.1. -/// - [`DEFAULT_PORT`] : 15702. +/// the available protocols and its default methods. /// /// [crate-level documentation]: crate pub struct RemotePlugin { - /// The address that Bevy will use. - address: IpAddr, - - /// The port that Bevy will listen on. - port: u16, - /// The verbs that the server will recognize and respond to. methods: RwLock< Vec<( @@ -319,26 +283,10 @@ impl RemotePlugin { /// any associated methods. fn empty() -> Self { Self { - address: DEFAULT_ADDR, - port: DEFAULT_PORT, methods: RwLock::new(vec![]), } } - /// Set the IP address that the server will use. - #[must_use] - pub fn with_address(mut self, address: impl Into) -> Self { - self.address = address.into(); - self - } - - /// Set the remote port that the server will listen on. - #[must_use] - pub fn with_port(mut self, port: u16) -> Self { - self.port = port; - self - } - /// Add a remote method to the plugin using the given `name` and `handler`. #[must_use] pub fn with_method( @@ -403,28 +351,12 @@ impl Plugin for RemotePlugin { ); } - app.insert_resource(HostAddress(self.address)) - .insert_resource(HostPort(self.port)) - .insert_resource(remote_methods) - .add_systems(Startup, start_server) + app.insert_resource(remote_methods) + .add_systems(PreStartup, setup_mailbox_channel) .add_systems(Update, process_remote_requests); } } -/// A resource containing the IP address that Bevy will host on. -/// -/// Currently, changing this while the application is running has no effect; this merely -/// reflects the IP address that is set during the setup of the [`RemotePlugin`]. -#[derive(Debug, Resource)] -pub struct HostAddress(pub IpAddr); - -/// A resource containing the port number that Bevy will listen on. -/// -/// Currently, changing this while the application is running has no effect; this merely -/// reflects the host that is set during the setup of the [`RemotePlugin`]. -#[derive(Debug, Resource, Reflect)] -pub struct HostPort(pub u16); - /// The type of a function that implements a remote method (`bevy/get`, `bevy/query`, etc.) /// /// The first parameter is the JSON value of the `params`. Typically, an @@ -658,7 +590,7 @@ pub enum BrpBatch { /// A message from the Bevy Remote Protocol server thread to the main world. /// -/// This is placed in the [`BrpMailbox`]. +/// This is placed in the [`BrpReceiver`]. #[derive(Debug, Clone)] pub struct BrpMessage { /// The request method. @@ -673,41 +605,41 @@ pub struct BrpMessage { pub sender: Sender, } +/// A resource holding the matching sender for the [`BrpReceiver`]'s receiver. +#[derive(Debug, Resource, Deref, DerefMut)] +pub struct BrpSender(Sender); + /// A resource that receives messages sent by Bevy Remote Protocol clients. /// /// Every frame, the `process_remote_requests` system drains this mailbox and /// processes the messages within. #[derive(Debug, Resource, Deref, DerefMut)] -pub struct BrpMailbox(Receiver); +pub struct BrpReceiver(Receiver); -/// A system that starts up the Bevy Remote Protocol server. -fn start_server(mut commands: Commands, address: Res, remote_port: Res) { +fn setup_mailbox_channel(mut commands: Commands) { // Create the channel and the mailbox. - let (request_sender, request_receiver) = channel::bounded(CHANNEL_SIZE); - commands.insert_resource(BrpMailbox(request_receiver)); - - IoTaskPool::get() - .spawn(server_main(address.0, remote_port.0, request_sender)) - .detach(); + let (request_sender, request_receiver) = async_channel::bounded(CHANNEL_SIZE); + commands.insert_resource(BrpSender(request_sender)); + commands.insert_resource(BrpReceiver(request_receiver)); } -/// A system that receives requests placed in the [`BrpMailbox`] and processes +/// A system that receives requests placed in the [`BrpReceiver`] and processes /// them, using the [`RemoteMethods`] resource to map each request to its handler. /// /// This needs exclusive access to the [`World`] because clients can manipulate /// anything in the ECS. fn process_remote_requests(world: &mut World) { - if !world.contains_resource::() { + if !world.contains_resource::() { return; } - while let Ok(message) = world.resource_mut::().try_recv() { + while let Ok(message) = world.resource_mut::().try_recv() { // Fetch the handler for the method. If there's no such handler // registered, return an error. let methods = world.resource::(); let Some(handler) = methods.0.get(&message.method) else { - let _ = message.sender.send_blocking(Err(BrpError { + let _ = message.sender.force_send(Err(BrpError { code: error_codes::METHOD_NOT_FOUND, message: format!("Method `{}` not found", message.method), data: None, @@ -719,7 +651,7 @@ fn process_remote_requests(world: &mut World) { let result = match world.run_system_with_input(*handler, message.params) { Ok(result) => result, Err(error) => { - let _ = message.sender.send_blocking(Err(BrpError { + let _ = message.sender.force_send(Err(BrpError { code: error_codes::INTERNAL_ERROR, message: format!("Failed to run method handler: {error}"), data: None, @@ -728,139 +660,6 @@ fn process_remote_requests(world: &mut World) { } }; - let _ = message.sender.send_blocking(result); + let _ = message.sender.force_send(result); } } - -/// The Bevy Remote Protocol server main loop. -async fn server_main( - address: IpAddr, - port: u16, - request_sender: Sender, -) -> AnyhowResult<()> { - listen( - Async::::bind((address, port))?, - &request_sender, - ) - .await -} - -async fn listen( - listener: Async, - request_sender: &Sender, -) -> AnyhowResult<()> { - loop { - let (client, _) = listener.accept().await?; - - let request_sender = request_sender.clone(); - IoTaskPool::get() - .spawn(async move { - let _ = handle_client(client, request_sender).await; - }) - .detach(); - } -} - -async fn handle_client( - client: Async, - request_sender: Sender, -) -> AnyhowResult<()> { - http1::Builder::new() - .timer(SmolTimer::new()) - .serve_connection( - FuturesIo::new(client), - service::service_fn(|request| process_request_batch(request, &request_sender)), - ) - .await?; - - Ok(()) -} - -/// A helper function for the Bevy Remote Protocol server that handles a batch -/// of requests coming from a client. -async fn process_request_batch( - request: Request, - request_sender: &Sender, -) -> AnyhowResult>> { - let batch_bytes = request.into_body().collect().await?.to_bytes(); - let batch: Result = serde_json::from_slice(&batch_bytes); - - let serialized = match batch { - Ok(BrpBatch::Single(request)) => { - serde_json::to_string(&process_single_request(request, request_sender).await?)? - } - Ok(BrpBatch::Batch(requests)) => { - let mut responses = Vec::new(); - - for request in requests { - responses.push(process_single_request(request, request_sender).await?); - } - - serde_json::to_string(&responses)? - } - Err(err) => { - let err = BrpResponse::new( - None, - Err(BrpError { - code: error_codes::INVALID_REQUEST, - message: err.to_string(), - data: None, - }), - ); - - serde_json::to_string(&err)? - } - }; - - Ok(Response::new(Full::new(Bytes::from( - serialized.as_bytes().to_owned(), - )))) -} - -/// A helper function for the Bevy Remote Protocol server that processes a single -/// request coming from a client. -async fn process_single_request( - request: Value, - request_sender: &Sender, -) -> AnyhowResult { - // Reach in and get the request ID early so that we can report it even when parsing fails. - let id = request.as_object().and_then(|map| map.get("id")).cloned(); - - let request: BrpRequest = match serde_json::from_value(request) { - Ok(v) => v, - Err(err) => { - return Ok(BrpResponse::new( - id, - Err(BrpError { - code: error_codes::INVALID_REQUEST, - message: err.to_string(), - data: None, - }), - )); - } - }; - - if request.jsonrpc != "2.0" { - return Ok(BrpResponse::new( - id, - Err(BrpError { - code: error_codes::INVALID_REQUEST, - message: String::from("JSON-RPC request requires `\"jsonrpc\": \"2.0\"`"), - data: None, - }), - )); - } - - let (result_sender, result_receiver) = channel::bounded(1); - - let _ = request_sender - .send(BrpMessage { - method: request.method, - params: request.params, - sender: result_sender, - }) - .await; - - let result = result_receiver.recv().await?; - Ok(BrpResponse::new(request.id, result)) -} diff --git a/examples/remote/client.rs b/examples/remote/client.rs index bf684b6471f40..7794aec0525f1 100644 --- a/examples/remote/client.rs +++ b/examples/remote/client.rs @@ -5,7 +5,9 @@ use anyhow::Result as AnyhowResult; use argh::FromArgs; use bevy::remote::{ builtin_methods::{BrpQuery, BrpQueryFilter, BrpQueryParams, BRP_QUERY_METHOD}, - BrpRequest, DEFAULT_ADDR, DEFAULT_PORT, + http::DEFAULT_ADDR, + http::DEFAULT_PORT, + BrpRequest, }; /// Struct containing the command-line arguments that can be passed to this example. diff --git a/examples/remote/server.rs b/examples/remote/server.rs index c829de9472905..bab8cacf4cd2d 100644 --- a/examples/remote/server.rs +++ b/examples/remote/server.rs @@ -1,12 +1,16 @@ //! A Bevy app that you can connect to with the BRP and edit. -use bevy::{prelude::*, remote::RemotePlugin}; +use bevy::{ + prelude::*, + remote::{http::RemoteHttpPlugin, RemotePlugin}, +}; use serde::{Deserialize, Serialize}; fn main() { App::new() .add_plugins(DefaultPlugins) .add_plugins(RemotePlugin::default()) + .add_plugins(RemoteHttpPlugin::default()) .add_systems(Startup, setup) .register_type::() .run(); From 6963b58eba4fa7d8cc73389f57699ed31a8216d4 Mon Sep 17 00:00:00 2001 From: Zachary Harrold Date: Sat, 28 Sep 2024 06:23:26 +1000 Subject: [PATCH 15/17] Modify `derive_label` to support `no_std` environments (#15465) # Objective - Contributes to #15460 ## Solution - Wrap `derive_label` `quote!` in an anonymous constant which contains an `extern crate alloc` statement, allowing use of the `alloc` namespace even when a user has not brought in the crate themselves. ## Testing - CI passed locally. ## Notes We can't generate code that uses `::std::boxed::Box` in `no_std` environments, but we also can't rely on `::alloc::boxed::Box` either, since the user might not have declared `extern crate alloc`. To resolve this, the generated code is wrapped in an anonymous constant which contains the `extern crate alloc` invocation. This does mean the macro is no longer hygienic against cases where the user provides an alternate `alloc` crate, however I believe this is an acceptable compromise. Additionally, this crate itself doesn't need to be `no_std`, it just needs to _generate_ `no_std` compatible code. --------- Co-authored-by: Alice Cecile --- crates/bevy_macro_utils/src/label.rs | 29 ++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/crates/bevy_macro_utils/src/label.rs b/crates/bevy_macro_utils/src/label.rs index 6eec83c04c6bb..1fc540c9c4ea3 100644 --- a/crates/bevy_macro_utils/src/label.rs +++ b/crates/bevy_macro_utils/src/label.rs @@ -81,21 +81,26 @@ pub fn derive_label( .unwrap(), ); quote! { - impl #impl_generics #trait_path for #ident #ty_generics #where_clause { - fn dyn_clone(&self) -> ::std::boxed::Box { - ::std::boxed::Box::new(::core::clone::Clone::clone(self)) - } + // To ensure alloc is available, but also prevent its name from clashing, we place the implementation inside an anonymous constant + const _: () = { + extern crate alloc; - fn as_dyn_eq(&self) -> &dyn #dyn_eq_path { - self - } + impl #impl_generics #trait_path for #ident #ty_generics #where_clause { + fn dyn_clone(&self) -> alloc::boxed::Box { + alloc::boxed::Box::new(::core::clone::Clone::clone(self)) + } - fn dyn_hash(&self, mut state: &mut dyn ::core::hash::Hasher) { - let ty_id = ::core::any::TypeId::of::(); - ::core::hash::Hash::hash(&ty_id, &mut state); - ::core::hash::Hash::hash(self, &mut state); + fn as_dyn_eq(&self) -> &dyn #dyn_eq_path { + self + } + + fn dyn_hash(&self, mut state: &mut dyn ::core::hash::Hasher) { + let ty_id = ::core::any::TypeId::of::(); + ::core::hash::Hash::hash(&ty_id, &mut state); + ::core::hash::Hash::hash(self, &mut state); + } } - } + }; } .into() } From 9b4d2de215d7207b5b4729370fe44e9ccc40ee72 Mon Sep 17 00:00:00 2001 From: Benjamin Brienen Date: Sat, 28 Sep 2024 00:20:41 +0200 Subject: [PATCH 16/17] Fix out of date template and grammar (#15483) # Objective A label was renamed, so this updates it in the issue template. ## Solution Change in the .github markdown. --- .github/ISSUE_TEMPLATE/docs_improvement.md | 2 +- .github/ISSUE_TEMPLATE/feature_request.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/docs_improvement.md b/.github/ISSUE_TEMPLATE/docs_improvement.md index 1bae3c9cf634c..f2dc170a8185f 100644 --- a/.github/ISSUE_TEMPLATE/docs_improvement.md +++ b/.github/ISSUE_TEMPLATE/docs_improvement.md @@ -10,4 +10,4 @@ assignees: '' Provide a link to the documentation and describe how it could be improved. In what ways is it incomplete, incorrect, or misleading? -If you have suggestions on exactly what the new docs should say, feel free to include them here. Or alternatively, make the changes yourself and [create a pull request](https://bevyengine.org/learn/book/contributing/code/) instead. +If you have suggestions on exactly what the new docs should say, feel free to include them here. Alternatively, make the changes yourself and [create a pull request](https://bevyengine.org/learn/book/contributing/code/) instead. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index cc6e73125dab9..0ac1873eb2c1b 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -2,7 +2,7 @@ name: Feature Request about: Propose a new feature! title: '' -labels: C-Enhancement, S-Needs-Triage +labels: C-Feature, S-Needs-Triage assignees: '' --- From df23b937cc60a81913ee3a06cfa775c4d3014ad2 Mon Sep 17 00:00:00 2001 From: charlotte Date: Fri, 27 Sep 2024 17:00:27 -0700 Subject: [PATCH 17/17] Make `CosmicFontSystem` and `SwashCache` pub resources. (#15479) # Objective In nannou, we'd like to be able to access the [outline commands](https://docs.rs/cosmic-text/latest/cosmic_text/struct.SwashCache.html#method.get_outline_commands) from swash, while still benefit from Bevy's management of font assets. ## Solution Make `CosmicFontSystem` and `SwashCache` pub resources. ## Testing Ran some examples. --- crates/bevy_text/src/lib.rs | 4 ++- crates/bevy_text/src/pipeline.rs | 57 +++++++++++++++++-------------- crates/bevy_text/src/text2d.rs | 13 +++++-- crates/bevy_ui/src/layout/mod.rs | 18 +++++++--- crates/bevy_ui/src/widget/text.rs | 17 +++++++-- 5 files changed, 73 insertions(+), 36 deletions(-) diff --git a/crates/bevy_text/src/lib.rs b/crates/bevy_text/src/lib.rs index 136ee7d7e7be6..ee2c28a8e1166 100644 --- a/crates/bevy_text/src/lib.rs +++ b/crates/bevy_text/src/lib.rs @@ -109,7 +109,9 @@ impl Plugin for TextPlugin { .register_type::() .init_asset_loader::() .init_resource::() - .insert_resource(TextPipeline::default()) + .init_resource::() + .init_resource::() + .init_resource::() .add_systems( PostUpdate, ( diff --git a/crates/bevy_text/src/pipeline.rs b/crates/bevy_text/src/pipeline.rs index 10efe23f748da..c969b9dc2d470 100644 --- a/crates/bevy_text/src/pipeline.rs +++ b/crates/bevy_text/src/pipeline.rs @@ -20,8 +20,13 @@ use crate::{ PositionedGlyph, TextBounds, TextSection, YAxisOrientation, }; -/// A wrapper around a [`cosmic_text::FontSystem`] -struct CosmicFontSystem(cosmic_text::FontSystem); +/// A wrapper resource around a [`cosmic_text::FontSystem`] +/// +/// The font system is used to retrieve fonts and their information, including glyph outlines. +/// +/// This resource is updated by the [`TextPipeline`] resource. +#[derive(Resource)] +pub struct CosmicFontSystem(pub cosmic_text::FontSystem); impl Default for CosmicFontSystem { fn default() -> Self { @@ -32,8 +37,13 @@ impl Default for CosmicFontSystem { } } -/// A wrapper around a [`cosmic_text::SwashCache`] -struct SwashCache(cosmic_text::SwashCache); +/// A wrapper resource around a [`cosmic_text::SwashCache`] +/// +/// The swash cache rasterizer is used to rasterize glyphs +/// +/// This resource is updated by the [`TextPipeline`] resource. +#[derive(Resource)] +pub struct SwashCache(pub cosmic_text::SwashCache); impl Default for SwashCache { fn default() -> Self { @@ -48,14 +58,6 @@ impl Default for SwashCache { pub struct TextPipeline { /// Identifies a font [`ID`](cosmic_text::fontdb::ID) by its [`Font`] [`Asset`](bevy_asset::Asset). map_handle_to_font_id: HashMap, (cosmic_text::fontdb::ID, String)>, - /// The font system is used to retrieve fonts and their information, including glyph outlines. - /// - /// See [`cosmic_text::FontSystem`] for more information. - font_system: CosmicFontSystem, - /// The swash cache rasterizer is used to rasterize glyphs - /// - /// See [`cosmic_text::SwashCache`] for more information. - swash_cache: SwashCache, /// Buffered vec for collecting spans. /// /// See [this dark magic](https://users.rust-lang.org/t/how-to-cache-a-vectors-capacity/94478/10). @@ -76,8 +78,9 @@ impl TextPipeline { scale_factor: f64, buffer: &mut CosmicBuffer, alignment: JustifyText, + font_system: &mut CosmicFontSystem, ) -> Result<(), TextError> { - let font_system = &mut self.font_system.0; + let font_system = &mut font_system.0; // return early if the fonts are not loaded yet let mut font_size = 0.; @@ -188,6 +191,8 @@ impl TextPipeline { textures: &mut Assets, y_axis_orientation: YAxisOrientation, buffer: &mut CosmicBuffer, + font_system: &mut CosmicFontSystem, + swash_cache: &mut SwashCache, ) -> Result<(), TextError> { layout_info.glyphs.clear(); layout_info.size = Default::default(); @@ -204,11 +209,10 @@ impl TextPipeline { scale_factor, buffer, text_alignment, + font_system, )?; let box_size = buffer_dimensions(buffer); - let font_system = &mut self.font_system.0; - let swash_cache = &mut self.swash_cache.0; buffer .layout_runs() @@ -250,8 +254,8 @@ impl TextPipeline { font_atlas_set.add_glyph_to_atlas( texture_atlases, textures, - font_system, - swash_cache, + &mut font_system.0, + &mut swash_cache.0, layout_glyph, font_smoothing, ) @@ -300,6 +304,7 @@ impl TextPipeline { linebreak_behavior: BreakLineOn, buffer: &mut CosmicBuffer, text_alignment: JustifyText, + font_system: &mut CosmicFontSystem, ) -> Result { const MIN_WIDTH_CONTENT_BOUNDS: TextBounds = TextBounds::new_horizontal(0.0); @@ -311,12 +316,13 @@ impl TextPipeline { scale_factor, buffer, text_alignment, + font_system, )?; let min_width_content_size = buffer_dimensions(buffer); let max_width_content_size = { - let font_system = &mut self.font_system.0; + let font_system = &mut font_system.0; buffer.set_size(font_system, None, None); buffer_dimensions(buffer) }; @@ -328,11 +334,12 @@ impl TextPipeline { }) } - /// Get a mutable reference to the [`cosmic_text::FontSystem`]. - /// - /// Used internally. - pub fn font_system_mut(&mut self) -> &mut cosmic_text::FontSystem { - &mut self.font_system.0 + /// Returns the [`cosmic_text::fontdb::ID`] for a given [`Font`] asset. + pub fn get_font_id(&self, asset_id: AssetId) -> Option { + self.map_handle_to_font_id + .get(&asset_id) + .cloned() + .map(|(id, _)| id) } } @@ -442,11 +449,11 @@ fn buffer_dimensions(buffer: &Buffer) -> Vec2 { } /// Discards stale data cached in `FontSystem`. -pub(crate) fn trim_cosmic_cache(mut pipeline: ResMut) { +pub(crate) fn trim_cosmic_cache(mut font_system: ResMut) { // A trim age of 2 was found to reduce frame time variance vs age of 1 when tested with dynamic text. // See https://github.com/bevyengine/bevy/pull/15037 // // We assume only text updated frequently benefits from the shape cache (e.g. animated text, or // text that is dynamically measured for UI). - pipeline.font_system_mut().shape_run_cache.trim(2); + font_system.0.shape_run_cache.trim(2); } diff --git a/crates/bevy_text/src/text2d.rs b/crates/bevy_text/src/text2d.rs index c514cabae3af4..5b84c0c4a8f84 100644 --- a/crates/bevy_text/src/text2d.rs +++ b/crates/bevy_text/src/text2d.rs @@ -1,6 +1,7 @@ +use crate::pipeline::CosmicFontSystem; use crate::{ - BreakLineOn, CosmicBuffer, Font, FontAtlasSets, PositionedGlyph, Text, TextBounds, TextError, - TextLayoutInfo, TextPipeline, YAxisOrientation, + BreakLineOn, CosmicBuffer, Font, FontAtlasSets, PositionedGlyph, SwashCache, Text, TextBounds, + TextError, TextLayoutInfo, TextPipeline, YAxisOrientation, }; use bevy_asset::Assets; use bevy_color::LinearRgba; @@ -158,6 +159,8 @@ pub fn update_text2d_layout( &mut TextLayoutInfo, &mut CosmicBuffer, )>, + mut font_system: ResMut, + mut swash_cache: ResMut, ) { // We need to consume the entire iterator, hence `last` let factor_changed = scale_factor_changed.read().last().is_some(); @@ -198,6 +201,8 @@ pub fn update_text2d_layout( &mut textures, YAxisOrientation::BottomToTop, buffer.as_mut(), + &mut font_system, + &mut swash_cache, ) { Err(TextError::NoSuchFont) => { // There was an error processing the text layout, let's add this entity to the @@ -274,7 +279,9 @@ mod tests { .init_resource::>() .init_resource::() .init_resource::>() - .insert_resource(TextPipeline::default()) + .init_resource::() + .init_resource::() + .init_resource::() .add_systems( Update, ( diff --git a/crates/bevy_ui/src/layout/mod.rs b/crates/bevy_ui/src/layout/mod.rs index 8f0de1fd35306..ef3f0e24733b4 100644 --- a/crates/bevy_ui/src/layout/mod.rs +++ b/crates/bevy_ui/src/layout/mod.rs @@ -22,7 +22,9 @@ use thiserror::Error; use ui_surface::UiSurface; #[cfg(feature = "bevy_text")] -use bevy_text::{CosmicBuffer, TextPipeline}; +use bevy_text::CosmicBuffer; +#[cfg(feature = "bevy_text")] +use bevy_text::CosmicFontSystem; mod convert; pub mod debug; @@ -124,7 +126,7 @@ pub fn ui_layout_system( Option<&ScrollPosition>, )>, #[cfg(feature = "bevy_text")] mut buffer_query: Query<&mut CosmicBuffer>, - #[cfg(feature = "bevy_text")] mut text_pipeline: ResMut, + #[cfg(feature = "bevy_text")] mut font_system: ResMut, ) { let UiLayoutSystemBuffers { interned_root_nodes, @@ -250,8 +252,6 @@ pub fn ui_layout_system( #[cfg(feature = "bevy_text")] let text_buffers = &mut buffer_query; - #[cfg(feature = "bevy_text")] - let font_system = text_pipeline.font_system_mut(); // clean up removed nodes after syncing children to avoid potential panic (invalid SlotMap key used) ui_surface.remove_entities(removed_components.removed_nodes.read()); @@ -271,7 +271,7 @@ pub fn ui_layout_system( #[cfg(feature = "bevy_text")] text_buffers, #[cfg(feature = "bevy_text")] - font_system, + &mut font_system.0, ); for root in &camera.root_nodes { @@ -523,6 +523,10 @@ mod tests { world.init_resource::(); #[cfg(feature = "bevy_text")] world.init_resource::(); + #[cfg(feature = "bevy_text")] + world.init_resource::(); + #[cfg(feature = "bevy_text")] + world.init_resource::(); // spawn a dummy primary window and camera world.spawn(( @@ -1160,6 +1164,10 @@ mod tests { world.init_resource::(); #[cfg(feature = "bevy_text")] world.init_resource::(); + #[cfg(feature = "bevy_text")] + world.init_resource::(); + #[cfg(feature = "bevy_text")] + world.init_resource::(); // spawn a dummy primary window and camera world.spawn(( diff --git a/crates/bevy_ui/src/widget/text.rs b/crates/bevy_ui/src/widget/text.rs index e84ec322dc13f..812e4dd1ab952 100644 --- a/crates/bevy_ui/src/widget/text.rs +++ b/crates/bevy_ui/src/widget/text.rs @@ -16,8 +16,9 @@ use bevy_reflect::{std_traits::ReflectDefault, Reflect}; use bevy_render::{camera::Camera, texture::Image}; use bevy_sprite::TextureAtlasLayout; use bevy_text::{ - scale_value, BreakLineOn, CosmicBuffer, Font, FontAtlasSets, JustifyText, Text, TextBounds, - TextError, TextLayoutInfo, TextMeasureInfo, TextPipeline, YAxisOrientation, + scale_value, BreakLineOn, CosmicBuffer, CosmicFontSystem, Font, FontAtlasSets, JustifyText, + SwashCache, Text, TextBounds, TextError, TextLayoutInfo, TextMeasureInfo, TextPipeline, + YAxisOrientation, }; use bevy_utils::{tracing::error, Entry}; use taffy::style::AvailableSpace; @@ -112,6 +113,7 @@ fn create_text_measure( mut text_flags: Mut, buffer: &mut CosmicBuffer, text_alignment: JustifyText, + font_system: &mut CosmicFontSystem, ) { match text_pipeline.create_text_measure( entity, @@ -121,6 +123,7 @@ fn create_text_measure( text.linebreak_behavior, buffer, text_alignment, + font_system, ) { Ok(measure) => { if text.linebreak_behavior == BreakLineOn::NoWrap { @@ -173,6 +176,7 @@ pub fn measure_text_system( With, >, mut text_pipeline: ResMut, + mut font_system: ResMut, ) { scale_factors_buffer.clear(); @@ -208,6 +212,7 @@ pub fn measure_text_system( text_flags, buffer.as_mut(), text_alignment, + &mut font_system, ); } } @@ -229,6 +234,8 @@ fn queue_text( mut text_flags: Mut, text_layout_info: Mut, buffer: &mut CosmicBuffer, + font_system: &mut CosmicFontSystem, + swash_cache: &mut SwashCache, ) { // Skip the text node if it is waiting for a new measure func if !text_flags.needs_new_measure_func { @@ -258,6 +265,8 @@ fn queue_text( textures, YAxisOrientation::TopToBottom, buffer, + font_system, + swash_cache, ) { Err(TextError::NoSuchFont) => { // There was an error processing the text layout, try again next frame @@ -305,6 +314,8 @@ pub fn text_system( Option<&TargetCamera>, &mut CosmicBuffer, )>, + mut font_system: ResMut, + mut swash_cache: ResMut, ) { scale_factors_buffer.clear(); @@ -343,6 +354,8 @@ pub fn text_system( text_flags, text_layout_info, buffer.as_mut(), + &mut font_system, + &mut swash_cache, ); } }