QuerySingle family of system params#15476
Conversation
|
The generated |
7896012 to
125002a
Compare
4bd9cd3 to
1b84446
Compare
| unsafe impl<'a, D: QueryData + 'static, F: QueryFilter + 'static> SystemParam | ||
| for Option<QuerySingle<'a, D, F>> |
There was a problem hiding this comment.
I wonder if now that we have validate_param we could use it to write a generic impl<S: SystemParam> SystemParam for Option<S>. This could be tackled in a separate PR though.
There was a problem hiding this comment.
Not every Option<P> makes sense, like Option<Query>
There was a problem hiding this comment.
Also, infinitely nested Options
There was a problem hiding this comment.
Right, though maybe this could be solved with a marker trait for those system parameters for which Option can make sense.
There was a problem hiding this comment.
If there is a decent way to derive it I'm down.
There are some cases where Option needs some specialized code, like in QuerySingle
| state.as_readonly().get_single_unchecked_manual( | ||
| world, | ||
| system_meta.last_run, | ||
| world.change_tick(), |
There was a problem hiding this comment.
Are we sure this is the change tick that will be used for calling get_param, or an equivalent one for what matters to it? If so could you write a comment explaining why that's the case?
There was a problem hiding this comment.
Practically yes, this happens to be the exact tick that is received by get_param, but there are not validation mechanisms/contract for that.
Currently only executors use validate_param and since the validation and running happens one after another, this is the correct change tick.
For run_systems and observers this also shouldn't be a problem.
While I can make validate_param accept a change_tick, the problem is that the tick used by get_param is generated inside run_unsafe, so we'd still need to uphold this "contract" of calling them back-to-back.
There was a problem hiding this comment.
I'm open for docs/mechanisms on making this better, I'm not sure how to go about it
There was a problem hiding this comment.
It won't always be exactly the same tick, because the multi-threaded executor will call validate_param and then spawn a task to run the system and call get_param at some later point. Another system could start in between and increment the current tick.
I think it will be equivalent, though. Any components read by this param can't be written by another system in between the calls, so they can't have an added or changed tick in between the two change_tick values.
There was a problem hiding this comment.
Okay, I'll try to thoroughly document this in validate_param
7509d02 to
9d0ab0f
Compare
| for QuerySingle<'a, D, F> | ||
| { | ||
| type State = QueryState<D, F>; | ||
| type Item<'w, 's> = QuerySingle<'w, D, F>; |
There was a problem hiding this comment.
Why isn't this just <D as QueryData>::Item? I think that would improve the ergonomics and complexity quite a bit?
There was a problem hiding this comment.
The ergonomics comment got removed, CI told me to remove unnecessary syntax which made it way better.
<D as WorldQuery>::Item is not a SystemParam so that's one issue with this.
Another would be, if SystemParam returns anything else than itself with changed lifetimes, it won't fit as the system argument.
fn my_system(q: QuerySingle<Entity>) { ... }
// imaginary executor code
let q: <Entity as WorldQuery>::Item = QuerySingle<Entity>::get_param(world);
system(q); // Expected `QuerySingle` got `<Entity as WorldQuery>::Item`# Objective Add the following system params: - `QuerySingle<D, F>` - Valid if only one matching entity exists, - `Option<QuerySingle<D, F>>` - Valid if zero or one matching entity exists. As @chescock pointed out, we don't need `Mut` variants. Fixes: bevyengine#15264 ## Solution Implement the type and both variants of system params. Also implement `ReadOnlySystemParam` for readonly queries. Added a new ECS example `fallible_params` which showcases `SingleQuery` usage. In the future we might want to add `NonEmptyQuery`, `NonEmptyEventReader` and `Res` to it (or maybe just stop at mentioning it). ## Testing Tested with the example. There is a lot of warning spam so we might want to implement bevyengine#15391.
|
Thank you to everyone involved with the authoring or reviewing of this PR! This work is relatively important and needs release notes! Head over to bevyengine/bevy-website#1701 if you'd like to help out. |
Objective
Add the following system params:
QuerySingle<D, F>- Valid if only one matching entity exists,Option<QuerySingle<D, F>>- Valid if zero or one matching entity exists.As @chescock pointed out, we don't need
Mutvariants.Fixes: #15264
Solution
Implement the type and both variants of system params.
Also implement
ReadOnlySystemParamfor readonly queries.Added a new ECS example
fallible_paramswhich showcasesSingleQueryusage.In the future we might want to add
NonEmptyQuery,NonEmptyEventReaderandResto it (or maybe just stop at mentioning it).Testing
Tested with the example.
There is a lot of warning spam so we might want to implement #15391.