Prevent setting parent as itself (#8980)
# Objective - Fixes https://github.com/bevyengine/bevy/issues/8979. ## Solution - Panic when parent and child are same entity. - Add checks into EntityCommands and EntityMut methods
This commit is contained in:
		
							parent
							
								
									10797d4f15
								
							
						
					
					
						commit
						7ccb203b37
					
				| @ -297,12 +297,20 @@ pub trait BuildChildren { | |||||||
|     /// If the children were previously children of another parent, that parent's [`Children`] component
 |     /// If the children were previously children of another parent, that parent's [`Children`] component
 | ||||||
|     /// will have those children removed from its list. Removing all children from a parent causes its
 |     /// will have those children removed from its list. Removing all children from a parent causes its
 | ||||||
|     /// [`Children`] component to be removed from the entity.
 |     /// [`Children`] component to be removed from the entity.
 | ||||||
|  |     ///
 | ||||||
|  |     /// # Panics
 | ||||||
|  |     ///
 | ||||||
|  |     /// Panics if any of the children are the same as the parent.
 | ||||||
|     fn push_children(&mut self, children: &[Entity]) -> &mut Self; |     fn push_children(&mut self, children: &[Entity]) -> &mut Self; | ||||||
|     /// Inserts children at the given index.
 |     /// Inserts children at the given index.
 | ||||||
|     ///
 |     ///
 | ||||||
|     /// If the children were previously children of another parent, that parent's [`Children`] component
 |     /// If the children were previously children of another parent, that parent's [`Children`] component
 | ||||||
|     /// will have those children removed from its list. Removing all children from a parent causes its
 |     /// will have those children removed from its list. Removing all children from a parent causes its
 | ||||||
|     /// [`Children`] component to be removed from the entity.
 |     /// [`Children`] component to be removed from the entity.
 | ||||||
|  |     ///
 | ||||||
|  |     /// # Panics
 | ||||||
|  |     ///
 | ||||||
|  |     /// Panics if any of the children are the same as the parent.
 | ||||||
|     fn insert_children(&mut self, index: usize, children: &[Entity]) -> &mut Self; |     fn insert_children(&mut self, index: usize, children: &[Entity]) -> &mut Self; | ||||||
|     /// Removes the given children
 |     /// Removes the given children
 | ||||||
|     ///
 |     ///
 | ||||||
| @ -313,18 +321,30 @@ pub trait BuildChildren { | |||||||
|     /// If the children were previously children of another parent, that parent's [`Children`] component
 |     /// If the children were previously children of another parent, that parent's [`Children`] component
 | ||||||
|     /// will have those children removed from its list. Removing all children from a parent causes its
 |     /// will have those children removed from its list. Removing all children from a parent causes its
 | ||||||
|     /// [`Children`] component to be removed from the entity.
 |     /// [`Children`] component to be removed from the entity.
 | ||||||
|  |     ///
 | ||||||
|  |     /// # Panics
 | ||||||
|  |     ///
 | ||||||
|  |     /// Panics if the child is the same as the parent.
 | ||||||
|     fn add_child(&mut self, child: Entity) -> &mut Self; |     fn add_child(&mut self, child: Entity) -> &mut Self; | ||||||
|     /// Removes all children from this entity. The [`Children`] component will be removed if it exists, otherwise this does nothing.
 |     /// Removes all children from this entity. The [`Children`] component will be removed if it exists, otherwise this does nothing.
 | ||||||
|     fn clear_children(&mut self) -> &mut Self; |     fn clear_children(&mut self) -> &mut Self; | ||||||
|     /// Removes all current children from this entity, replacing them with the specified list of entities.
 |     /// Removes all current children from this entity, replacing them with the specified list of entities.
 | ||||||
|     ///
 |     ///
 | ||||||
|     /// The removed children will have their [`Parent`] component removed.
 |     /// The removed children will have their [`Parent`] component removed.
 | ||||||
|  |     ///
 | ||||||
|  |     /// # Panics
 | ||||||
|  |     ///
 | ||||||
|  |     /// Panics if any of the children are the same as the parent.
 | ||||||
|     fn replace_children(&mut self, children: &[Entity]) -> &mut Self; |     fn replace_children(&mut self, children: &[Entity]) -> &mut Self; | ||||||
|     /// Sets the parent of this entity.
 |     /// Sets the parent of this entity.
 | ||||||
|     ///
 |     ///
 | ||||||
|     /// If this entity already had a parent, the parent's [`Children`] component will have this
 |     /// If this entity already had a parent, the parent's [`Children`] component will have this
 | ||||||
|     /// child removed from its list. Removing all children from a parent causes its [`Children`]
 |     /// child removed from its list. Removing all children from a parent causes its [`Children`]
 | ||||||
|     /// component to be removed from the entity.
 |     /// component to be removed from the entity.
 | ||||||
|  |     ///
 | ||||||
|  |     /// # Panics
 | ||||||
|  |     ///
 | ||||||
|  |     /// Panics if the parent is the same as the child.
 | ||||||
|     fn set_parent(&mut self, parent: Entity) -> &mut Self; |     fn set_parent(&mut self, parent: Entity) -> &mut Self; | ||||||
|     /// Removes the [`Parent`] of this entity.
 |     /// Removes the [`Parent`] of this entity.
 | ||||||
|     ///
 |     ///
 | ||||||
| @ -346,12 +366,18 @@ impl<'w, 's, 'a> BuildChildren for EntityCommands<'w, 's, 'a> { | |||||||
| 
 | 
 | ||||||
|         spawn_children(&mut builder); |         spawn_children(&mut builder); | ||||||
|         let children = builder.push_children; |         let children = builder.push_children; | ||||||
|  |         if children.children.contains(&parent) { | ||||||
|  |             panic!("Entity cannot be a child of itself."); | ||||||
|  |         } | ||||||
|         self.commands().add(children); |         self.commands().add(children); | ||||||
|         self |         self | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fn push_children(&mut self, children: &[Entity]) -> &mut Self { |     fn push_children(&mut self, children: &[Entity]) -> &mut Self { | ||||||
|         let parent = self.id(); |         let parent = self.id(); | ||||||
|  |         if children.contains(&parent) { | ||||||
|  |             panic!("Cannot push entity as a child of itself."); | ||||||
|  |         } | ||||||
|         self.commands().add(PushChildren { |         self.commands().add(PushChildren { | ||||||
|             children: SmallVec::from(children), |             children: SmallVec::from(children), | ||||||
|             parent, |             parent, | ||||||
| @ -361,6 +387,9 @@ impl<'w, 's, 'a> BuildChildren for EntityCommands<'w, 's, 'a> { | |||||||
| 
 | 
 | ||||||
|     fn insert_children(&mut self, index: usize, children: &[Entity]) -> &mut Self { |     fn insert_children(&mut self, index: usize, children: &[Entity]) -> &mut Self { | ||||||
|         let parent = self.id(); |         let parent = self.id(); | ||||||
|  |         if children.contains(&parent) { | ||||||
|  |             panic!("Cannot insert entity as a child of itself."); | ||||||
|  |         } | ||||||
|         self.commands().add(InsertChildren { |         self.commands().add(InsertChildren { | ||||||
|             children: SmallVec::from(children), |             children: SmallVec::from(children), | ||||||
|             index, |             index, | ||||||
| @ -380,6 +409,9 @@ impl<'w, 's, 'a> BuildChildren for EntityCommands<'w, 's, 'a> { | |||||||
| 
 | 
 | ||||||
|     fn add_child(&mut self, child: Entity) -> &mut Self { |     fn add_child(&mut self, child: Entity) -> &mut Self { | ||||||
|         let parent = self.id(); |         let parent = self.id(); | ||||||
|  |         if child == parent { | ||||||
|  |             panic!("Cannot add entity as a child of itself."); | ||||||
|  |         } | ||||||
|         self.commands().add(AddChild { child, parent }); |         self.commands().add(AddChild { child, parent }); | ||||||
|         self |         self | ||||||
|     } |     } | ||||||
| @ -392,6 +424,9 @@ impl<'w, 's, 'a> BuildChildren for EntityCommands<'w, 's, 'a> { | |||||||
| 
 | 
 | ||||||
|     fn replace_children(&mut self, children: &[Entity]) -> &mut Self { |     fn replace_children(&mut self, children: &[Entity]) -> &mut Self { | ||||||
|         let parent = self.id(); |         let parent = self.id(); | ||||||
|  |         if children.contains(&parent) { | ||||||
|  |             panic!("Cannot replace entity as a child of itself."); | ||||||
|  |         } | ||||||
|         self.commands().add(ReplaceChildren { |         self.commands().add(ReplaceChildren { | ||||||
|             children: SmallVec::from(children), |             children: SmallVec::from(children), | ||||||
|             parent, |             parent, | ||||||
| @ -401,6 +436,9 @@ impl<'w, 's, 'a> BuildChildren for EntityCommands<'w, 's, 'a> { | |||||||
| 
 | 
 | ||||||
|     fn set_parent(&mut self, parent: Entity) -> &mut Self { |     fn set_parent(&mut self, parent: Entity) -> &mut Self { | ||||||
|         let child = self.id(); |         let child = self.id(); | ||||||
|  |         if child == parent { | ||||||
|  |             panic!("Cannot set parent to itself"); | ||||||
|  |         } | ||||||
|         self.commands().add(AddChild { child, parent }); |         self.commands().add(AddChild { child, parent }); | ||||||
|         self |         self | ||||||
|     } |     } | ||||||
| @ -466,6 +504,10 @@ pub trait BuildWorldChildren { | |||||||
|     /// If the children were previously children of another parent, that parent's [`Children`] component
 |     /// If the children were previously children of another parent, that parent's [`Children`] component
 | ||||||
|     /// will have those children removed from its list. Removing all children from a parent causes its
 |     /// will have those children removed from its list. Removing all children from a parent causes its
 | ||||||
|     /// [`Children`] component to be removed from the entity.
 |     /// [`Children`] component to be removed from the entity.
 | ||||||
|  |     ///
 | ||||||
|  |     /// # Panics
 | ||||||
|  |     ///
 | ||||||
|  |     /// Panics if the child is the same as the parent.
 | ||||||
|     fn add_child(&mut self, child: Entity) -> &mut Self; |     fn add_child(&mut self, child: Entity) -> &mut Self; | ||||||
| 
 | 
 | ||||||
|     /// Pushes children to the back of the builder's children. For any entities that are
 |     /// Pushes children to the back of the builder's children. For any entities that are
 | ||||||
| @ -474,12 +516,20 @@ pub trait BuildWorldChildren { | |||||||
|     /// If the children were previously children of another parent, that parent's [`Children`] component
 |     /// If the children were previously children of another parent, that parent's [`Children`] component
 | ||||||
|     /// will have those children removed from its list. Removing all children from a parent causes its
 |     /// will have those children removed from its list. Removing all children from a parent causes its
 | ||||||
|     /// [`Children`] component to be removed from the entity.
 |     /// [`Children`] component to be removed from the entity.
 | ||||||
|  |     ///
 | ||||||
|  |     /// # Panics
 | ||||||
|  |     ///
 | ||||||
|  |     /// Panics if any of the children are the same as the parent.
 | ||||||
|     fn push_children(&mut self, children: &[Entity]) -> &mut Self; |     fn push_children(&mut self, children: &[Entity]) -> &mut Self; | ||||||
|     /// Inserts children at the given index.
 |     /// Inserts children at the given index.
 | ||||||
|     ///
 |     ///
 | ||||||
|     /// If the children were previously children of another parent, that parent's [`Children`] component
 |     /// If the children were previously children of another parent, that parent's [`Children`] component
 | ||||||
|     /// will have those children removed from its list. Removing all children from a parent causes its
 |     /// will have those children removed from its list. Removing all children from a parent causes its
 | ||||||
|     /// [`Children`] component to be removed from the entity.
 |     /// [`Children`] component to be removed from the entity.
 | ||||||
|  |     ///
 | ||||||
|  |     /// # Panics
 | ||||||
|  |     ///
 | ||||||
|  |     /// Panics if any of the children are the same as the parent.
 | ||||||
|     fn insert_children(&mut self, index: usize, children: &[Entity]) -> &mut Self; |     fn insert_children(&mut self, index: usize, children: &[Entity]) -> &mut Self; | ||||||
|     /// Removes the given children
 |     /// Removes the given children
 | ||||||
|     ///
 |     ///
 | ||||||
| @ -491,6 +541,10 @@ pub trait BuildWorldChildren { | |||||||
|     /// If this entity already had a parent, the parent's [`Children`] component will have this
 |     /// If this entity already had a parent, the parent's [`Children`] component will have this
 | ||||||
|     /// child removed from its list. Removing all children from a parent causes its [`Children`]
 |     /// child removed from its list. Removing all children from a parent causes its [`Children`]
 | ||||||
|     /// component to be removed from the entity.
 |     /// component to be removed from the entity.
 | ||||||
|  |     ///
 | ||||||
|  |     /// # Panics
 | ||||||
|  |     ///
 | ||||||
|  |     /// Panics if the parent is the same as the child.
 | ||||||
|     fn set_parent(&mut self, parent: Entity) -> &mut Self; |     fn set_parent(&mut self, parent: Entity) -> &mut Self; | ||||||
| 
 | 
 | ||||||
|     /// Removes the [`Parent`] of this entity.
 |     /// Removes the [`Parent`] of this entity.
 | ||||||
| @ -511,6 +565,9 @@ impl<'w> BuildWorldChildren for EntityMut<'w> { | |||||||
| 
 | 
 | ||||||
|     fn add_child(&mut self, child: Entity) -> &mut Self { |     fn add_child(&mut self, child: Entity) -> &mut Self { | ||||||
|         let parent = self.id(); |         let parent = self.id(); | ||||||
|  |         if child == parent { | ||||||
|  |             panic!("Cannot add entity as a child of itself."); | ||||||
|  |         } | ||||||
|         self.world_scope(|world| { |         self.world_scope(|world| { | ||||||
|             update_old_parent(world, child, parent); |             update_old_parent(world, child, parent); | ||||||
|         }); |         }); | ||||||
| @ -525,6 +582,9 @@ impl<'w> BuildWorldChildren for EntityMut<'w> { | |||||||
| 
 | 
 | ||||||
|     fn push_children(&mut self, children: &[Entity]) -> &mut Self { |     fn push_children(&mut self, children: &[Entity]) -> &mut Self { | ||||||
|         let parent = self.id(); |         let parent = self.id(); | ||||||
|  |         if children.contains(&parent) { | ||||||
|  |             panic!("Cannot push entity as a child of itself."); | ||||||
|  |         } | ||||||
|         self.world_scope(|world| { |         self.world_scope(|world| { | ||||||
|             update_old_parents(world, parent, children); |             update_old_parents(world, parent, children); | ||||||
|         }); |         }); | ||||||
| @ -541,6 +601,9 @@ impl<'w> BuildWorldChildren for EntityMut<'w> { | |||||||
| 
 | 
 | ||||||
|     fn insert_children(&mut self, index: usize, children: &[Entity]) -> &mut Self { |     fn insert_children(&mut self, index: usize, children: &[Entity]) -> &mut Self { | ||||||
|         let parent = self.id(); |         let parent = self.id(); | ||||||
|  |         if children.contains(&parent) { | ||||||
|  |             panic!("Cannot insert entity as a child of itself."); | ||||||
|  |         } | ||||||
|         self.world_scope(|world| { |         self.world_scope(|world| { | ||||||
|             update_old_parents(world, parent, children); |             update_old_parents(world, parent, children); | ||||||
|         }); |         }); | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 张林伟
						张林伟