-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Allow users to choose how Commands and EntityCommands should fail
#15929
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
I don't know how to do Tracy stuff, but I ran the "spawn_commands" benchmark which does this: and got these results: |
EntityCommands should fail if the entity is missingCommands and EntityCommands should fail
|
Maybe controversial, but since invalid |
also handled failure properly in `insert_batch_with_caller`
|
I benchmarked again with a modified version of main versionthis PR versionand got these results: So,
tl;dr: there's maybe a 1% performance impact across the board, if you don't want to call that noise. Should note that |
|
Bikeshedding: I thought a "failure mode" or a "mode of failure" is the way something went wrong. This type/field describes the strategy for handling when something goes wrong. |
|
Hadn't heard of that, but that does seem to be the case. Maybe just Totally open to more bikeshedding, I'm not committed to any of the names here |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I love it!
`failure_mode` and `FailureMode` are now `failure_handling_mode` and `FailureHandlingMode`
also undo `despawn` change
## Objective I was resolving a conflict between #16132 and my PR #15929 and thought the `clone_entity` commands made more sense in `EntityCommands`. ## Solution Moved `Commands::clone_entity` to `EntityCommands::clone`, moved `Commands::clone_entity_with` to `EntityCommands::clone_with`. ## Testing Ran the two tests that used the old methods. ## Showcase ``` // Create a new entity and keep its EntityCommands. let mut entity = commands.spawn((ComponentA(10), ComponentB(20))); // Create a clone of the first entity let mut entity_clone = entity.clone(); ``` The only potential downside is that the method name is now the same as the one from the `Clone` trait. `EntityCommands` doesn't implement `Clone` though, so there's no actual conflict. Maybe I'm biased because this'll work better with my PR, but I think the UX is nicer regardless.
|
Closing in favor of your newer #17043. |
## Objective I was resolving a conflict between bevyengine#16132 and my PR bevyengine#15929 and thought the `clone_entity` commands made more sense in `EntityCommands`. ## Solution Moved `Commands::clone_entity` to `EntityCommands::clone`, moved `Commands::clone_entity_with` to `EntityCommands::clone_with`. ## Testing Ran the two tests that used the old methods. ## Showcase ``` // Create a new entity and keep its EntityCommands. let mut entity = commands.spawn((ComponentA(10), ComponentB(20))); // Create a clone of the first entity let mut entity_clone = entity.clone(); ``` The only potential downside is that the method name is now the same as the one from the `Clone` trait. `EntityCommands` doesn't implement `Clone` though, so there's no actual conflict. Maybe I'm biased because this'll work better with my PR, but I think the UX is nicer regardless.






Objective
Solution
Added the following
Commands:ignore_on_errorlog_on_error(sends messages usinginfo!)warn_on_error(sends messages usingwarn!)panic_on_errorand the following
EntityCommands:ignore_if_missinglog_if_missingwarn_if_missingpanic_if_missingThese change how subsequent commands will respond if errors occur.
Internally:
failure_handling_modefield toCommands.Commandor anEntityCommandis queued, this field is sent with it.Commands should check for errors themselves.EntityCommandis applied, it automatically checks if the entity exists.failure_handling_modeto determine how to respond.Showcase
Review Notes
The real changes are all in
system/commands/mod.rsandworld/mod.rs.All the other files are just returning some commands to their old behavior:
despawn()->warn_if_missing().despawn()remove()->ignore_if_missing().remove()These two are the only commands that both 1) didn't already panic by default and 2) were used internally (according to VS Code's "Find All References" anyway).
They might not all need to be kept non-panicking, I just didn't want to regress anything.
Bikeshedding
ignorevssilentvs something else?failure_handling_modevsfailure_responsevs something else? (Used to befailure_mode, but that's wrong)info!vsdebug!?Possible Additions / Future PRs
try_variants of commandsLocation::callerin the user-facing command (if not set toignore) and pass it in, so the user can see exactly which command caused an error. Didn't seem to hurt performance meaningfully in my testing, but maybe I'm not the best at benchmarking.CommandsusingResultResultfrom a command to the caller, but we could wrap commands in something that handles anyErrreturned from the internal function call.Migration Guide
The following commands that used to fail silently will now panic by default:
EntityCommands::removeEntityCommands::remove_by_idEntityCommands::remove_with_requiresEntityCommands::clearEntityCommands::retainEntityCommands::observeEntityEntryCommands::and_modifyUse
ignore_if_missingto achieve the previous behavior:The command
EntityCommands::despawnused to warn upon failure and will now panic by default.Use
warn_if_missingto achieve the previous behavior:tryvariants of commands are unchanged and will always fail silently; these will be removed in the future.