Conversation
f4f433e to
cabaf73
Compare
# Objective The current query iterators cannot be used in positions with a `Debug` bound. F.e. when they are packaged in `Result` in the error position, `expect` cannot be called on them. Required for `QueryManyIter::entities_all_unique` in #13477. ## Solution Add simple `Debug` impls that print the query iterator names. ## Changelog `QueryIter`, `QueryManyIter`, `QueryCombinationIter`, and `QuerySortedIter` now implement `Debug`.
cabaf73 to
3c502c4
Compare
crates/bevy_ecs/src/query/iter.rs
Outdated
| { | ||
| // Entities are guaranteed to be unique, so no lifetime shrinking needed for mutable iteration. | ||
| #[inline(always)] | ||
| fn fetch_next(&mut self) -> Option<D::Item<'w>> { |
There was a problem hiding this comment.
This duplicates the code in QueryManyIter::fetch_next_aliased_unchecked(). Could you share the implementation by having QueryManyUniqueIter wrap a whole QueryManyIter, and then implement Iterator::next() by calling fetch_next_aliased_unchecked() on the inner QueryManyIter?
There was a problem hiding this comment.
IIRC, I was not sure whether the uniqueness property could simplify the next() call, so I kept them separate, but looking at it again, you're right, this can just be wrapper type! Good idea.
| /// # schedule.run(&mut world); | ||
| /// ``` | ||
| #[inline(always)] | ||
| pub fn entities_all_unique( |
There was a problem hiding this comment.
It might be useful to have methods to construct a QueryManyUniqueIter directly from a few iterator types that can already guarantee uniqueness, such as HashSet. That could let users skip the overhead of the uniqueness check.
It might also be useful to have a method that removes duplicates instead of returning Err, by doing something like
entity_iter: self
.entity_iter
.map(|e| *e.borrow())
.collect::<EntityHashSet>()
.into_iter(),(Those could always be done in future PRs, of course.)
There was a problem hiding this comment.
I agree with the methods to construct from unique iterators. What other source iterator types would you suggest?
Deduplication can already be done on the iterator itself with itertools, so isn't as important to have as the others. Still a nice to have though.
I wonder whether a sort + dedup would be faster than your HashSet version.
Edit: Actually just collecting into a BTreeSet might be simpler and faster. None of these retain input order however, that would be more expensive.
I think I'll make these separate follow-up PRs, since I have to keep these changes in line with #13443.
There was a problem hiding this comment.
I have added dedup_entities on QueryManyIter to this PR anyway.
also adds: a Debug impl associated type bounds in the struct and impl definitions a missing unsafe block in QueryManyIter
| .get(location.archetype_id) | ||
| .debug_checked_unwrap(); | ||
| let table = self.tables.get(location.table_id).debug_checked_unwrap(); | ||
| let (archetype, table); |
There was a problem hiding this comment.
This is good cleanup, but could probably be a separate PR.
There was a problem hiding this comment.
Fair, I'll put it in a different PR.
|
I wonder whether it might be easier to have a direct |
|
I have come up with a more powerful, general solution, which I think I will put in a different PR. I'll keep this open as the simpler alternative.
|
|
This PR is now superseded by the concept of #16547, though the actual conversion API would be a follow-up to that PR. |
|
#16547 has merged. |
Objective
Requires #13476.Currently we cannot iterate mutably over
QueryManyItereven if all entities we pass are unique.Solution
Add a
QueryManyUniqueIterwrapper aroundQueryManyIterfor fullIteratortrait iteration.It can be constructed via either the
dedup_entitiesorentities_all_uniquemethod onQueryManyIter.dedup_entitiesdeduplicates the internalentity_iter, retaining order.entities_all_uniquetakesself, checks for uniqueness, returnsQueryManyUniqueIteron success, andQueryManyIter(Self) on failure.Since
QueryManyUniqueItercan iterate over mutableQueryData, it does not expose afetch_nextmethod.Testing
The example/doc test shows the method in use, also making sure
expectcan be called on the returnResult.Changelog
Added
dedup_entitiesandentities_all_uniquemethods onQueryManyIter.Added
QueryManyUniqueIterstruct.