Skip to content

Commit

Permalink
Add EntityMut::world_scope
Browse files Browse the repository at this point in the history
  • Loading branch information
irate-devil committed Nov 4, 2022
1 parent 4453650 commit 201a3f9
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 23 deletions.
8 changes: 7 additions & 1 deletion crates/bevy_ecs/src/world/entity_ref.rs
Expand Up @@ -526,7 +526,7 @@ impl<'w> EntityMut<'w> {

/// Returns this `EntityMut`'s world.
///
/// See [`EntityMut::into_world_mut`] for a safe alternative.
/// See [`EntityMut::world_scope`] or [`EntityMut::into_world_mut`] for a safe alternative.
///
/// # Safety
/// Caller must not modify the world in a way that changes the current entity's location
Expand All @@ -543,6 +543,12 @@ impl<'w> EntityMut<'w> {
self.world
}

/// Gives mutable access to this `EntityMut`'s [`World`] in a temporary scope.
pub fn world_scope(&mut self, f: impl FnOnce(&mut World)) {
f(self.world);
self.update_location();
}

/// Updates the internal entity location to match the current location in the internal
/// [`World`]. This is only needed if the user called [`EntityMut::world`], which enables the
/// location to change.
Expand Down
33 changes: 11 additions & 22 deletions crates/bevy_hierarchy/src/child_builder.rs
Expand Up @@ -456,29 +456,23 @@ pub trait BuildWorldChildren {

impl<'w> BuildWorldChildren for EntityMut<'w> {
fn with_children(&mut self, spawn_children: impl FnOnce(&mut WorldChildBuilder)) -> &mut Self {
{
let entity = self.id();
let entity = self.id();
self.world_scope(|world| {
let mut builder = WorldChildBuilder {
current_entity: None,
parent_entities: vec![entity],
// SAFETY: The EntityLocation is updated before any other methods are called on self.
world: unsafe { self.world_mut() },
world,
};

spawn_children(&mut builder);
}
self.update_location();
});
self
}

fn push_children(&mut self, children: &[Entity]) -> &mut Self {
let parent = self.id();
{
// SAFETY: The EntityLocation is updated before any other methods are called on self.
let world = unsafe { self.world_mut() };
self.world_scope(|world| {
update_old_parents(world, parent, children);
self.update_location();
}
});
if let Some(mut children_component) = self.get_mut::<Children>() {
children_component
.0
Expand All @@ -492,13 +486,9 @@ impl<'w> BuildWorldChildren for EntityMut<'w> {

fn insert_children(&mut self, index: usize, children: &[Entity]) -> &mut Self {
let parent = self.id();
{
// SAFETY: The EntityLocation is updated before any other methods are called on self.
let world = unsafe { self.world_mut() };
self.world_scope(|world| {
update_old_parents(world, parent, children);
self.update_location();
}

});
if let Some(mut children_component) = self.get_mut::<Children>() {
children_component
.0
Expand All @@ -512,10 +502,9 @@ impl<'w> BuildWorldChildren for EntityMut<'w> {

fn remove_children(&mut self, children: &[Entity]) -> &mut Self {
let parent = self.id();
// SAFETY: The EntityLocation is updated before any other methods are called on self.
let world = unsafe { self.world_mut() };
remove_children(parent, children, world);
self.update_location();
self.world_scope(|world| {
remove_children(parent, children, world);
});
self
}
}
Expand Down

0 comments on commit 201a3f9

Please sign in to comment.