-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
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
Allow users to choose how Commands
and EntityCommands
should fail
#15929
base: main
Are you sure you want to change the base?
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 version
this PR version
and 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.
Objective
Solution
Added the following
Commands
:ignore_on_error
log_on_error
(sends messages usinginfo!
)warn_on_error
(sends messages usingwarn!
)panic_on_error
and the following
EntityCommands
:ignore_if_missing
log_if_missing
warn_if_missing
panic_if_missing
These change how subsequent commands will respond if errors occur.
Internally:
failure_handling_mode
field toCommands
.Command
or anEntityCommand
is queued, this field is sent with it.Command
s should check for errors themselves.EntityCommand
is applied, it automatically checks if the entity exists.failure_handling_mode
to determine how to respond.Showcase
Review Notes
The real changes are all in
system/commands/mod.rs
andworld/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
ignore
vssilent
vs something else?failure_handling_mode
vsfailure_response
vs something else? (Used to befailure_mode
, but that's wrong)info!
vsdebug!
?Possible Additions / Future PRs
try_
variants of commandsLocation::caller
in 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.Commands
usingResult
Result
from a command to the caller, but we could wrap commands in something that handles anyErr
returned from the internal function call.Migration Guide
The following commands that used to fail silently will now panic by default:
EntityCommands::remove
EntityCommands::remove_by_id
EntityCommands::remove_with_requires
EntityCommands::clear
EntityCommands::retain
EntityCommands::observe
EntityEntryCommands::and_modify
Use
ignore_if_missing
to achieve the previous behavior:The command
EntityCommands::despawn
used to warn upon failure and will now panic by default.Use
warn_if_missing
to achieve the previous behavior:try
variants of commands are unchanged and will always fail silently; these will be removed in the future.