add try_insert to entity commands#9844
Merged
james7132 merged 6 commits intobevyengine:mainfrom Sep 20, 2023
Merged
Conversation
Contributor
|
Welcome, new contributor! Please make sure you've read our contributing guide and we look forward to reviewing your pull request shortly ✨ |
nicopap
reviewed
Sep 19, 2023
Contributor
nicopap
left a comment
There was a problem hiding this comment.
Looks good, I think we should merge this. I'd like to see minor adjustments though.
| /// | ||
| /// fn add_combat_stats_system(mut commands: Commands, player: Res<PlayerEntity>) { | ||
| /// | ||
| /// commands.entity(player.entity) |
Contributor
There was a problem hiding this comment.
Suggested change
| /// commands.entity(player.entity) | |
| /// commands.entity(player.entity) |
| /// health: Health(100), | ||
| /// strength: Strength(40), | ||
| /// }); | ||
| /// |
Contributor
There was a problem hiding this comment.
For the lulz (and illustration) I'd add this line
Suggested change
| /// | |
| /// commands.entity(player.entity).despawn(); |
Edit: Actually this should be moved before the insert.
| if let Some(mut entity) = world.get_entity_mut(self.entity) { | ||
| entity.insert(self.bundle); | ||
| } else { | ||
| info!("error[B0003]: Could not insert a bundle (of type `{}`) for entity {:?} because it doesn't exist in this World.", std::any::type_name::<T>(), self.entity); |
Contributor
There was a problem hiding this comment.
Suggested change
| info!("error[B0003]: Could not insert a bundle (of type `{}`) for entity {:?} because it doesn't exist in this World.", std::any::type_name::<T>(), self.entity); | |
| debug!("[B0003]: Could not insert a bundle (of type `{}`) for entity {:?} because it doesn't exist in this World.", std::any::type_name::<T>(), self.entity); |
joseph-gio
reviewed
Sep 20, 2023
| if let Some(mut entity) = world.get_entity_mut(self.entity) { | ||
| entity.insert(self.bundle); | ||
| } else { | ||
| info!("error[B0003]: Could not insert a bundle (of type `{}`) for entity {:?} because it doesn't exist in this World.", std::any::type_name::<T>(), self.entity); |
Member
There was a problem hiding this comment.
This log seems like unnecessary noise. If someone calls try_insert that means they don't care about this "error" case, so we can safely ignore it.
joseph-gio
reviewed
Sep 20, 2023
| /// | ||
| /// # Note | ||
| /// | ||
| /// The command will not panic if the associated entity does not exist. |
Member
There was a problem hiding this comment.
Suggested change
| /// The command will not panic if the associated entity does not exist. | |
| /// Unlike [`Self::insert`], this command will not panic if the associated entity does not exist. |
Contributor
Author
|
okay updated based on fdbk |
joseph-gio
approved these changes
Sep 20, 2023
james7132
approved these changes
Sep 20, 2023
rdrpenguin04
pushed a commit
to rdrpenguin04/bevy
that referenced
this pull request
Jan 9, 2024
# Objective - I spoke with some users in the ECS channel of bevy discord today and they suggested that I implement a fallible form of .insert for components. - In my opinion, it would be nice to have a fallible .insert like .try_insert (or to just make insert be fallible!) because it was causing a lot of panics in my game. In my game, I am spawning terrain chunks and despawning them in the Update loop. However, this was causing bevy_xpbd to panic because it was trying to .insert some physics components on my chunks and a race condition meant that its check to see if the entity exists would pass but then the next execution step it would not exist and would do an .insert and then panic. This means that there is no way to avoid a panic with conditionals. Luckily, bevy_xpbd does not care about inserting these components if the entity is being deleted and so if there were a .try_insert, like this PR provides it could use that instead in order to NOT panic. ( My interim solution for my own game has been to run the entity despawn events in the Last schedule but really this is just a hack and I should not be expected to manage the scheduling of despawns like this - it should just be easy and simple. IF it just so happened that bevy_xpbd ran .inserts in the Last schedule also, this would be an untenable soln overall ) ## Solution - Describe the solution used to achieve the objective above. Add a new command named TryInsert (entitycommands.try_insert) which functions exactly like .insert except if the entity does not exist it will not panic. Instead, it will log to info. This way, crates that are attaching components in ways which they do not mind that the entity no longer exists can just use try_insert instead of insert. --- ## Changelog ## Additional Thoughts In my opinion, NOT panicing should really be the default and having an .insert that does panic should be the odd edgecase but removing the panic! from .insert seems a bit above my paygrade -- although i would love to see it. My other thought is it would be good for .insert to return an Option AND not panic but it seems it uses an event bus right now so that seems to be impossible w the current architecture.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Objective
I spoke with some users in the ECS channel of bevy discord today and they suggested that I implement a fallible form of .insert for components.
In my opinion, it would be nice to have a fallible .insert like .try_insert (or to just make insert be fallible!) because it was causing a lot of panics in my game. In my game, I am spawning terrain chunks and despawning them in the Update loop. However, this was causing bevy_xpbd to panic because it was trying to .insert some physics components on my chunks and a race condition meant that its check to see if the entity exists would pass but then the next execution step it would not exist and would do an .insert and then panic. This means that there is no way to avoid a panic with conditionals.
Luckily, bevy_xpbd does not care about inserting these components if the entity is being deleted and so if there were a .try_insert, like this PR provides it could use that instead in order to NOT panic.
( My interim solution for my own game has been to run the entity despawn events in the Last schedule but really this is just a hack and I should not be expected to manage the scheduling of despawns like this - it should just be easy and simple. IF it just so happened that bevy_xpbd ran .inserts in the Last schedule also, this would be an untenable soln overall )
Solution
Add a new command named TryInsert (entitycommands.try_insert) which functions exactly like .insert except if the entity does not exist it will not panic. Instead, it will log to info. This way, crates that are attaching components in ways which they do not mind that the entity no longer exists can just use try_insert instead of insert.
Changelog
Additional Thoughts
In my opinion, NOT panicing should really be the default and having an .insert that does panic should be the odd edgecase but removing the panic! from .insert seems a bit above my paygrade -- although i would love to see it. My other thought is it would be good for .insert to return an Option AND not panic but it seems it uses an event bus right now so that seems to be impossible w the current architecture.