Conversation
alice-i-cecile
left a comment
There was a problem hiding this comment.
The example is great, but we probably also want a third query_state initialization showing how to init filter state.
|
Awesome work; thanks for the prompt response. This is a niche feature, but I think it will be useful as part of our "dynamic components" story. |
No problem, your prompt response is much more appreciated :) With this feature it is already possible to make a dynamic query by implementing |
|
Yep, I mostly wanted to hear if you thought it was useful :) The implementation is trivial, and the docs are great. |
|
I expect this is incredibly unsound as-is since it would let you construct a Having a way to do the goal of this PR does seem useful for dynamic queries and I think relations could make use of this too. |
|
Nice catch @BoxyUwU! While there is nothing unsafe that this function does, indeed we can incorrectly cast types as a consequence. There are two ways I see that this can be resolved.
|
|
The former is definitely safer. This would be a one time cost paid during system / query initialization, correct? |
|
no, |
|
Made the method unsafe and added the appropriate safety comment |
Currently the bevy/crates/bevy_ecs/src/storage/blob_vec.rs Lines 141 to 144 in d38a8df As I understand it, the point of the struct ComponentIdQuery(ComponentId);
struct ComponentIdQueryMut(ComponentId);
impl WorldQuery for ComponentIdQuery {
type Item = Ptr<'_>;
...
}
impl WorldQuery for ComponentIdQueryMut {
type Item = (PtrMut<'_>, &mut Ticks);
...
}is that currently trait WorldQuery: WorldQueryGats {
type State;
+ type Config;
- fn init_state(world: &mut World) -> Self::State;
+ fn init_state(world: &mut World, config: Self::Config) -> Self::State;
}where the current implementors set Then you can add impls of let query = QueryState<Vec<ComponentIdQuery>>::new_with_config(vec![my_component_id_1, my_component_id_2]); |
It's sort of difficult because this method is only unsafe when querying component references, but I reordered the safety comment to more strongly word the requirements for safety.
This is exactly right! However, this isn't the only use, one could likely implement world query for Your solution is definitely an improvement, however, I would like to prioritize minimal changes with this PR. Dynamic query work is still up for discussion on how it should be implemented, and I would like to avoid establishing any future design directions, and instead, work with the API surface as it is available today. |
e104365 to
6cbbb9d
Compare
I disagree with this, worldquery impls should be able to rely on the state being created from their own If the above is true then this API is also kind of Not Great, I would much prefer the solution @jakobhellermann proposes with a |
|
The problem I see is that I've tried the implementation suggested and it results in a lot of extra type constraints that need to be managed across the codebase, and due to the above, severely restricts the reusability of existing implementations.
Due to this restriction on While I agree that queries should be able to rely on their |
|
Yeah, the |
|
I think one could argue that having a default here is equally dangerous as providing the state outright, due to the potential implications of accidentally using a It results in a situation where you don't know whether The added benefit of this PR would be that you can avoid the added complication of manipulating type bounds. |
|
I posted a PR of my proposal: #6390 |
ae570b0 to
767efee
Compare
Improved doc comment Further improved doc Make QueryState::new_with_state unsafe Reorder safety comment Relax safety comment
767efee to
d3dfbfa
Compare
|
Resolved by #9774 |
Objective
Allows providing state to
QueryStatewhich requires input other thanWorldQuery::init_state(&mut World)to be constructed.This allows the user to provide a custom state such as
ComponentIdfor dynamic queries which cannot be derived from the type definition.Solution
Create new method
QueryState::new_with_state, which is now called byQueryState::newusingWorldQuery::init_state.