From 3cc2b635fd20bf29e59c427f44dd28d923f54359 Mon Sep 17 00:00:00 2001 From: janis Date: Fri, 12 Sep 2025 16:26:54 +0200 Subject: [PATCH 1/3] sync/send for movingptr --- crates/bevy_ptr/src/lib.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/crates/bevy_ptr/src/lib.rs b/crates/bevy_ptr/src/lib.rs index 1d6e43fcf1f9b..c41ec896c1c71 100644 --- a/crates/bevy_ptr/src/lib.rs +++ b/crates/bevy_ptr/src/lib.rs @@ -805,6 +805,9 @@ impl Drop for MovingPtr<'_, T, A> { } } +unsafe impl Send for MovingPtr<'_, T, A> {} +unsafe impl Sync for MovingPtr<'_, T, A> {} + impl<'a, A: IsAligned> Ptr<'a, A> { /// Creates a new instance from a raw pointer. /// From 7ec83e646c835e7ae586d5ccf8e22fbfc2e723f9 Mon Sep 17 00:00:00 2001 From: janis Date: Fri, 12 Sep 2025 16:27:27 +0200 Subject: [PATCH 2/3] bundle name associated type --- crates/bevy_ecs/macros/src/lib.rs | 1 + crates/bevy_ecs/src/bundle/impls.rs | 37 +++++++++++++++++++++++++++++ crates/bevy_ecs/src/bundle/info.rs | 17 ++++++++----- crates/bevy_ecs/src/bundle/mod.rs | 15 ++++++++++-- crates/bevy_ecs/src/spawn.rs | 2 ++ crates/bevy_ecs/src/system/mod.rs | 4 +++- 6 files changed, 67 insertions(+), 9 deletions(-) diff --git a/crates/bevy_ecs/macros/src/lib.rs b/crates/bevy_ecs/macros/src/lib.rs index c465e052d284b..5b5aed0594b31 100644 --- a/crates/bevy_ecs/macros/src/lib.rs +++ b/crates/bevy_ecs/macros/src/lib.rs @@ -151,6 +151,7 @@ pub fn derive_bundle(input: TokenStream) -> TokenStream { // the correct `StorageType` into the callback. #[allow(deprecated)] unsafe impl #impl_generics #ecs_path::bundle::Bundle for #struct_name #ty_generics #where_clause { + type Name = (#(<#active_field_types as #ecs_path::bundle::Bundle>::Name,)*); fn component_ids( components: &mut #ecs_path::component::ComponentsRegistrator, ids: &mut impl FnMut(#ecs_path::component::ComponentId) diff --git a/crates/bevy_ecs/src/bundle/impls.rs b/crates/bevy_ecs/src/bundle/impls.rs index 7cf74a86e324f..c41d803ea2097 100644 --- a/crates/bevy_ecs/src/bundle/impls.rs +++ b/crates/bevy_ecs/src/bundle/impls.rs @@ -15,6 +15,8 @@ use crate::{ // - `Bundle::component_ids` calls `ids` for C's component id (and nothing else) // - `Bundle::get_components` is called exactly once for C and passes the component's storage type based on its associated constant. unsafe impl Bundle for C { + type Name = C; + fn component_ids(components: &mut ComponentsRegistrator, ids: &mut impl FnMut(ComponentId)) { ids(components.register_component::()); } @@ -53,6 +55,40 @@ impl DynamicBundle for C { unsafe fn apply_effect(_ptr: MovingPtr<'_, MaybeUninit>, _entity: &mut EntityWorldMut) {} } +unsafe impl Bundle for MovingPtr<'_, T> { + type Name = ::Name; + + fn component_ids(components: &mut ComponentsRegistrator, ids: &mut impl FnMut(ComponentId)) { + T::component_ids(components, ids); + } + + fn get_component_ids(components: &Components, ids: &mut impl FnMut(Option)) { + T::get_component_ids(components, ids); + } +} + +impl DynamicBundle for MovingPtr<'_, T> { + type Effect = T::Effect; + + unsafe fn get_components( + ptr: MovingPtr<'_, Self>, + func: &mut impl FnMut(StorageType, OwningPtr<'_>), + ) { + let this = ptr.read(); + + T::get_components(this, func); + } + + unsafe fn apply_effect(ptr: MovingPtr<'_, MaybeUninit>, entity: &mut EntityWorldMut) { + let this = unsafe { + core::mem::transmute::>, MovingPtr<'_, MaybeUninit>>( + ptr.read(), + ) + }; + T::apply_effect(this, entity); + } +} + macro_rules! tuple_impl { ($(#[$meta:meta])* $(($index:tt, $name: ident, $alias: ident)),*) => { #[expect( @@ -72,6 +108,7 @@ macro_rules! tuple_impl { // - `Bundle::get_components` is called exactly once for each member. Relies on the above implementation to pass the correct // `StorageType` into the callback. unsafe impl<$($name: Bundle),*> Bundle for ($($name,)*) { + type Name = ($(<$name as Bundle>::Name,)*); fn component_ids(components: &mut ComponentsRegistrator, ids: &mut impl FnMut(ComponentId)){ $(<$name as Bundle>::component_ids(components, ids);)* } diff --git a/crates/bevy_ecs/src/bundle/info.rs b/crates/bevy_ecs/src/bundle/info.rs index 589ec0b7c65e6..9e8ad7edb0149 100644 --- a/crates/bevy_ecs/src/bundle/info.rs +++ b/crates/bevy_ecs/src/bundle/info.rs @@ -10,7 +10,7 @@ use indexmap::{IndexMap, IndexSet}; use crate::{ archetype::{Archetype, BundleComponentStatus, ComponentStatus}, - bundle::{Bundle, DynamicBundle}, + bundle::{bundle_id_of, Bundle, DynamicBundle}, change_detection::MaybeLocation, component::{ ComponentId, Components, ComponentsRegistrator, RequiredComponentConstructor, StorageType, @@ -411,9 +411,10 @@ impl Bundles { self.bundle_infos.get(bundle_id.index()) } - /// Gets the value identifying a specific type of bundle. + /// Gets the value identifying a specific bundle. + /// You can use [`bundle_id_of`] or [`bundle_id_of_val`](super::bundle_id_of_val) to easily get a bundle's `TypeId`. /// Returns `None` if the bundle does not exist in the world, - /// or if `type_id` does not correspond to a type of bundle. + /// or if `type_id` does not correspond to a bundle. #[inline] pub fn get_id(&self, type_id: TypeId) -> Option { self.bundle_ids.get(&type_id).cloned() @@ -435,7 +436,7 @@ impl Bundles { storages: &mut Storages, ) -> BundleId { let bundle_infos = &mut self.bundle_infos; - *self.bundle_ids.entry(TypeId::of::()).or_insert_with(|| { + *self.bundle_ids.entry(bundle_id_of::()).or_insert_with(|| { let mut component_ids= Vec::new(); T::component_ids(components, &mut |id| component_ids.push(id)); let id = BundleId(bundle_infos.len()); @@ -465,7 +466,11 @@ impl Bundles { components: &mut ComponentsRegistrator, storages: &mut Storages, ) -> BundleId { - if let Some(id) = self.contributed_bundle_ids.get(&TypeId::of::()).cloned() { + if let Some(id) = self + .contributed_bundle_ids + .get(&bundle_id_of::()) + .cloned() + { id } else { // SAFETY: as per the guarantees of this function, components and @@ -485,7 +490,7 @@ impl Bundles { // part of init_dynamic_info. No mutable references will be created and the allocation will remain valid. self.init_dynamic_info(storages, components, core::slice::from_raw_parts(ptr, len)) }; - self.contributed_bundle_ids.insert(TypeId::of::(), id); + self.contributed_bundle_ids.insert(bundle_id_of::(), id); id } } diff --git a/crates/bevy_ecs/src/bundle/mod.rs b/crates/bevy_ecs/src/bundle/mod.rs index 17d894d40b660..a0abfd05227c6 100644 --- a/crates/bevy_ecs/src/bundle/mod.rs +++ b/crates/bevy_ecs/src/bundle/mod.rs @@ -15,7 +15,7 @@ pub(crate) use remove::BundleRemover; pub(crate) use spawner::BundleSpawner; use bevy_ptr::MovingPtr; -use core::mem::MaybeUninit; +use core::{any::TypeId, mem::MaybeUninit}; pub use info::*; /// Derive the [`Bundle`] trait @@ -197,7 +197,8 @@ use bevy_ptr::OwningPtr; label = "invalid `Bundle`", note = "consider annotating `{Self}` with `#[derive(Component)]` or `#[derive(Bundle)]`" )] -pub unsafe trait Bundle: DynamicBundle + Send + Sync + 'static { +pub unsafe trait Bundle: DynamicBundle + Send { + type Name: 'static; /// Gets this [`Bundle`]'s component ids, in the order of this bundle's [`Component`]s #[doc(hidden)] fn component_ids(components: &mut ComponentsRegistrator, ids: &mut impl FnMut(ComponentId)); @@ -206,6 +207,16 @@ pub unsafe trait Bundle: DynamicBundle + Send + Sync + 'static { fn get_component_ids(components: &Components, ids: &mut impl FnMut(Option)); } +pub const fn bundle_id_of() -> TypeId { + TypeId::of::() +} +pub const fn bundle_id_of_val(_: &T) -> TypeId { + TypeId::of::() +} + +pub trait StaticBundle: Bundle + 'static {} +impl StaticBundle for T {} + /// Creates a [`Bundle`] by taking it from internal storage. /// /// # Safety diff --git a/crates/bevy_ecs/src/spawn.rs b/crates/bevy_ecs/src/spawn.rs index e4b7340c9ccfc..c9b16435b49fd 100644 --- a/crates/bevy_ecs/src/spawn.rs +++ b/crates/bevy_ecs/src/spawn.rs @@ -309,6 +309,7 @@ pub struct SpawnRelatedBundle> { unsafe impl + Send + Sync + 'static> Bundle for SpawnRelatedBundle { + type Name = ::Name; fn component_ids( components: &mut crate::component::ComponentsRegistrator, ids: &mut impl FnMut(crate::component::ComponentId), @@ -402,6 +403,7 @@ impl DynamicBundle for SpawnOneRelated { // SAFETY: This internally relies on the RelationshipTarget's Bundle implementation, which is sound. unsafe impl Bundle for SpawnOneRelated { + type Name = ::Name; fn component_ids( components: &mut crate::component::ComponentsRegistrator, ids: &mut impl FnMut(crate::component::ComponentId), diff --git a/crates/bevy_ecs/src/system/mod.rs b/crates/bevy_ecs/src/system/mod.rs index b5738733d7f95..86081998e87ab 100644 --- a/crates/bevy_ecs/src/system/mod.rs +++ b/crates/bevy_ecs/src/system/mod.rs @@ -1129,7 +1129,9 @@ mod tests { let archetype = archetypes.get(location.archetype_id).unwrap(); let archetype_components = archetype.components(); let bundle_id = bundles - .get_id(TypeId::of::<(W, W)>()) + .get_id(TypeId::of::< + <(W, W) as crate::bundle::Bundle>::Name, + >()) .expect("Bundle used to spawn entity should exist"); let bundle_info = bundles.get(bundle_id).unwrap(); let mut bundle_components = bundle_info.contributed_components().to_vec(); From 7940a799aebf2f9b83b93d28fc2a9a0e412579f3 Mon Sep 17 00:00:00 2001 From: janis Date: Fri, 12 Sep 2025 17:28:08 +0200 Subject: [PATCH 3/3] rename Bundle to BundleImpl (bikeshed), remove 'static bound --- crates/bevy_ecs/macros/src/lib.rs | 8 +++--- crates/bevy_ecs/src/bundle/impls.rs | 23 +++++++++------- crates/bevy_ecs/src/bundle/info.rs | 4 ++- crates/bevy_ecs/src/bundle/mod.rs | 10 +++---- crates/bevy_ecs/src/bundle/spawner.rs | 4 ++- crates/bevy_ecs/src/lib.rs | 15 ++++++----- crates/bevy_ecs/src/spawn.rs | 38 +++++++++++++-------------- crates/bevy_ecs/src/system/mod.rs | 6 ++--- crates/bevy_ecs/src/world/mod.rs | 10 +++---- 9 files changed, 63 insertions(+), 55 deletions(-) diff --git a/crates/bevy_ecs/macros/src/lib.rs b/crates/bevy_ecs/macros/src/lib.rs index 5b5aed0594b31..87677eb5f2c0f 100644 --- a/crates/bevy_ecs/macros/src/lib.rs +++ b/crates/bevy_ecs/macros/src/lib.rs @@ -150,20 +150,20 @@ pub fn derive_bundle(input: TokenStream) -> TokenStream { // - `Bundle::get_components` is exactly once for each member. Rely's on the Component -> Bundle implementation to properly pass // the correct `StorageType` into the callback. #[allow(deprecated)] - unsafe impl #impl_generics #ecs_path::bundle::Bundle for #struct_name #ty_generics #where_clause { - type Name = (#(<#active_field_types as #ecs_path::bundle::Bundle>::Name,)*); + unsafe impl #impl_generics #ecs_path::bundle::BundleImpl for #struct_name #ty_generics #where_clause { + type Name = (#(<#active_field_types as #ecs_path::bundle::BundleImpl>::Name,)*); fn component_ids( components: &mut #ecs_path::component::ComponentsRegistrator, ids: &mut impl FnMut(#ecs_path::component::ComponentId) ) { - #(<#active_field_types as #ecs_path::bundle::Bundle>::component_ids(components, ids);)* + #(<#active_field_types as #ecs_path::bundle::BundleImpl>::component_ids(components, ids);)* } fn get_component_ids( components: &#ecs_path::component::Components, ids: &mut impl FnMut(Option<#ecs_path::component::ComponentId>) ) { - #(<#active_field_types as #ecs_path::bundle::Bundle>::get_component_ids(components, &mut *ids);)* + #(<#active_field_types as #ecs_path::bundle::BundleImpl>::get_component_ids(components, &mut *ids);)* } } }; diff --git a/crates/bevy_ecs/src/bundle/impls.rs b/crates/bevy_ecs/src/bundle/impls.rs index c41d803ea2097..2a6fbdd4bb9d6 100644 --- a/crates/bevy_ecs/src/bundle/impls.rs +++ b/crates/bevy_ecs/src/bundle/impls.rs @@ -5,16 +5,19 @@ use core::mem::MaybeUninit; use variadics_please::all_tuples_enumerated; use crate::{ - bundle::{Bundle, BundleFromComponents, DynamicBundle, NoBundleEffect}, + bundle::{BundleFromComponents, DynamicBundle, NoBundleEffect}, component::{Component, ComponentId, Components, ComponentsRegistrator, StorageType}, query::DebugCheckedUnwrap, world::EntityWorldMut, }; +use super::BundleImpl; + +// note: `Component: 'static`, so `C: Bundle`. // SAFETY: // - `Bundle::component_ids` calls `ids` for C's component id (and nothing else) // - `Bundle::get_components` is called exactly once for C and passes the component's storage type based on its associated constant. -unsafe impl Bundle for C { +unsafe impl BundleImpl for C { type Name = C; fn component_ids(components: &mut ComponentsRegistrator, ids: &mut impl FnMut(ComponentId)) { @@ -55,8 +58,8 @@ impl DynamicBundle for C { unsafe fn apply_effect(_ptr: MovingPtr<'_, MaybeUninit>, _entity: &mut EntityWorldMut) {} } -unsafe impl Bundle for MovingPtr<'_, T> { - type Name = ::Name; +unsafe impl BundleImpl for MovingPtr<'_, T> { + type Name = ::Name; fn component_ids(components: &mut ComponentsRegistrator, ids: &mut impl FnMut(ComponentId)) { T::component_ids(components, ids); @@ -67,7 +70,7 @@ unsafe impl Bundle for MovingPtr<'_, T> { } } -impl DynamicBundle for MovingPtr<'_, T> { +impl DynamicBundle for MovingPtr<'_, T> { type Effect = T::Effect; unsafe fn get_components( @@ -107,14 +110,14 @@ macro_rules! tuple_impl { // - `Bundle::from_components` calls `func` exactly once for each `ComponentId` returned by `Bundle::component_ids`. // - `Bundle::get_components` is called exactly once for each member. Relies on the above implementation to pass the correct // `StorageType` into the callback. - unsafe impl<$($name: Bundle),*> Bundle for ($($name,)*) { - type Name = ($(<$name as Bundle>::Name,)*); + unsafe impl<$($name: BundleImpl),*> BundleImpl for ($($name,)*) { + type Name = ($(<$name as BundleImpl>::Name,)*); fn component_ids(components: &mut ComponentsRegistrator, ids: &mut impl FnMut(ComponentId)){ - $(<$name as Bundle>::component_ids(components, ids);)* + $(<$name as BundleImpl>::component_ids(components, ids);)* } fn get_component_ids(components: &Components, ids: &mut impl FnMut(Option)){ - $(<$name as Bundle>::get_component_ids(components, ids);)* + $(<$name as BundleImpl>::get_component_ids(components, ids);)* } } @@ -163,7 +166,7 @@ macro_rules! tuple_impl { reason = "Zero-length tuples won't use any of the parameters." )] $(#[$meta])* - impl<$($name: Bundle),*> DynamicBundle for ($($name,)*) { + impl<$($name: DynamicBundle),*> DynamicBundle for ($($name,)*) { type Effect = ($($name::Effect,)*); #[allow( clippy::unused_unit, diff --git a/crates/bevy_ecs/src/bundle/info.rs b/crates/bevy_ecs/src/bundle/info.rs index 9e8ad7edb0149..ad2589a90f8bf 100644 --- a/crates/bevy_ecs/src/bundle/info.rs +++ b/crates/bevy_ecs/src/bundle/info.rs @@ -21,6 +21,8 @@ use crate::{ storage::{SparseSetIndex, SparseSets, Storages, Table, TableRow}, }; +use super::BundleImpl; + /// For a specific [`World`], this stores a unique value identifying a type of a registered [`Bundle`]. /// /// [`World`]: crate::world::World @@ -430,7 +432,7 @@ impl Bundles { /// /// [`World`]: crate::world::World #[deny(unsafe_op_in_unsafe_fn)] - pub(crate) unsafe fn register_info( + pub(crate) unsafe fn register_info( &mut self, components: &mut ComponentsRegistrator, storages: &mut Storages, diff --git a/crates/bevy_ecs/src/bundle/mod.rs b/crates/bevy_ecs/src/bundle/mod.rs index a0abfd05227c6..a5c96bf671ec4 100644 --- a/crates/bevy_ecs/src/bundle/mod.rs +++ b/crates/bevy_ecs/src/bundle/mod.rs @@ -197,7 +197,7 @@ use bevy_ptr::OwningPtr; label = "invalid `Bundle`", note = "consider annotating `{Self}` with `#[derive(Component)]` or `#[derive(Bundle)]`" )] -pub unsafe trait Bundle: DynamicBundle + Send { +pub unsafe trait BundleImpl: DynamicBundle + Send + Sync { type Name: 'static; /// Gets this [`Bundle`]'s component ids, in the order of this bundle's [`Component`]s #[doc(hidden)] @@ -207,15 +207,15 @@ pub unsafe trait Bundle: DynamicBundle + Send { fn get_component_ids(components: &Components, ids: &mut impl FnMut(Option)); } -pub const fn bundle_id_of() -> TypeId { +pub const fn bundle_id_of() -> TypeId { TypeId::of::() } -pub const fn bundle_id_of_val(_: &T) -> TypeId { +pub const fn bundle_id_of_val(_: &T) -> TypeId { TypeId::of::() } -pub trait StaticBundle: Bundle + 'static {} -impl StaticBundle for T {} +pub trait Bundle: BundleImpl + 'static {} +impl Bundle for T {} /// Creates a [`Bundle`] by taking it from internal storage. /// diff --git a/crates/bevy_ecs/src/bundle/spawner.rs b/crates/bevy_ecs/src/bundle/spawner.rs index b4f32147aecdf..45e9a24298805 100644 --- a/crates/bevy_ecs/src/bundle/spawner.rs +++ b/crates/bevy_ecs/src/bundle/spawner.rs @@ -15,6 +15,8 @@ use crate::{ world::{unsafe_world_cell::UnsafeWorldCell, World}, }; +use super::BundleImpl; + // SAFETY: We have exclusive world access so our pointers can't be invalidated externally pub(crate) struct BundleSpawner<'w> { world: UnsafeWorldCell<'w>, @@ -26,7 +28,7 @@ pub(crate) struct BundleSpawner<'w> { impl<'w> BundleSpawner<'w> { #[inline] - pub fn new(world: &'w mut World, change_tick: Tick) -> Self { + pub fn new(world: &'w mut World, change_tick: Tick) -> Self { let bundle_id = world.register_bundle_info::(); // SAFETY: we initialized this bundle_id in `init_info` diff --git a/crates/bevy_ecs/src/lib.rs b/crates/bevy_ecs/src/lib.rs index 0d148b346895f..718505ea023c1 100644 --- a/crates/bevy_ecs/src/lib.rs +++ b/crates/bevy_ecs/src/lib.rs @@ -158,7 +158,7 @@ pub struct HotPatchChanges; #[cfg(test)] mod tests { use crate::{ - bundle::Bundle, + bundle::{Bundle, BundleImpl}, change_detection::Ref, component::Component, entity::{Entity, EntityMapper}, @@ -250,7 +250,7 @@ mod tests { y: SparseStored, } let mut ids = Vec::new(); - ::component_ids(&mut world.components_registrator(), &mut |id| { + ::component_ids(&mut world.components_registrator(), &mut |id| { ids.push(id); }); @@ -300,9 +300,12 @@ mod tests { } let mut ids = Vec::new(); - ::component_ids(&mut world.components_registrator(), &mut |id| { - ids.push(id); - }); + ::component_ids( + &mut world.components_registrator(), + &mut |id| { + ids.push(id); + }, + ); assert_eq!( ids, @@ -352,7 +355,7 @@ mod tests { } let mut ids = Vec::new(); - ::component_ids( + ::component_ids( &mut world.components_registrator(), &mut |id| { ids.push(id); diff --git a/crates/bevy_ecs/src/spawn.rs b/crates/bevy_ecs/src/spawn.rs index c9b16435b49fd..47d4f10dc9605 100644 --- a/crates/bevy_ecs/src/spawn.rs +++ b/crates/bevy_ecs/src/spawn.rs @@ -2,7 +2,7 @@ //! for the best entry points into these APIs and examples of how to use them. use crate::{ - bundle::{Bundle, DynamicBundle, InsertMode, NoBundleEffect}, + bundle::{Bundle, BundleImpl, DynamicBundle, InsertMode, NoBundleEffect}, change_detection::MaybeLocation, entity::Entity, query::DebugCheckedUnwrap, @@ -80,23 +80,23 @@ impl SpawnableList for Spawn { // SAFETY: // - `Spawn` has one field at index 0. // - if `this` is aligned, then its inner bundle must be as well. - let bundle = unsafe { + let bundle: MovingPtr<'_, B, _> = unsafe { bevy_ptr::deconstruct_moving_ptr!(this => ( 0 => bundle, )); bundle.try_into().debug_checked_unwrap() }; - let r = R::from(entity); + let r = (R::from(entity), bundle); move_as_ptr!(r); - let mut entity = world.spawn_with_caller(r, caller); - - entity.insert_with_caller( - bundle, - InsertMode::Replace, - caller, - RelationshipHookMode::Run, - ); + world.spawn_with_caller(r, caller); + + // entity.insert_with_caller( + // bundle, + // InsertMode::Replace, + // caller, + // RelationshipHookMode::Run, + // ); } spawn::(this, world, entity); @@ -306,22 +306,22 @@ pub struct SpawnRelatedBundle> { } // SAFETY: This internally relies on the RelationshipTarget's Bundle implementation, which is sound. -unsafe impl + Send + Sync + 'static> Bundle +unsafe impl + Send + Sync + 'static> BundleImpl for SpawnRelatedBundle { - type Name = ::Name; + type Name = ::Name; fn component_ids( components: &mut crate::component::ComponentsRegistrator, ids: &mut impl FnMut(crate::component::ComponentId), ) { - ::component_ids(components, ids); + ::component_ids(components, ids); } fn get_component_ids( components: &crate::component::Components, ids: &mut impl FnMut(Option), ) { - ::get_component_ids(components, ids); + ::get_component_ids(components, ids); } } @@ -402,20 +402,20 @@ impl DynamicBundle for SpawnOneRelated { } // SAFETY: This internally relies on the RelationshipTarget's Bundle implementation, which is sound. -unsafe impl Bundle for SpawnOneRelated { - type Name = ::Name; +unsafe impl BundleImpl for SpawnOneRelated { + type Name = ::Name; fn component_ids( components: &mut crate::component::ComponentsRegistrator, ids: &mut impl FnMut(crate::component::ComponentId), ) { - ::component_ids(components, ids); + ::component_ids(components, ids); } fn get_component_ids( components: &crate::component::Components, ids: &mut impl FnMut(Option), ) { - ::get_component_ids(components, ids); + ::get_component_ids(components, ids); } } diff --git a/crates/bevy_ecs/src/system/mod.rs b/crates/bevy_ecs/src/system/mod.rs index 86081998e87ab..360028445c43f 100644 --- a/crates/bevy_ecs/src/system/mod.rs +++ b/crates/bevy_ecs/src/system/mod.rs @@ -403,7 +403,7 @@ mod tests { use crate::{ archetype::Archetypes, - bundle::Bundles, + bundle::{bundle_id_of, Bundles}, change_detection::DetectChanges, component::{Component, Components}, entity::{Entities, Entity}, @@ -1129,9 +1129,7 @@ mod tests { let archetype = archetypes.get(location.archetype_id).unwrap(); let archetype_components = archetype.components(); let bundle_id = bundles - .get_id(TypeId::of::< - <(W, W) as crate::bundle::Bundle>::Name, - >()) + .get_id(bundle_id_of::<(W, W)>()) .expect("Bundle used to spawn entity should exist"); let bundle_info = bundles.get(bundle_id).unwrap(); let mut bundle_components = bundle_info.contributed_components().to_vec(); diff --git a/crates/bevy_ecs/src/world/mod.rs b/crates/bevy_ecs/src/world/mod.rs index 4c6d3c5455d51..3886d576f8018 100644 --- a/crates/bevy_ecs/src/world/mod.rs +++ b/crates/bevy_ecs/src/world/mod.rs @@ -32,8 +32,8 @@ pub use spawn_batch::*; use crate::{ archetype::{ArchetypeId, Archetypes}, bundle::{ - Bundle, BundleId, BundleInfo, BundleInserter, BundleSpawner, Bundles, InsertMode, - NoBundleEffect, + Bundle, BundleId, BundleImpl, BundleInfo, BundleInserter, BundleSpawner, Bundles, + InsertMode, NoBundleEffect, }, change_detection::{MaybeLocation, MutUntyped, TicksMut}, component::{ @@ -1156,7 +1156,7 @@ impl World { self.spawn_with_caller(bundle, MaybeLocation::caller()) } - pub(crate) fn spawn_with_caller( + pub(crate) fn spawn_with_caller( &mut self, bundle: MovingPtr<'_, B>, caller: MaybeLocation, @@ -3085,14 +3085,14 @@ impl World { /// This is largely equivalent to calling [`register_component`](Self::register_component) on each /// component in the bundle. #[inline] - pub fn register_bundle(&mut self) -> &BundleInfo { + pub fn register_bundle(&mut self) -> &BundleInfo { let id = self.register_bundle_info::(); // SAFETY: We just initialized the bundle so its id should definitely be valid. unsafe { self.bundles.get(id).debug_checked_unwrap() } } - pub(crate) fn register_bundle_info(&mut self) -> BundleId { + pub(crate) fn register_bundle_info(&mut self) -> BundleId { // SAFETY: These come from the same world. `Self.components_registrator` can't be used since we borrow other fields too. let mut registrator = unsafe { ComponentsRegistrator::new(&mut self.components, &mut self.component_ids) };