Skip to content

Commit

Permalink
Apply documentation suggestions from code review
Browse files Browse the repository at this point in the history
Co-authored-by: Federico Rinaldi <gisquerin@gmail.com>
  • Loading branch information
sixfold-origami and Nilirad authored Jul 1, 2022
1 parent 34d5714 commit 5ba438b
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 35 deletions.
2 changes: 1 addition & 1 deletion crates/bevy_ecs/src/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ pub struct Components {
impl Components {
/// Adds a new component type to [`Components`].
///
/// If the component type is already present, then simply return its [`ComponentId`].
/// If the component type is already present, it simply returns its [`ComponentId`].
#[inline]
pub fn init_component<T: Component>(&mut self, storages: &mut Storages) -> ComponentId {
let type_id = TypeId::of::<T>();
Expand Down
53 changes: 26 additions & 27 deletions crates/bevy_ecs/src/world/archetype_invariants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use bevy_utils::{tracing::warn, HashSet};

use crate::{component::ComponentId, prelude::Bundle, world::World};

/// A rule about which [`Component`](crate::component::Component)s can coexist on entities
/// A rule about which [`Component`](crate::component::Component)s can coexist on entities.
///
/// These rules must be true at all times for all entities in the [`World`].
/// The generic [`Bundle`] type `B1` is always used in the `predicate`,
Expand All @@ -18,9 +18,6 @@ use crate::{component::ComponentId, prelude::Bundle, world::World};
///
/// Archetypes are only modified when a novel archetype (set of components) is seen for the first time;
/// swapping between existing archetypes will not trigger these checks.
///
/// Note that this is converted to an [`UntypedArchetypeInvariant`] when added to a [`World`].
/// This is to ensure compatibility between different invariants.
#[derive(Clone, Debug, PartialEq)]
pub struct ArchetypeInvariant<B1: Bundle, B2: Bundle = B1> {
/// For all entities where the predicate is true
Expand All @@ -43,9 +40,9 @@ impl<B1: Bundle, B2: Bundle> ArchetypeInvariant<B1, B2> {
}

impl<B: Bundle> ArchetypeInvariant<B, B> {
/// This is a helper function for constructing common invariants.
/// All components of the provided bundle require each other.
/// In other words, if any one component of this bundle is present, then all of them must be.
/// Creates an archetype invariant where all components of `B` require each other.
///
/// In other words, if any component of this bundle is present, then all of them must be.
#[inline]
pub fn full_bundle() -> Self {
Self {
Expand All @@ -70,20 +67,20 @@ impl<B: Bundle> ArchetypeInvariant<B, B> {
/// This is to ensure compatibility between different invariants.
#[derive(Clone, Debug, PartialEq)]
pub enum ArchetypeStatement<B: Bundle> {
/// Evaluates to true if and only if the entity has all of the components present in the bundle `B`
/// Evaluates to true if and only if the entity has all of the components present in the bundle `B`.
AllOf(PhantomData<B>),
/// The entity has at least one component in the bundle `B`, and may have all of them.
/// The entity has at least one component in the bundle `B`.
/// When using a single-component bundle, `AllOf` is preferred.
AtLeastOneOf(PhantomData<B>),
/// The entity has zero or one of the components in the bundle `B`, but no more.
/// When using a single-component bundle, this is a tautology.
/// When using a single-component bundle, this will always be true.
AtMostOneOf(PhantomData<B>),
/// The entity has none of the components in the bundle `B`
/// The entity has none of the components in the bundle `B`.
NoneOf(PhantomData<B>),
}

impl<B: Bundle> ArchetypeStatement<B> {
/// Erases the type information of this archetype statment.
/// Erases the type information of this archetype statement.
///
/// Requires mutable world access, since the components might not have been added to the world yet.
pub fn into_untyped(self, world: &mut World) -> UntypedArchetypeStatement {
Expand All @@ -105,25 +102,25 @@ impl<B: Bundle> ArchetypeStatement<B> {
}
}

/// Constructs a new [`ArchetypeStatement::AllOf`] variant for all components stored in the bundle `B`
/// Constructs a new [`ArchetypeStatement::AllOf`] variant for all components stored in the bundle `B`.
#[inline]
pub const fn all_of() -> Self {
ArchetypeStatement::AllOf(PhantomData)
}

/// Constructs a new [`ArchetypeStatement::AtLeastOneOf`] variant for all components stored in the bundle `B`
/// Constructs a new [`ArchetypeStatement::AtLeastOneOf`] variant for all components stored in the bundle `B`.
#[inline]
pub const fn at_least_one_of() -> Self {
ArchetypeStatement::AtLeastOneOf(PhantomData)
}

/// Constructs a new [`ArchetypeStatement::AtMostOneOf`] variant for all components stored in the bundle `B`
/// Constructs a new [`ArchetypeStatement::AtMostOneOf`] variant for all components stored in the bundle `B`.
#[inline]
pub const fn at_most_one_of() -> Self {
ArchetypeStatement::AtMostOneOf(PhantomData)
}

/// Constructs a new [`ArchetypeStatement::NoneOf`] variant for all components stored in the bundle `B`
/// Constructs a new [`ArchetypeStatement::NoneOf`] variant for all components stored in the bundle `B`.
#[inline]
pub const fn none_of() -> Self {
ArchetypeStatement::NoneOf(PhantomData)
Expand All @@ -143,14 +140,14 @@ pub struct UntypedArchetypeInvariant {
}

impl UntypedArchetypeInvariant {
/// Assert that the provided iterator of [`ComponentId`]s obeys this archetype invariant
/// Asserts that the provided iterator of [`ComponentId`]s obeys this archetype invariant.
///
/// `component_ids` is generally provided via the `components` field on [`Archetype`](crate::archetype::Archetype).
/// When testing against multiple archetypes, [`ArchetypeInvariants::test_archetype`] is preferred,
/// as it can more efficiently cache checks between archetypes.
///
/// # Panics
/// Panics if the archetype invariant is violated
/// Panics if the archetype invariant is violated.
pub fn test_archetype(&self, component_ids_of_archetype: impl Iterator<Item = ComponentId>) {
let component_ids_of_archetype: HashSet<ComponentId> = component_ids_of_archetype.collect();

Expand All @@ -165,20 +162,21 @@ impl UntypedArchetypeInvariant {
}
}

/// A type-erased version of [`ArchetypeStatement`]
/// A type-erased version of [`ArchetypeStatement`].
///
/// Intended to be used with dynamic components that cannot be represented with Rust types.
/// Prefer [`ArchetypeStatement`] when possible.
#[derive(Clone, Debug, PartialEq)]
pub enum UntypedArchetypeStatement {
/// Evaluates to true if and only if the entity has all of the components present in the set
/// Evaluates to true if and only if the entity has all of the components present in the set.
AllOf(HashSet<ComponentId>),
/// The entity has at least one component in the set, and may have all of them.
/// When using a single-component set, `AllOf` is preferred
/// When using a single-component set, `AllOf` is preferred.
AtLeastOneOf(HashSet<ComponentId>),
/// The entity has zero or one of the components in the set, but no more.
/// When using a single-component set, this is a tautology.
AtMostOneOf(HashSet<ComponentId>),
/// The entity has none of the components in the set
/// The entity has none of the components in the set.
NoneOf(HashSet<ComponentId>),
}

Expand All @@ -193,7 +191,7 @@ impl UntypedArchetypeStatement {
}
}

/// Test if this statement is true for the provided set of [`ComponentId`]s
/// Test if this statement is true for the provided set of [`ComponentId`]s.
pub fn test(&self, component_ids: &HashSet<ComponentId>) -> bool {
match self {
UntypedArchetypeStatement::AllOf(required_ids) => {
Expand Down Expand Up @@ -238,26 +236,27 @@ impl UntypedArchetypeStatement {

#[derive(Default)]
pub struct ArchetypeInvariants {
/// The list of invariants that must be upheld
/// The list of invariants that must be upheld.
raw_list: Vec<UntypedArchetypeInvariant>,
}

impl ArchetypeInvariants {
/// Adds a new [`ArchetypeInvariant`] to this set of archetype invariants.
///
/// Whenever a new archetype invariant is added, all existing archetypes are re-checked.
/// This may include empty archetypes- archetypes that contain no entities.
/// This may include empty archetypes: archetypes that contain no entities.
#[inline]
pub fn add(&mut self, archetype_invariant: UntypedArchetypeInvariant) {
self.raw_list.push(archetype_invariant);
}

/// Assert that the provided iterator of [`ComponentId`]s obeys all archetype invariants
/// Asserts that the provided iterator of [`ComponentId`]s obeys all archetype invariants.
///
/// `component_ids` is generally provided via the `components` field on [`Archetype`](crate::archetype::Archetype).
///
/// # Panics
/// Panics if any archetype invariant is violated
///
/// Panics if any archetype invariant is violated.
pub fn test_archetype(&self, component_ids_of_archetype: impl Iterator<Item = ComponentId>) {
let component_ids_of_archetype: HashSet<ComponentId> = component_ids_of_archetype.collect();

Expand Down
11 changes: 4 additions & 7 deletions crates/bevy_ecs/src/world/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
pub mod archetype_invariants;
mod archetype_invariants;
mod entity_ref;
mod spawn_batch;
mod world_cell;
Expand All @@ -7,10 +7,7 @@ pub use crate::change_detection::Mut;
pub use entity_ref::*;
pub use spawn_batch::*;
pub use world_cell::*;

use self::archetype_invariants::{
ArchetypeInvariant, ArchetypeInvariants, UntypedArchetypeInvariant,
};
pub use archetype_invariants::*;

use crate::{
archetype::{ArchetypeComponentId, ArchetypeComponentInfo, ArchetypeId, Archetypes},
Expand Down Expand Up @@ -159,7 +156,7 @@ impl World {
&self.archetypes
}

/// Retrieves this world's [`ArchetypeInvariants`] collection
/// Retrieves this world's [`ArchetypeInvariants`] collection.
#[inline]
pub fn archetype_invariants(&self) -> &ArchetypeInvariants {
&self.archetype_invariants
Expand Down Expand Up @@ -672,7 +669,7 @@ impl World {
self.archetype_invariants.add(untyped_invariant);
}

/// Inserts a new [`UntypedArchetypeInvariant`] to the world
/// Inserts a new [`UntypedArchetypeInvariant`] to the world.
///
/// Whenever a new archetype invariant is added, all existing archetypes are re-checked.
/// This may include empty archetypes- archetypes that contain no entities.
Expand Down

0 comments on commit 5ba438b

Please sign in to comment.