From 4eab25cb8531c8a8abdb9d772aa4790215055ed4 Mon Sep 17 00:00:00 2001 From: Elliott Pierce Date: Fri, 30 May 2025 18:09:19 -0400 Subject: [PATCH] finished most easy fixes --- crates/bevy_ecs/src/bundle.rs | 47 +++++++++++-------------- crates/bevy_ecs/src/lib.rs | 10 ------ crates/bevy_ecs/src/world/entity_ref.rs | 8 ++--- crates/bevy_ecs/src/world/mod.rs | 2 +- 4 files changed, 24 insertions(+), 43 deletions(-) diff --git a/crates/bevy_ecs/src/bundle.rs b/crates/bevy_ecs/src/bundle.rs index 1b8b6fd1de..999dc63d29 100644 --- a/crates/bevy_ecs/src/bundle.rs +++ b/crates/bevy_ecs/src/bundle.rs @@ -1191,8 +1191,8 @@ impl<'w> BundleInserter<'w> { let swapped_location = // SAFETY: If the swap was successful, swapped_entity must be valid. unsafe { entities.get(swapped_entity).debug_checked_unwrap() }; - entities.set( - swapped_entity.index(), + entities.update( + swapped_entity.row(), Some(EntityLocation { archetype_id: swapped_location.archetype_id, archetype_row: location.archetype_row, @@ -1202,7 +1202,7 @@ impl<'w> BundleInserter<'w> { ); } let new_location = new_archetype.allocate(entity, result.table_row); - entities.set(entity.index(), Some(new_location)); + entities.update(entity.row(), Some(new_location)); let after_effect = bundle_info.write_components( table, sparse_sets, @@ -1240,8 +1240,8 @@ impl<'w> BundleInserter<'w> { let swapped_location = // SAFETY: If the swap was successful, swapped_entity must be valid. unsafe { entities.get(swapped_entity).debug_checked_unwrap() }; - entities.set( - swapped_entity.index(), + entities.update( + swapped_entity.row(), Some(EntityLocation { archetype_id: swapped_location.archetype_id, archetype_row: location.archetype_row, @@ -1254,7 +1254,7 @@ impl<'w> BundleInserter<'w> { // redundant copies let move_result = table.move_to_superset_unchecked(result.table_row, new_table); let new_location = new_archetype.allocate(entity, move_result.new_row); - entities.set(entity.index(), Some(new_location)); + entities.update(entity.row(), Some(new_location)); // If an entity was moved into this entity's table spot, update its table row. if let Some(swapped_entity) = move_result.swapped_entity { @@ -1262,8 +1262,8 @@ impl<'w> BundleInserter<'w> { // SAFETY: If the swap was successful, swapped_entity must be valid. unsafe { entities.get(swapped_entity).debug_checked_unwrap() }; - entities.set( - swapped_entity.index(), + entities.update( + swapped_entity.row(), Some(EntityLocation { archetype_id: swapped_location.archetype_id, archetype_row: swapped_location.archetype_row, @@ -1571,8 +1571,8 @@ impl<'w> BundleRemover<'w> { if let Some(swapped_entity) = remove_result.swapped_entity { let swapped_location = world.entities.get(swapped_entity).unwrap(); - world.entities.set( - swapped_entity.index(), + world.entities.update( + swapped_entity.row(), Some(EntityLocation { archetype_id: swapped_location.archetype_id, archetype_row: location.archetype_row, @@ -1612,8 +1612,8 @@ impl<'w> BundleRemover<'w> { if let Some(swapped_entity) = move_result.swapped_entity { let swapped_location = world.entities.get(swapped_entity).unwrap(); - world.entities.set( - swapped_entity.index(), + world.entities.update( + swapped_entity.row(), Some(EntityLocation { archetype_id: swapped_location.archetype_id, archetype_row: swapped_location.archetype_row, @@ -1635,7 +1635,7 @@ impl<'w> BundleRemover<'w> { // SAFETY: The entity is valid and has been moved to the new location already. unsafe { - world.entities.set(entity.index(), Some(new_location)); + world.entities.update(entity.row(), Some(new_location)); } (new_location, pre_remove_result) @@ -1702,10 +1702,10 @@ impl<'w> BundleSpawner<'w> { } /// # Safety - /// `entity` must be allocated (but non-existent), `T` must match this [`BundleInfo`]'s type + /// `entity` must be allocated and have no location. `T` must match this [`BundleInfo`]'s type #[inline] #[track_caller] - pub unsafe fn spawn_non_existent( + pub unsafe fn construct( &mut self, entity: Entity, bundle: T, @@ -1736,8 +1736,8 @@ impl<'w> BundleSpawner<'w> { InsertMode::Replace, caller, ); - entities.set(entity.index(), Some(location)); - entities.mark_construct_or_destruct(entity.index(), caller, self.change_tick); + entities.declare(entity.row(), Some(location)); + entities.mark_construct_or_destruct(entity.row(), caller, self.change_tick); (location, after_effect) }; @@ -1790,16 +1790,11 @@ impl<'w> BundleSpawner<'w> { bundle: T, caller: MaybeLocation, ) -> (Entity, T::Effect) { - let entity = self.entities().alloc(); - // SAFETY: entity is allocated (but non-existent), `T` matches this BundleInfo's type - let (_, after_effect) = unsafe { self.spawn_non_existent(entity, bundle, caller) }; - (entity, after_effect) - } - - #[inline] - pub(crate) fn entities(&mut self) -> &mut Entities { // SAFETY: No outstanding references to self.world, changes to entities cannot invalidate our internal pointers - unsafe { &mut self.world.world_mut().entities } + let entity = unsafe { self.world.world().allocator.alloc() }; + // SAFETY: entity is allocated (but non-existent), `T` matches this BundleInfo's type + let (_, after_effect) = unsafe { self.construct(entity, bundle, caller) }; + (entity, after_effect) } /// # Safety diff --git a/crates/bevy_ecs/src/lib.rs b/crates/bevy_ecs/src/lib.rs index d8846b29a1..6cd00a5c60 100644 --- a/crates/bevy_ecs/src/lib.rs +++ b/crates/bevy_ecs/src/lib.rs @@ -1179,16 +1179,6 @@ mod tests { assert_eq!(e_mut.get::().unwrap(), &A(0)); } - #[test] - fn reserve_and_spawn() { - let mut world = World::default(); - let e = world.entities().reserve_entity(); - world.flush_entities(); - let mut e_mut = world.entity_mut(e); - e_mut.insert(A(0)); - assert_eq!(e_mut.get::().unwrap(), &A(0)); - } - #[test] fn changed_query() { let mut world = World::default(); diff --git a/crates/bevy_ecs/src/world/entity_ref.rs b/crates/bevy_ecs/src/world/entity_ref.rs index 765a71436a..570c090ee8 100644 --- a/crates/bevy_ecs/src/world/entity_ref.rs +++ b/crates/bevy_ecs/src/world/entity_ref.rs @@ -2500,10 +2500,6 @@ impl<'w> EntityWorldMut<'w> { /// /// This will also despawn any [`Children`](crate::hierarchy::Children) entities, and any other [`RelationshipTarget`](crate::relationship::RelationshipTarget) that is configured /// to despawn descendants. This results in "recursive despawn" behavior. - /// - /// # Panics - /// - /// If the entity has been despawned while this `EntityWorldMut` is still alive. #[track_caller] pub fn despawn(self) { self.despawn_with_caller(MaybeLocation::caller()); @@ -2786,10 +2782,10 @@ impl<'w> EntityWorldMut<'w> { config: impl FnOnce(&mut EntityClonerBuilder) + Send + Sync + 'static, ) -> Entity { self.assert_not_despawned(); - - let entity_clone = self.world.entities.reserve_entity(); self.world.flush(); + let entity_clone = self.world.allocator.alloc(); + let mut builder = EntityCloner::build(self.world); config(&mut builder); builder.clone_entity(self.entity, entity_clone); diff --git a/crates/bevy_ecs/src/world/mod.rs b/crates/bevy_ecs/src/world/mod.rs index 5ce7f181cd..cc41dda6dc 100644 --- a/crates/bevy_ecs/src/world/mod.rs +++ b/crates/bevy_ecs/src/world/mod.rs @@ -1111,7 +1111,7 @@ impl World { let mut bundle_spawner = BundleSpawner::new::(self, change_tick); // SAFETY: bundle's type matches `bundle_info`, entity is allocated but non-existent let (entity_location, after_effect) = - unsafe { bundle_spawner.spawn_non_existent(entity, bundle, caller) }; + unsafe { bundle_spawner.construct(entity, bundle, caller) }; let mut entity_location = Some(entity_location);