Improve the docs for ChildOf and Children (#17886)
# Context Renaming `Parent` to `ChildOf` in #17247 has been contentious. While those users concerns are valid (especially around legibility of code IMO!), @cart [has decided](https://discord.com/channels/691052431525675048/749335865876021248/1340434322833932430) to stick with the new name. > In general this conversation is unsurprising to me, as it played out essentially the same way when I asked for opinions in my PR. There are strong opinions on both sides. Everyone is right in their own way. > > I chose ChildOf for the following reasons: > > 1. I think it derives naturally from the system we have built, the concepts we have chosen, and how we generally name the types that implement a trait in Rust. This is the name of the type implementing Relationship. We are adding that Relationship component to a given entity (whether it "is" the relationship or "has" the relationship is kind of immaterial ... we are naming the relationship that it "is" or "has"). What is the name of the relationship that a child has to its parent? It is a "child" of the parent of course! > 2. In general the non-parent/child relationships I've seen in the wild generally benefit from (or need to) use the naming convention in (1) (aka calling the Relationship the name of the relationship the entity has). Many relationships don't have an equivalent to the Parent/Child name concept. > 3. I do think we could get away with using (1) for pretty much everything else and special casing Parent/Children. But by embracing the naming convention, we help establish that this is in fact a pattern, and we help prime people to think about these things in a consistent way. Consistency and predictability is a generally desirable property. And for something as divisive and polarizing as relationship naming, I think drawing a hard line in the sand is to the benefit of the community as a whole. > 4. I believe the fact that we dont see as much of the XOf naming style elsewhere is to our benefit. When people see things in that style, they are primed to think of them as relationships (after some exposure to Bevy and the ecosystem). I consider this a useful hint. > 5. Most of the practical confusion from using ChildOf seems to be from calling the value of the target field we read from the relationship child_of. The name of the target field should be parent (we could even consider renaming child_of.0 to child_of.parent for clarity). I suspect that existing Bevy users renaming their existing code will feel the most friction here, as this requires a reframing. Imo it is natural and expected to receive pushback from these users hitting this case. ## Objective The new documentation doesn't do a particularly good job at quickly explaining the meaning of each component or how to work with them; making a tricky migration more painful and slowing down new users as they learn about some of the most fundamental types in Bevy. ## Solution 1. Clearly explain what each component does in the very first line, assuming no background knowledge. This is the first relationships that 99% of users will encounter, so explaining that they are relationships is unhelpful as an introduction. 2. Add doc aliases for the rejected `IsParent`/`IsChild`/`Parent` names, to improve autocomplete and doc searching. 3. Do some assorted docs cleanup while we're here. --------- Co-authored-by: Eagster <79881080+ElliottjPierce@users.noreply.github.com>
This commit is contained in:
parent
ee44560523
commit
be3c6f7578
@ -22,7 +22,9 @@ use core::slice;
|
||||
use disqualified::ShortName;
|
||||
use log::warn;
|
||||
|
||||
/// A [`Relationship`](crate::relationship::Relationship) component that creates the canonical
|
||||
/// Stores the parent entity of this child entity with this component.
|
||||
///
|
||||
/// This is a [`Relationship`](crate::relationship::Relationship) component, and creates the canonical
|
||||
/// "parent / child" hierarchy. This is the "source of truth" component, and it pairs with
|
||||
/// the [`Children`] [`RelationshipTarget`](crate::relationship::RelationshipTarget).
|
||||
///
|
||||
@ -31,7 +33,6 @@ use log::warn;
|
||||
/// 1. Organizing entities in a scene
|
||||
/// 2. Propagating configuration or data inherited from a parent, such as "visibility" or "world-space global transforms".
|
||||
/// 3. Ensuring a hierarchy is despawned when an entity is despawned.
|
||||
/// 4.
|
||||
///
|
||||
/// [`ChildOf`] contains a single "target" [`Entity`]. When [`ChildOf`] is inserted on a "source" entity,
|
||||
/// the "target" entity will automatically (and immediately, via a component hook) have a [`Children`]
|
||||
@ -92,10 +93,11 @@ use log::warn;
|
||||
reflect(Component, PartialEq, Debug, FromWorld)
|
||||
)]
|
||||
#[relationship(relationship_target = Children)]
|
||||
#[doc(alias = "IsChild", alias = "Parent")]
|
||||
pub struct ChildOf(pub Entity);
|
||||
|
||||
impl ChildOf {
|
||||
/// Returns the "target" entity.
|
||||
/// Returns the parent entity, which is the "target" of this relationship.
|
||||
pub fn get(&self) -> Entity {
|
||||
self.0
|
||||
}
|
||||
@ -121,15 +123,29 @@ impl FromWorld for ChildOf {
|
||||
}
|
||||
}
|
||||
|
||||
/// A [`RelationshipTarget`](crate::relationship::RelationshipTarget) collection component that is populated
|
||||
/// Tracks which entities are children of this parent entity.
|
||||
///
|
||||
/// A [`RelationshipTarget`] collection component that is populated
|
||||
/// with entities that "target" this entity with the [`ChildOf`] [`Relationship`](crate::relationship::Relationship) component.
|
||||
///
|
||||
/// Together, these components form the "canonical parent-child hierarchy". See the [`ChildOf`] component for all full
|
||||
/// Together, these components form the "canonical parent-child hierarchy". See the [`ChildOf`] component for the full
|
||||
/// description of this relationship and instructions on how to use it.
|
||||
///
|
||||
/// # Usage
|
||||
///
|
||||
/// Like all [`RelationshipTarget`] components, this data should not be directly manipulated to avoid desynchronization.
|
||||
/// Instead, modify the [`ChildOf`] components on the "source" entities.
|
||||
///
|
||||
/// To access the children of an entity, you can iterate over the [`Children`] component,
|
||||
/// using the [`IntoIterator`] trait.
|
||||
/// For more complex access patterns, see the [`RelationshipTarget`] trait.
|
||||
///
|
||||
/// [`RelationshipTarget`]: crate::relationship::RelationshipTarget
|
||||
#[derive(Component, Default, Debug, PartialEq, Eq)]
|
||||
#[relationship_target(relationship = ChildOf, linked_spawn)]
|
||||
#[cfg_attr(feature = "bevy_reflect", derive(bevy_reflect::Reflect))]
|
||||
#[cfg_attr(feature = "bevy_reflect", reflect(Component, FromWorld))]
|
||||
#[doc(alias = "IsParent")]
|
||||
pub struct Children(Vec<Entity>);
|
||||
|
||||
impl<'a> IntoIterator for &'a Children {
|
||||
|
Loading…
Reference in New Issue
Block a user