Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Merged by Bors] - Hierarchy commandization #4197

Closed
wants to merge 24 commits into from

Conversation

james7132
Copy link
Member

@james7132 james7132 commented Mar 13, 2022

Objective

Implement absolute minimum viable product for the changes proposed in bevyengine/rfcs#53.

Solution

  • Remove public mutative access to Parent (Children is already publicly read-only). This includes public construction methods like Copy, Clone, and Default.
  • Remove PreviousParent
  • Remove parent_update_system
  • Update all hierarchy related commands to immediately update both Parent and Children references.

Remaining TODOs

  • Update documentation for both Parent and Children. Discourage using EntityCommands::remove
  • Add HierarchyEvent to notify listeners of hierarchy updates. This is meant to replace listening on PreviousParent

Followup

  • These changes should be best moved to the hooks mentioned in Entity-entity relations 🌈  #3742.
  • Backing storage for both might be best moved to indexes mentioned in the same relations.

@github-actions github-actions bot added the S-Needs-Triage This issue needs to be labelled label Mar 13, 2022
@james7132 james7132 added S-Needs-Design-Doc This issue or PR is particularly complex, and needs an approved design doc before it can be merged A-Transform Translations, rotations and scales and removed S-Needs-Triage This issue needs to be labelled labels Mar 13, 2022
@alice-i-cecile alice-i-cecile added the C-Usability A targeted quality-of-life change that makes Bevy easier to use label Mar 13, 2022
@alice-i-cecile
Copy link
Member

We should probably merge #4168 before merging this, but I can do more rebasing if needed...

@james7132
Copy link
Member Author

We should probably merge #4168 before merging this, but I can do more rebasing if needed...

The intention is that this won't be merged until we have bevyengine/rfcs#53 is merged. Still quite some hefty few TODOs here too.

@james7132 james7132 removed the S-Needs-Design-Doc This issue or PR is particularly complex, and needs an approved design doc before it can be merged label May 30, 2022
@james7132
Copy link
Member Author

The associated RFC has been merged. I'll update the PR to match the design there.

@SkiFire13
Copy link
Contributor

I'm suprised this compiles. This looks unsound. Doesn't the inner remove invalidate the get_mut on the outside?

fn remove_from_children(world: &mut World, parent: Entity, child: Entity) {
    let mut parent = world.entity_mut(parent);
    if let Some(mut children) = parent.get_mut::<Children>() {
        if let Some(idx) = children.iter().position(|x| *x == child) {
            children.0.remove(idx);
            if children.is_empty() {
                parent.remove::<Children>();
            }
        }
    }
}

This is normal behaviour with NLL: children's last use is before the remove so the borrow is released.

@james7132 james7132 requested a review from BoxyUwU July 1, 2022 23:25
Copy link
Member

@cart cart left a comment

Choose a reason for hiding this comment

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

