Skip to content

Commit

Permalink
Document every public item in bevy_ecs (#8731)
Browse files Browse the repository at this point in the history
# Objective

Title.

---------

Co-authored-by: François <mockersf@gmail.com>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: James Liu <contact@jamessliu.com>
  • Loading branch information
4 people committed Jun 10, 2023
1 parent 50bc785 commit 32faf4c
Show file tree
Hide file tree
Showing 41 changed files with 374 additions and 14 deletions.
7 changes: 7 additions & 0 deletions crates/bevy_ecs/src/archetype.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ use std::{
pub struct ArchetypeRow(u32);

impl ArchetypeRow {
/// Index indicating an invalid archetype row.
/// This is meant to be used as a placeholder.
pub const INVALID: ArchetypeRow = ArchetypeRow(u32::MAX);

/// Creates a `ArchetypeRow`.
Expand Down Expand Up @@ -349,6 +351,7 @@ impl Archetype {
self.table_id
}

/// Fetches the entities contained in this archetype.
#[inline]
pub fn entities(&self) -> &[ArchetypeEntity] {
&self.entities
Expand Down Expand Up @@ -614,6 +617,8 @@ impl Archetypes {
archetypes
}

/// Returns the current archetype generation. This is an ID indicating the current set of archetypes
/// that are registered with the world.
#[inline]
pub fn generation(&self) -> ArchetypeGeneration {
ArchetypeGeneration(self.archetypes.len())
Expand Down Expand Up @@ -719,6 +724,8 @@ impl Archetypes {
})
}

/// Returns the number of components that are stored in archetypes.
/// Note that if some component `T` is stored in more than one archetype, it will be counted once for each archetype it's present in.
#[inline]
pub fn archetype_components_len(&self) -> usize {
self.archetype_component_count
Expand Down
17 changes: 17 additions & 0 deletions crates/bevy_ecs/src/bundle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,10 +247,16 @@ macro_rules! tuple_impl {

all_tuples!(tuple_impl, 0, 15, B);

/// For a specific [`World`], this stores a unique value identifying a type of a registered [`Bundle`].
///
/// [`World`]: crate::world::World
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
pub struct BundleId(usize);

impl BundleId {
/// Returns the index of the associated [`Bundle`] type.
///
/// Note that this is unique per-world, and should not be reused across them.
#[inline]
pub fn index(self) -> usize {
self.0
Expand All @@ -269,6 +275,9 @@ impl SparseSetIndex for BundleId {
}
}

/// Stores metadata associated with a specific type of [`Bundle`] for a given [`World`].
///
/// [`World`]: crate::world::World
pub struct BundleInfo {
id: BundleId,
// SAFETY: Every ID in this list must be valid within the World that owns the BundleInfo,
Expand Down Expand Up @@ -324,11 +333,13 @@ impl BundleInfo {
BundleInfo { id, component_ids }
}

/// Returns a value identifying the associated [`Bundle`] type.
#[inline]
pub const fn id(&self) -> BundleId {
self.id
}

/// Returns the [ID](ComponentId) of each component stored in this bundle.
#[inline]
pub fn components(&self) -> &[ComponentId] {
&self.component_ids
Expand Down Expand Up @@ -782,6 +793,7 @@ impl<'a, 'b> BundleSpawner<'a, 'b> {
}
}

/// Metadata for bundles. Stores a [`BundleInfo`] for each type of [`Bundle`] in a given world.
#[derive(Default)]
pub struct Bundles {
bundle_infos: Vec<BundleInfo>,
Expand All @@ -794,11 +806,16 @@ pub struct Bundles {
}

impl Bundles {
/// Gets the metadata associated with a specific type of bundle.
/// Returns `None` if the bundle is not registered with the world.
#[inline]
pub fn get(&self, bundle_id: BundleId) -> Option<&BundleInfo> {
self.bundle_infos.get(bundle_id.index())
}

/// Gets the value identifying a specific type of bundle.
/// Returns `None` if the bundle does not exist in the world,
/// or if `type_id` does not correspond to a type of bundle.
#[inline]
pub fn get_id(&self, type_id: TypeId) -> Option<BundleId> {
self.bundle_ids.get(&type_id).cloned()
Expand Down
6 changes: 5 additions & 1 deletion crates/bevy_ecs/src/change_detection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,10 @@ pub struct Res<'w, T: ?Sized + Resource> {
}

impl<'w, T: Resource> Res<'w, T> {
// no it shouldn't clippy
/// Copies a reference to a resource.
///
/// Note that unless you actually need an instance of `Res<T>`, you should
/// prefer to just convert it to `&T` which can be freely copied.
#[allow(clippy::should_implement_trait)]
pub fn clone(this: &Self) -> Self {
Self {
Expand Down Expand Up @@ -539,6 +542,7 @@ pub struct Ref<'a, T: ?Sized> {
}

impl<'a, T: ?Sized> Ref<'a, T> {
/// Returns the reference wrapped by this type. The reference is allowed to outlive `self`, which makes this method more flexible than simply borrowing `self`.
pub fn into_inner(self) -> &'a T {
self.value
}
Expand Down
64 changes: 61 additions & 3 deletions crates/bevy_ecs/src/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,14 +146,23 @@ use std::{
/// [`SyncCell`]: bevy_utils::synccell::SyncCell
/// [`Exclusive`]: https://doc.rust-lang.org/nightly/std/sync/struct.Exclusive.html
pub trait Component: Send + Sync + 'static {
/// A marker type indicating the storage type used for this component.
/// This must be either [`TableStorage`] or [`SparseStorage`].
type Storage: ComponentStorage;
}

/// Marker type for components stored in a [`Table`](crate::storage::Table).
pub struct TableStorage;

/// Marker type for components stored in a [`ComponentSparseSet`](crate::storage::ComponentSparseSet).
pub struct SparseStorage;

/// Types used to specify the storage strategy for a component.
///
/// This trait is implemented for [`TableStorage`] and [`SparseStorage`].
/// Custom implementations are forbidden.
pub trait ComponentStorage: sealed::Sealed {
// because the trait is sealed, those items are private API.
/// A value indicating the storage strategy specified by this type.
const STORAGE_TYPE: StorageType;
}

Expand Down Expand Up @@ -191,28 +200,34 @@ pub enum StorageType {
SparseSet,
}

/// Stores metadata for a type of component or resource stored in a specific [`World`].
#[derive(Debug)]
pub struct ComponentInfo {
id: ComponentId,
descriptor: ComponentDescriptor,
}

impl ComponentInfo {
/// Returns a value uniquely identifying the current component.
#[inline]
pub fn id(&self) -> ComponentId {
self.id
}

/// Returns the name of the current component.
#[inline]
pub fn name(&self) -> &str {
&self.descriptor.name
}

/// Returns the [`TypeId`] of the underlying component type.
/// Returns `None` if the component does not correspond to a Rust type.
#[inline]
pub fn type_id(&self) -> Option<TypeId> {
self.descriptor.type_id
}

/// Returns the layout used to store values of this component in memory.
#[inline]
pub fn layout(&self) -> Layout {
self.descriptor.layout
Expand All @@ -229,11 +244,15 @@ impl ComponentInfo {
self.descriptor.drop
}

/// Returns a value indicating the storage strategy for the current component.
#[inline]
pub fn storage_type(&self) -> StorageType {
self.descriptor.storage_type
}

/// Returns `true` if the underlying component type can be freely shared between threads.
/// If this returns `false`, then extra care must be taken to ensure that components
/// are not accessed from the wrong thread.
#[inline]
pub fn is_send_and_sync(&self) -> bool {
self.descriptor.is_send_and_sync
Expand All @@ -245,7 +264,7 @@ impl ComponentInfo {
}
}

/// A semi-opaque value which uniquely identifies the type of a [`Component`] within a
/// A value which uniquely identifies the type of a [`Component`] within a
/// [`World`](crate::world::World).
///
/// Each time a new `Component` type is registered within a `World` using
Expand All @@ -266,11 +285,16 @@ impl ComponentInfo {
pub struct ComponentId(usize);

impl ComponentId {
/// Creates a new [`ComponentId`].
///
/// The `index` is a unique value associated with each type of component in a given world.
/// Usually, this value is taken from a counter incremented for each type of component registered with the world.
#[inline]
pub const fn new(index: usize) -> ComponentId {
ComponentId(index)
}

/// Returns the index of the current component.
#[inline]
pub fn index(self) -> usize {
self.0
Expand All @@ -289,6 +313,7 @@ impl SparseSetIndex for ComponentId {
}
}

/// A value describing a component or resource, which may or may not correspond to a Rust type.
pub struct ComponentDescriptor {
name: Cow<'static, str>,
// SAFETY: This must remain private. It must match the statically known StorageType of the
Expand Down Expand Up @@ -384,22 +409,27 @@ impl ComponentDescriptor {
}
}

/// Returns a value indicating the storage strategy for the current component.
#[inline]
pub fn storage_type(&self) -> StorageType {
self.storage_type
}

/// Returns the [`TypeId`] of the underlying component type.
/// Returns `None` if the component does not correspond to a Rust type.
#[inline]
pub fn type_id(&self) -> Option<TypeId> {
self.type_id
}

/// Returns the name of the current component.
#[inline]
pub fn name(&self) -> &str {
self.name.as_ref()
}
}

/// Stores metadata associated with each kind of [`Component`] in a given [`World`].
#[derive(Debug, Default)]
pub struct Components {
components: Vec<ComponentInfo>,
Expand All @@ -408,6 +438,9 @@ pub struct Components {
}

impl Components {
/// Initializes a component of type `T` with this instance.
/// If a component of this type has already been initialized, this will return
/// the ID of the pre-existing component.
#[inline]
pub fn init_component<T: Component>(&mut self, storages: &mut Storages) -> ComponentId {
let type_id = TypeId::of::<T>();
Expand All @@ -423,6 +456,12 @@ impl Components {
ComponentId(*index)
}

/// Initializes a component described by `descriptor`.
///
/// ## Note
///
/// If this method is called multiple times with identical descriptors, a distinct `ComponentId`
/// will be created for each one.
pub fn init_component_with_descriptor(
&mut self,
storages: &mut Storages,
Expand All @@ -447,26 +486,35 @@ impl Components {
index
}

/// Returns the number of components registered with this instance.
#[inline]
pub fn len(&self) -> usize {
self.components.len()
}

/// Returns `true` if there are no components registered with this instance. Otherwise, this returns `false`.
#[inline]
pub fn is_empty(&self) -> bool {
self.components.len() == 0
}

/// Gets the metadata associated with the given component.
///
/// This will return an incorrect result if `id` did not come from the same world as `self`. It may return `None` or a garbage value.
#[inline]
pub fn get_info(&self, id: ComponentId) -> Option<&ComponentInfo> {
self.components.get(id.0)
}

/// Returns the name associated with the given component.
///
/// This will return an incorrect result if `id` did not come from the same world as `self`. It may return `None` or a garbage value.
#[inline]
pub fn get_name(&self, id: ComponentId) -> Option<&str> {
self.get_info(id).map(|descriptor| descriptor.name())
}

/// Gets the metadata associated with the given component.
/// # Safety
///
/// `id` must be a valid [`ComponentId`]
Expand Down Expand Up @@ -542,6 +590,9 @@ impl Components {
self.get_resource_id(TypeId::of::<T>())
}

/// Initializes a [`Resource`] of type `T` with this instance.
/// If a resource of this type has already been initialized, this will return
/// the ID of the pre-existing resource.
#[inline]
pub fn init_resource<T: Resource>(&mut self) -> ComponentId {
// SAFETY: The [`ComponentDescriptor`] matches the [`TypeId`]
Expand All @@ -552,6 +603,9 @@ impl Components {
}
}

/// Initializes a [non-send resource](crate::system::NonSend) of type `T` with this instance.
/// If a resource of this type has already been initialized, this will return
/// the ID of the pre-existing resource.
#[inline]
pub fn init_non_send<T: Any>(&mut self) -> ComponentId {
// SAFETY: The [`ComponentDescriptor`] matches the [`TypeId`]
Expand Down Expand Up @@ -582,6 +636,7 @@ impl Components {
ComponentId(*index)
}

/// Gets an iterator over all components registered with this instance.
pub fn iter(&self) -> impl Iterator<Item = &ComponentInfo> + '_ {
self.components.iter()
}
Expand All @@ -602,6 +657,7 @@ impl Tick {
/// ticks are periodically scanned to ensure their relative values are below this.
pub const MAX: Self = Self::new(MAX_CHANGE_AGE);

/// Creates a new [`Tick`] wrapping the given value.
#[inline]
pub const fn new(tick: u32) -> Self {
Self { tick }
Expand Down Expand Up @@ -659,10 +715,12 @@ impl Tick {
}
}

/// Wrapper around [`Tick`]s for a single component
/// Interior-mutable access to the [`Tick`]s for a single component or resource.
#[derive(Copy, Clone, Debug)]
pub struct TickCells<'a> {
/// The tick indicating when the value was added to the world.
pub added: &'a UnsafeCell<Tick>,
/// The tick indicating the last time the value was modified.
pub changed: &'a UnsafeCell<Tick>,
}

Expand Down
4 changes: 2 additions & 2 deletions crates/bevy_ecs/src/entity/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -717,8 +717,8 @@ impl Entities {
}
}

// Flushes all reserved entities to an "invalid" state. Attempting to retrieve them will return None
// unless they are later populated with a valid archetype.
/// Flushes all reserved entities to an "invalid" state. Attempting to retrieve them will return `None`
/// unless they are later populated with a valid archetype.
pub fn flush_as_invalid(&mut self) {
// SAFETY: as per `flush` safety docs, the archetype id can be set to [`ArchetypeId::INVALID`] if
// the [`Entity`] has not been assigned to an [`Archetype`][crate::archetype::Archetype], which is the case here
Expand Down
Loading

0 comments on commit 32faf4c

Please sign in to comment.