Experiment to mitigate StorageId union access patterns #16939
+433
−342
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Objective
In the query iteration code there are some types which rely on comments & programmer discipline to ensure correct access of fields:
StorageId
- a union ofArchetypeId
andTableId
QueryIterationCursor
- multiple fields are only valid, and some types vary, depending on a boolean value:QueryState
- similar to above:I asked why this wasn't achieved with an
enum
of some kind on Discord.Somebody replied saying the reasoning for this is historical (
is_dense
used to be derived from a const generic or similar), and my proposed enum refactoring was worth considering.This PR is my initial draft of that work to get feedback on direction. Further testing may be required, and currently no documentation comments have been written!
Solution
is_dense
before, we now do a single match on the enum.StorageId
type and made it a normalenum
rather thanunion
. I have then tried to only use this in places where the downsides are hopefully minimal, such as:is_dense
anyway)fold_over_storage_range
, but I'm open to people giving advice on how to proceed there, whether I should be braver (or not).ArchetypeId
orTableId
viadebug_checked_as_x()
unsafely, to still preserve the idea that when theQueryIter
knows whether the iteration is dense or not, it doesn't want to pay the cost of checking that again when being asked to iterate storage by aStorageId
. The old code didn't pay that cost, so I was wary of doing so. If people feel that this is overly cautious perf-wise, then I can make it safe and have it fail in some way (or whatever you suggest).Testing
bevy_ecs
unit tests, but don't know what else to do. Please advise! I'm also asking in #bevy_ecs on discord.