Generally looks good to me!

}
let mut parent = world.entity_mut(self.parent);
if let Some(mut children) = parent.get_mut::<Children>() {
if !children.contains(&self.child) {
Copy link
Member

Choose a reason for hiding this comment

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

Is this check necessary? Given that this is now transactional, won't children only contain child if child already has the Parent component pointing to self.parent? In that case, the update_parent call would have returned Some(self.parent) and AddChild would early return on line 101.

Copy link
Member Author

Choose a reason for hiding this comment

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

Not doing this check could result in duplicate children if the hierarchy is altered directly via World. It's highly unlikely given that there's no easy way to make those edits, but it is doable.

Copy link
Member

Choose a reason for hiding this comment

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

Reasonable. O(n) behavior (especially in the context of something that will likely happen regularly at runtime) is nasty enough that I think its worth considering omitting this check. But thats a controversial enough conversation that its probably worth having separately and biasing toward correctness here.

@cart
Copy link
Member

cart commented Jul 10, 2022

bors r+

bors bot pushed a commit that referenced this pull request Jul 10, 2022
## Objective
Implement absolute minimum viable product for the changes proposed in bevyengine/rfcs#53.

## Solution

 - Remove public mutative access to `Parent` (Children is already publicly read-only). This includes public construction methods like `Copy`, `Clone`, and `Default`.
 - Remove `PreviousParent`
 - Remove `parent_update_system`
 - Update all hierarchy related commands to immediately update both `Parent` and `Children` references.

## Remaining TODOs

 - [ ] Update documentation for both `Parent` and `Children`. Discourage using `EntityCommands::remove`
 - [x] Add `HierarchyEvent` to notify listeners of hierarchy updates. This is meant to replace listening on `PreviousParent`

## Followup

 - These changes should be best moved to the hooks mentioned in #3742.
 - Backing storage for both might be best moved to indexes mentioned in the same relations.
@bors bors bot changed the title Hierarchy commandization [Merged by Bors] - Hierarchy commandization Jul 10, 2022
@bors bors bot closed this Jul 10, 2022
bors bot pushed a commit that referenced this pull request Aug 5, 2022
#4197 intended to remove all `pub` constructors of `Children` and `Parent` and it seems like this one was missed.

Co-authored-by: devil-ira <justthecooldude@gmail.com>
inodentry pushed a commit to IyesGames/bevy that referenced this pull request Aug 8, 2022
## Objective
Implement absolute minimum viable product for the changes proposed in bevyengine/rfcs#53.

## Solution

 - Remove public mutative access to `Parent` (Children is already publicly read-only). This includes public construction methods like `Copy`, `Clone`, and `Default`.
 - Remove `PreviousParent`
 - Remove `parent_update_system`
 - Update all hierarchy related commands to immediately update both `Parent` and `Children` references.

## Remaining TODOs

 - [ ] Update documentation for both `Parent` and `Children`. Discourage using `EntityCommands::remove`
 - [x] Add `HierarchyEvent` to notify listeners of hierarchy updates. This is meant to replace listening on `PreviousParent`

## Followup

 - These changes should be best moved to the hooks mentioned in bevyengine#3742.
 - Backing storage for both might be best moved to indexes mentioned in the same relations.
maccesch pushed a commit to Synphonyte/bevy that referenced this pull request Sep 28, 2022
bevyengine#4197 intended to remove all `pub` constructors of `Children` and `Parent` and it seems like this one was missed.

Co-authored-by: devil-ira <justthecooldude@gmail.com>
james7132 added a commit to james7132/bevy that referenced this pull request Oct 28, 2022
## Objective
Implement absolute minimum viable product for the changes proposed in bevyengine/rfcs#53.

## Solution

 - Remove public mutative access to `Parent` (Children is already publicly read-only). This includes public construction methods like `Copy`, `Clone`, and `Default`.
 - Remove `PreviousParent`
 - Remove `parent_update_system`
 - Update all hierarchy related commands to immediately update both `Parent` and `Children` references.

## Remaining TODOs

 - [ ] Update documentation for both `Parent` and `Children`. Discourage using `EntityCommands::remove`
 - [x] Add `HierarchyEvent` to notify listeners of hierarchy updates. This is meant to replace listening on `PreviousParent`

## Followup

 - These changes should be best moved to the hooks mentioned in bevyengine#3742.
 - Backing storage for both might be best moved to indexes mentioned in the same relations.
james7132 pushed a commit to james7132/bevy that referenced this pull request Oct 28, 2022
bevyengine#4197 intended to remove all `pub` constructors of `Children` and `Parent` and it seems like this one was missed.

Co-authored-by: devil-ira <justthecooldude@gmail.com>
@james7132 james7132 deleted the hierarchy-commandization branch December 12, 2022 06:45
ItsDoot pushed a commit to ItsDoot/bevy that referenced this pull request Feb 1, 2023
## Objective
Implement absolute minimum viable product for the changes proposed in bevyengine/rfcs#53.

## Solution

 - Remove public mutative access to `Parent` (Children is already publicly read-only). This includes public construction methods like `Copy`, `Clone`, and `Default`.
 - Remove `PreviousParent`
 - Remove `parent_update_system`
 - Update all hierarchy related commands to immediately update both `Parent` and `Children` references.

## Remaining TODOs

 - [ ] Update documentation for both `Parent` and `Children`. Discourage using `EntityCommands::remove`
 - [x] Add `HierarchyEvent` to notify listeners of hierarchy updates. This is meant to replace listening on `PreviousParent`

## Followup

 - These changes should be best moved to the hooks mentioned in bevyengine#3742.
 - Backing storage for both might be best moved to indexes mentioned in the same relations.
ItsDoot pushed a commit to ItsDoot/bevy that referenced this pull request Feb 1, 2023
bevyengine#4197 intended to remove all `pub` constructors of `Children` and `Parent` and it seems like this one was missed.

Co-authored-by: devil-ira <justthecooldude@gmail.com>
alice-i-cecile pushed a commit that referenced this pull request May 1, 2023
# Objective

- For many UI use cases (e.g. tree views, lists), it is important to be
able to imperatively sort child nodes.
- This also enables us to eventually support something like the
[`order`](https://developer.mozilla.org/en-US/docs/Web/CSS/order) CSS
property, that declaratively re-orders flex box items by a numeric
value, similar to z-index, but in space.

## Solution

We removed the ability to directly construct `Children` from `&[Entity]`
some time ago (#4197 #5532) to enforce consistent hierarchies ([RFC
53](https://github.com/bevyengine/rfcs/blob/main/rfcs/53-consistent-hierarchy.md)).
If I understand it correctly, it's currently possible to re-order
children by using `Children::swap()` or
`commands.entity(id).replace_children(...)`, however these are either
too cumbersome, needlessly inefficient, and/or don't take effect
immediately.

This PR exposes the in-place sorting methods from the `slice` primitive
in `Children`, enabling imperatively sorting children in place via `&mut
Children`, while still preserving consistent hierarchies.

---

## Changelog
### Added
- The sorting methods from the `slice` primitive are now exposed by the
`Children` component, allowing imperatively sorting children in place
(Useful for UI scenarios such as lists)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Transform Translations, rotations and scales C-Usability A targeted quality-of-life change that makes Bevy easier to use
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

6 participants