Skip to content

Conversation

SkiFire13
Copy link
Contributor

@SkiFire13 SkiFire13 commented Jul 13, 2025

Objective

Solution

  • Switch everything to a depth-first order priority as @cart originally intended it.
  • Effectively revert Use register_dynamic for merging #18028, which tried to give priority to components with higher inheritance depth (i.e. with a breadth-first order priority).

Testing

Most existing tests pass, except a couple that were removed due to testing inheritance depth or the breadth-first order priority that this PR will remove.

Some tests were also added, some of which as regression tests and others to add more coverage.

@SkiFire13 SkiFire13 force-pushed the rework-required-components branch 2 times, most recently from 5362a26 to 8b14b9c Compare July 13, 2025 14:48
@alice-i-cecile alice-i-cecile added A-ECS Entities, components, systems, and events S-Blocked This cannot move forward until something else changes C-Bug An unexpected or incorrect behavior X-Contentious There are nontrivial implications that should be thought through labels Jul 14, 2025
@alice-i-cecile alice-i-cecile added this to the 0.17 milestone Jul 14, 2025
@alice-i-cecile alice-i-cecile added S-Needs-Review Needs reviewer attention (from anyone!) to move forward and removed S-Blocked This cannot move forward until something else changes labels Jul 14, 2025
@SkiFire13 SkiFire13 force-pushed the rework-required-components branch from 8b14b9c to 18c4ca4 Compare July 14, 2025 18:39
@alice-i-cecile
Copy link
Member

@SkiFire13 is this ready for review now that the bundle-split PR is merged? This is still in draft mode :)

@alice-i-cecile alice-i-cecile requested review from cart and Jondolf July 14, 2025 19:33
@SkiFire13 SkiFire13 marked this pull request as ready for review July 14, 2025 19:48
@SkiFire13
Copy link
Contributor Author

SkiFire13 commented Jul 14, 2025

@SkiFire13 is this ready for review now that the bundle-split PR is merged? This is still in draft mode :)

Ah yes, I was forgetting to change the status! I think it might still need some more tests, but the implementation should be ready.

@urben1680
Copy link
Contributor

I encountered an issue where a required component is not registered at all on main during my work on #19852. This PR seems to fix that too. That problem seems to be not among the issues listed here.

I try to review this the next days and if needed suggest another test if this is missing.

@SkiFire13
Copy link
Contributor Author

I added a few more tests, cleaned up some parts of the code and added a fix for #20173 (I would have preferred a separate PR but that ended up being requiring too many changes that would be included in this PR anyway)

Copy link
Contributor

@cBournhonesque cBournhonesque left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First pass, haven't looked in depth at required.rs

let explicit_components_len = component_ids.len();
let mut required_components = RequiredComponents::default();
for component_id in component_ids.iter().copied() {
let mut depth_first_components = IndexMap::<_, _, FixedHasher>::default();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If i understand correctly there could be 2 meanings to DFS:

  • if we add two components A and B at the same time in a bundle and they both required C, we want to add the version required by A because it appears first in the bundle list. This is the DFS performed here
  • if A requires B and C, and both B and C require D, we want to add the version required by B first because it appears first in the required list. This is handled somewhere else, probably at registration time (I have yet to review that)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. A way in which you can unify these two views is seeing a bundle as if it was directly requiring all its components, with the "default" value the one in the actual bundle.

Copy link
Contributor

@chescock chescock left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! The comments were extremely helpful in understanding some of the tricky parts, especially the step-by-step comments in register_required_components! I left some nits on things that tripped me up while I was reading it, but none of them should be blocking.

Entity,
MaybeLocation,
);
// If already registered as a direct required component then bail.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why ignore the new constructor instead of updating the registration? It looks like the old code did an update in this case.

Or, is this an error case and we should panic! or return an Err somehow?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The old code used to decide based on the given inheritance_depth. If we go by the new rules the second occurence of a duplicated direct required components would always "lose" to the first and hence be ignored, though I can see why this is not ideal. I'll try to see if we can update this to return a Result and/or panic (possibly with a try_ variant of the methods).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed this to panic for now. I'm not particularly a fan, but it's a bit awkward to return a RequiredComponentsError. Let me know what you (and others) think.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine with the decision to panic for now: this PR is already very involved.

@alice-i-cecile alice-i-cecile added D-Complex Quite challenging from either a design or technical perspective. Ask for help! C-Code-Quality A section of code that is hard to understand or change labels Jul 28, 2025
@alice-i-cecile alice-i-cecile changed the title Rework required components Ensure required components are consistently depth-first Jul 29, 2025
Copy link
Member

@alice-i-cecile alice-i-cecile left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is very complex, but extremely well-commented and has a robust set of tests. In the course of reviewing I've been convinced that this is the correct behavior, and I'm very happy to remove inheritance_depth.

Thanks for taking the time to do this well.

@alice-i-cecile alice-i-cecile added S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it and removed S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels Jul 29, 2025
@alice-i-cecile alice-i-cecile added this pull request to the merge queue Jul 29, 2025
Merged via the queue into bevyengine:main with commit 45c997c Jul 29, 2025
38 checks passed
tychedelia pushed a commit to tychedelia/bevy that referenced this pull request Jul 31, 2025
…0110)

# Objective

- Fixes bevyengine#19863 by removing `inheritance_depth`
- Fixed bevyengine#19333 by properly using depth-first order priority 
- Helps with bevyengine#19300 (not sure if it could be closed with this PR)
- Fixes bevyengine#20173
- Overall, fix the weird situation that required components are in,
where some operations respect a depth-first order priority while other
respect a breadth-first order priority.

## Solution

- Switch everything to a depth-first order priority as @cart originally
intended it.
- Effectively revert bevyengine#18028, which tried to give priority to components
with higher inheritance depth (i.e. with a breadth-first order
priority).

## Testing

Most existing tests pass, except a couple that were removed due to
testing inheritance depth or the breadth-first order priority that this
PR will remove.

Some tests were also added, some of which as regression tests and others
to add more coverage.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-ECS Entities, components, systems, and events C-Bug An unexpected or incorrect behavior C-Code-Quality A section of code that is hard to understand or change D-Complex Quite challenging from either a design or technical perspective. Ask for help! S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it X-Contentious There are nontrivial implications that should be thought through
Projects
None yet
5 participants