Disjoint QueryData access
- Dominant language
- Rust
- Stars
- 48.2k
- Forks
- 4.8k
- Avg merge
- 3d 22h
- Merged PRs (30d)
- 161
Description
## What problem does this solve or what need does it fill?
In generic contexts, or when you have really complex `QueryData` parameters, there is currently no way to have disjoint `QueryData` access in a single query iteration
For example, you have a generic system that changes Transform based on an output of the generic parameter:
```rust
trait EntitySystem {
Data: QueryData;
Out;
fn run(data: QueryItem) -> Self::Out;
}
fn change_transform>(mut query: Query>) {
for mut set in query.iter_mut() {
let desirable_translation = T::run(set.d0());
let mut transform = set.d1();
transform.translation = desirable_translation;
}
}
```
## What solution would you like?
For this feature request I will name such `QueryData` implementer `DataSet` (similar to how `ParamSet` for `SystemParam` was named)
Implementation would be similar to the `ParamSet` implementation.
Requires cloning `WorldQuery::Fetch` in call to `WorldQuery::fetch`
```rust
pub struct DataSet<'w, T: QueryData> {
fetch: T::Fetch<'w>,
entity: Entity,
table_row: TableRow,
}
```
## What alternative(s) have you considered?
Lose much performance and ergonomics.
or
Implement much simpler `Matches` query filter. Still loses much ergonomics.
There, `Matches` is the filter that allows iterating only on those entities could have iterated on `D` if it was in place of `Data` generict parameter of `Query`.
That would allow to:
```rust
fn alternative_function(query: Query>, mut set: ParamSet<(Query<(D0)>, Query<(D1)>)>) {
for entity in query.iter() {
let p0_query = set.p0();
let p0_data = p0_query.get_mut();
// Code with p0 ....
let p1_query = set.p1();
let p1_data = p1_query.get_mut();
// Code with p1 ....
}
}
```
or
```rust
fn alternative_function(mut set: ParamSet<(Query<(Entity, D0), Matches>, Query>)>) {
let mut p0_map = EntityHashMap::new();
for (entity, data) in set.p0().iter_mut() {
let result = calculation_for_p0(data);
p0_map.insert(entity, result);
}
for (entity, data) in set.p1().iter_mut() {
let p0_result = p0_hash_map.get_mut(&entity).unwrap();
// Actual code ...
}
}
```
Contributor guide
Assessment
This issue has not been assessed yet.