From 803920c59a484b4b5c488f3ad9d9e65f383159c8 Mon Sep 17 00:00:00 2001 From: Alice Cecile Date: Fri, 17 Dec 2021 14:04:22 -0500 Subject: [PATCH 1/7] Basic docs for bundle / archetype internals --- crates/bevy_ecs/src/archetype.rs | 14 ++++++++++++++ crates/bevy_ecs/src/bundle.rs | 3 +++ crates/bevy_ecs/src/component.rs | 14 ++++++++++++++ 3 files changed, 31 insertions(+) diff --git a/crates/bevy_ecs/src/archetype.rs b/crates/bevy_ecs/src/archetype.rs index 9d6ba80bd9dae..7ea0b5b5397d3 100644 --- a/crates/bevy_ecs/src/archetype.rs +++ b/crates/bevy_ecs/src/archetype.rs @@ -14,6 +14,7 @@ use std::{ ops::{Index, IndexMut}, }; +/// The unique identifier of an [`Archetype`] #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] pub struct ArchetypeId(usize); @@ -33,16 +34,22 @@ impl ArchetypeId { } } +/// Records whether a component was modified by addition or mutation pub enum ComponentStatus { Added, Mutated, } +/// Stores the information needed to add a bundle to the archetype graph. pub struct AddBundle { pub archetype_id: ArchetypeId, pub bundle_status: Vec, } +/// The connections from one [`Archetype`] to its neighbours +/// +/// Used to acccelerate add and remove operations. +/// Edges, like archetypes, are never cleaned up. #[derive(Default)] pub struct Edges { pub add_bundle: SparseArray, @@ -116,6 +123,9 @@ pub(crate) struct ArchetypeComponentInfo { pub(crate) archetype_component_id: ArchetypeComponentId, } +/// A unique set of components stored within the [`World`](crate::world::World) +/// +/// Archetypes are used internally to accelerate iteration over queries pub struct Archetype { id: ArchetypeId, entities: Vec, @@ -335,6 +345,9 @@ pub struct ArchetypeIdentity { sparse_set_components: Cow<'static, [ComponentId]>, } +/// The unique identifier for a component within a particular archetype +/// +/// These are unique across archetypes. #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] pub struct ArchetypeComponentId(usize); @@ -361,6 +374,7 @@ impl SparseSetIndex for ArchetypeComponentId { } } +/// The collection of [`Archetype`] stored in the [`World`](crate::world::World) pub struct Archetypes { pub(crate) archetypes: Vec, pub(crate) archetype_component_count: usize, diff --git a/crates/bevy_ecs/src/bundle.rs b/crates/bevy_ecs/src/bundle.rs index d3112f149c034..a2a08f8b74fe0 100644 --- a/crates/bevy_ecs/src/bundle.rs +++ b/crates/bevy_ecs/src/bundle.rs @@ -129,6 +129,7 @@ macro_rules! tuple_impl { all_tuples!(tuple_impl, 0, 15, C); +/// The unique identifer of a type that implements [Bundle] #[derive(Debug, Clone, Copy)] pub struct BundleId(usize); @@ -150,6 +151,7 @@ impl SparseSetIndex for BundleId { } } +/// The metadata of a [Bundle] and its constituent components pub struct BundleInfo { pub(crate) id: BundleId, pub(crate) component_ids: Vec, @@ -572,6 +574,7 @@ impl<'a, 'b> BundleSpawner<'a, 'b> { } } +/// A central storage of [Bundle]s #[derive(Default)] pub struct Bundles { bundle_infos: Vec, diff --git a/crates/bevy_ecs/src/component.rs b/crates/bevy_ecs/src/component.rs index a38132fc4c435..c88c58489df1f 100644 --- a/crates/bevy_ecs/src/component.rs +++ b/crates/bevy_ecs/src/component.rs @@ -137,6 +137,9 @@ impl ComponentInfo { } } +/// Unique identifier for a component (or resource) type. +/// +/// Used to lookup storage information in ['Components'](crate::component::Components) #[derive(Debug, Copy, Clone, Hash, Ord, PartialOrd, Eq, PartialEq)] pub struct ComponentId(usize); @@ -163,6 +166,9 @@ impl SparseSetIndex for ComponentId { } } +/// Functional metadata for a component (or resource) type +/// +/// Used for control flow in ECS internals to ensure the correct behavior is followed. #[derive(Debug)] pub struct ComponentDescriptor { name: String, @@ -232,6 +238,14 @@ impl ComponentDescriptor { } } +/// The ['World'](crate::world::World)'s collection of component and resource types. +/// +/// Can be accessed via ['World::components'](crate::world::World::components) +/// +/// Stores metadata about component storage layout. +/// ['ComponentId'](crate::component::ComponentId)'s can be produced from +/// ['TypeId'](std::any::TypeId) using ['get_id'](Self::get_id). +/// These can then be used to access the corresponding ['ComponentInfo'](crate::component::ComponentInfo). #[derive(Debug, Default)] pub struct Components { components: Vec, From ed1dab4fd67caf7b69fdded899c19b248699df36 Mon Sep 17 00:00:00 2001 From: Alice Cecile Date: Fri, 17 Dec 2021 15:13:01 -0500 Subject: [PATCH 2/7] Docs for Access --- crates/bevy_ecs/src/query/access.rs | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/crates/bevy_ecs/src/query/access.rs b/crates/bevy_ecs/src/query/access.rs index 25c1f39054008..4d95505cd111c 100644 --- a/crates/bevy_ecs/src/query/access.rs +++ b/crates/bevy_ecs/src/query/access.rs @@ -2,16 +2,17 @@ use crate::storage::SparseSetIndex; use fixedbitset::FixedBitSet; use std::marker::PhantomData; -/// `Access` keeps track of read and write accesses to values within a collection. +/// [Access] keeps track of read and write accesses to values within a collection. /// /// This is used for ensuring systems are executed soundly. #[derive(Debug, Eq, PartialEq, Clone)] pub struct Access { + /// Is read-access to the entire [World](crate::world::World) required? reads_all: bool, - /// A combined set of T read and write accesses. + /// A combined set of read and write accesses for T. reads_and_writes: FixedBitSet, writes: FixedBitSet, - marker: PhantomData, + _marker: PhantomData, } impl Default for Access { @@ -20,7 +21,7 @@ impl Default for Access { reads_all: false, reads_and_writes: Default::default(), writes: Default::default(), - marker: PhantomData, + _marker: PhantomData, } } } @@ -129,6 +130,10 @@ impl Access { } } +/// An [Access] which is filtered by various [With](crate::query::With) and [Without](crate::query::Without) query filters. +/// +/// Used to schedule systems efficiently and verify non-conflicting accesses to entities, +/// as entities cannot both have and not-have a component. #[derive(Clone, Eq, PartialEq)] pub struct FilteredAccess { access: Access, @@ -188,6 +193,11 @@ impl FilteredAccess { } } +/// The combined [Access] of a system parameter or system, +/// used to schedule systems soundly. +/// +/// A [FilteredAccessSet] is constructed iteratively, by combining the [FilteredAccess] of +/// its constituents using [FilteredAccessSet::add](Self::add). pub struct FilteredAccessSet { combined_access: Access, filtered_accesses: Vec>, From 84b9b44e90ae80d3473591a0e39bc69ab255b1cb Mon Sep 17 00:00:00 2001 From: Alice Cecile Date: Fri, 17 Dec 2021 15:33:47 -0500 Subject: [PATCH 3/7] Docs for Fetch --- crates/bevy_ecs/src/query/fetch.rs | 50 +++++++++++++++------- crates/bevy_ecs/src/system/system_param.rs | 12 +++++- 2 files changed, 44 insertions(+), 18 deletions(-) diff --git a/crates/bevy_ecs/src/query/fetch.rs b/crates/bevy_ecs/src/query/fetch.rs index 264b370e26dfb..3e9e160497d4b 100644 --- a/crates/bevy_ecs/src/query/fetch.rs +++ b/crates/bevy_ecs/src/query/fetch.rs @@ -41,14 +41,28 @@ use std::{ /// /// [`Or`]: crate::query::Or pub trait WorldQuery { + /// The data requested by this query parameter, which must implement the [Fetch] trait type Fetch: for<'world, 'state> Fetch<'world, 'state, State = Self::State>; + /// The type that can be used to cache internal state for the query parameter type State: FetchState; + /// The read-only version of the data requested by this query parameter, which must implement both [Fetch] and [ReadOnlyFetch] type ReadOnlyFetch: for<'world, 'state> Fetch<'world, 'state, State = Self::State> + ReadOnlyFetch; } +/// The type of the items returned when a [Query](crate::system::Query) is iterated over. +/// +/// The particular tuple of items returned is constructed based on the [Fetch] field of the [WorldQuery] type passed in. pub type QueryItem<'w, 's, Q> = <::Fetch as Fetch<'w, 's>>::Item; +/// Describes the data that is accessed by a [WorldQuery] type. +/// +/// See [SystemParamFetch](crate::system::system_param::SystemParamFetch) for the [SystemParam](crate::system::SystemParam) analogue. +/// +/// By default, a [Fetch] implies read-write access. +/// Structs which implement this trait may also want to implement one of the following extension traits: +/// - [ReadOnlyFetch], for when the data access is entirely read-only. +/// - [FilterFetch](crate::query::FilterFetch), for when only information about presence/absence is required. pub trait Fetch<'world, 'state>: Sized { type Item; type State: FetchState; @@ -110,9 +124,9 @@ pub trait Fetch<'world, 'state>: Sized { unsafe fn table_fetch(&mut self, table_row: usize) -> Self::Item; } -/// State used to construct a Fetch. This will be cached inside [`QueryState`](crate::query::QueryState), -/// so it is best to move as much data / computation here as possible to reduce the cost of -/// constructing Fetch. +/// State used to construct a [Fetch]. This will be cached inside [`QueryState`](crate::query::QueryState), +/// so it is best to move as much data / computation here as possible +/// to reduce the cost of construction. /// /// # Safety /// @@ -132,7 +146,7 @@ pub unsafe trait FetchState: Send + Sync + Sized { fn matches_table(&self, table: &Table) -> bool; } -/// A fetch that is read only. +/// A [Fetch] that only permits read access to data. /// /// # Safety /// @@ -232,7 +246,7 @@ impl WorldQuery for &T { type ReadOnlyFetch = ReadFetch; } -/// The [`FetchState`] of `&T`. +/// The [`FetchState`] of `&T`, when used as a [Component] in a [WorldQuery]. pub struct ReadState { component_id: ComponentId, marker: PhantomData, @@ -278,7 +292,7 @@ unsafe impl FetchState for ReadState { } } -/// The [`Fetch`] of `&T`. +/// The [`Fetch`] of `&T`, when used as a [Component] in a [WorldQuery]. pub struct ReadFetch { table_components: NonNull, entity_table_rows: *const usize, @@ -387,7 +401,7 @@ impl WorldQuery for &mut T { type ReadOnlyFetch = ReadOnlyWriteFetch; } -/// The [`Fetch`] of `&mut T`. +/// The [`Fetch`] of `&mut T`, when used as a [Component] in a [WorldQuery]. pub struct WriteFetch { table_components: NonNull, table_ticks: *const UnsafeCell, @@ -412,7 +426,7 @@ impl Clone for WriteFetch { } } -/// The [`ReadOnlyFetch`] of `&mut T`. +/// The [`ReadOnlyFetch`] of `&mut T`, when used as a [Component] in a [WorldQuery]. pub struct ReadOnlyWriteFetch { table_components: NonNull, entities: *const Entity, @@ -434,14 +448,14 @@ impl Clone for ReadOnlyWriteFetch { } } -/// The [`FetchState`] of `&mut T`. +/// The [`FetchState`] of `&mut T`, when used as a [Component] in a [WorldQuery]. pub struct WriteState { component_id: ComponentId, marker: PhantomData, } -// SAFETY: component access and archetype component access are properly updated to reflect that T is -// written +// SAFETY: component access and archetype component access are properly updated +// to reflect that T is written unsafe impl FetchState for WriteState { fn init(world: &mut World) -> Self { let component_id = world.init_component::(); @@ -671,6 +685,8 @@ impl WorldQuery for Option { } /// The [`Fetch`] of `Option`. +/// +/// `T` may implement [SystemParam](crate::system::SystemParam) or [WorldQuery] #[derive(Clone)] pub struct OptionFetch { fetch: T, @@ -681,12 +697,14 @@ pub struct OptionFetch { unsafe impl ReadOnlyFetch for OptionFetch {} /// The [`FetchState`] of `Option`. +/// +/// `T` may implement [SystemParam](crate::system::SystemParam) or [WorldQuery] pub struct OptionState { state: T, } -// SAFETY: component access and archetype component access are properly updated according to the -// internal Fetch +// SAFETY: component access and archetype component access are properly updated +// according to the internal Fetch unsafe impl FetchState for OptionState { fn init(world: &mut World) -> Self { Self { @@ -776,12 +794,12 @@ impl<'w, 's, T: Fetch<'w, 's>> Fetch<'w, 's> for OptionFetch { } } -/// [`WorldQuery`] that tracks changes and additions for component `T`. +/// A [`WorldQuery`] parameter that tracks changes and additions for component `T`. /// /// Wraps a [`Component`] to track whether the component changed for the corresponding entities in -/// a query since the last time the system that includes these queries ran. +/// a query since the last time the system that contains the query ran. /// -/// If you only care about entities that changed or that got added use the +/// If you only care about entities that have been changed or added use the /// [`Changed`](crate::query::Changed) and [`Added`](crate::query::Added) filters instead. /// /// # Examples diff --git a/crates/bevy_ecs/src/system/system_param.rs b/crates/bevy_ecs/src/system/system_param.rs index af52e24d7bec4..7d7be8ca1548a 100644 --- a/crates/bevy_ecs/src/system/system_param.rs +++ b/crates/bevy_ecs/src/system/system_param.rs @@ -21,6 +21,7 @@ use std::{ /// A parameter that can be used in a [`System`](super::System). /// +/// /// # Derive /// /// This trait can be derived with the [`derive@super::SystemParam`] macro. The only requirement @@ -45,12 +46,16 @@ use std::{ /// # my_system.system(); /// ``` pub trait SystemParam: Sized { + /// The data requested by this system parameter, which must implement the [SystemParamFetch] trait type Fetch: for<'w, 's> SystemParamFetch<'w, 's>; } +/// The concrete type returned by the [SystemParam] P pub type SystemParamItem<'w, 's, P> = <

::Fetch as SystemParamFetch<'w, 's>>::Item; -/// The state of a [`SystemParam`]. +/// The internal state of a [`SystemParam`]. +/// +/// Used for caching work and storing data between executions of the system. /// /// # Safety /// @@ -80,12 +85,15 @@ pub unsafe trait SystemParamState: Send + Sync + 'static { fn default_config() -> Self::Config; } -/// A [`SystemParamFetch`] that only reads a given [`World`]. +/// A [`SystemParamFetch`] that can only read from a [`World`]. /// /// # Safety /// This must only be implemented for [`SystemParamFetch`] impls that exclusively read the World passed in to [`SystemParamFetch::get_param`] pub unsafe trait ReadOnlySystemParamFetch {} +/// The data requested by a [SystemParam] +/// +/// See [Fetch](crate::query::Fetch) for the [WorldQuery](crate::query::WorldQuery) analogue. pub trait SystemParamFetch<'world, 'state>: SystemParamState { type Item; /// # Safety From 39568184331e60ca8a73ecf0b54a8812ff1204fb Mon Sep 17 00:00:00 2001 From: Alice Cecile Date: Fri, 17 Dec 2021 01:11:18 -0500 Subject: [PATCH 4/7] More basic docs --- crates/bevy_ecs/src/component.rs | 11 ++++++++++- crates/bevy_ecs/src/entity/map_entities.rs | 4 ++++ crates/bevy_ecs/src/entity/mod.rs | 6 ++++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/crates/bevy_ecs/src/component.rs b/crates/bevy_ecs/src/component.rs index c88c58489df1f..7442900589b63 100644 --- a/crates/bevy_ecs/src/component.rs +++ b/crates/bevy_ecs/src/component.rs @@ -35,9 +35,15 @@ pub trait Component: Send + Sync + 'static { type Storage: ComponentStorage; } +/// A [ComponentStorage] strategy that prioritizes efficient iteration pub struct TableStorage; + +/// A [ComponentStorage] strategy that prioritizes efficient insertion and removal pub struct SparseStorage; +/// The strategy used to store a [Component] within the [World](crate::world::World) +/// +/// This trait is sealed, and cannot be implemented externally. pub trait ComponentStorage: sealed::Sealed { // because the trait is sealed, those items are private API. const STORAGE_TYPE: StorageType; @@ -90,6 +96,7 @@ impl Default for StorageType { } } +/// Stores metadata that identify and describe a specific [Component] #[derive(Debug)] pub struct ComponentInfo { id: ComponentId, @@ -139,7 +146,8 @@ impl ComponentInfo { /// Unique identifier for a component (or resource) type. /// -/// Used to lookup storage information in ['Components'](crate::component::Components) +/// Used to lookup storage information in ['Components'](crate::component::Components). +/// These are assigned sequentially, beginning at 0. #[derive(Debug, Copy, Clone, Hash, Ord, PartialOrd, Eq, PartialEq)] pub struct ComponentId(usize); @@ -358,6 +366,7 @@ impl Components { } } +/// Stores the last time a [Component] or [Resource] was added or changed #[derive(Clone, Debug)] pub struct ComponentTicks { pub(crate) added: u32, diff --git a/crates/bevy_ecs/src/entity/map_entities.rs b/crates/bevy_ecs/src/entity/map_entities.rs index b6cf162177859..06643ecfaa1ba 100644 --- a/crates/bevy_ecs/src/entity/map_entities.rs +++ b/crates/bevy_ecs/src/entity/map_entities.rs @@ -13,6 +13,10 @@ pub trait MapEntities { fn map_entities(&mut self, entity_map: &EntityMap) -> Result<(), MapEntitiesError>; } +/// A map storing a map from one set of entities to a new set +/// +/// This is useful for reflection, scenes, and hierarchies, +/// particularly when used with the [MapEntities] trait #[derive(Default, Debug)] pub struct EntityMap { map: HashMap, diff --git a/crates/bevy_ecs/src/entity/mod.rs b/crates/bevy_ecs/src/entity/mod.rs index c74974d7a4457..3fea64bb1b429 100644 --- a/crates/bevy_ecs/src/entity/mod.rs +++ b/crates/bevy_ecs/src/entity/mod.rs @@ -50,6 +50,7 @@ pub struct Entity { pub(crate) id: u32, } +/// The result of attempting to allocate an entity using [Entity::alloc_at_without_replacement] pub enum AllocAtWithoutReplacement { Exists(EntityLocation), DidNotExist, @@ -158,6 +159,7 @@ impl<'a> Iterator for ReserveEntitiesIterator<'a> { impl<'a> core::iter::ExactSizeIterator for ReserveEntitiesIterator<'a> {} +/// The central collection of [Entity]s found within a [World](crate::world::World). #[derive(Debug, Default)] pub struct Entities { pub meta: Vec, @@ -404,6 +406,9 @@ impl Entities { .map_or(false, |e| e.generation() == entity.generation) } + /// Despawns all entities, removing them from the [World](crate::world::World) + /// + /// All data will be lost, but the size of the underlying vector storages will not be reset. pub fn clear(&mut self) { self.meta.clear(); self.pending.clear(); @@ -516,6 +521,7 @@ impl Entities { } } +/// The position within [Entities] of a particular [Entity] #[derive(Copy, Clone, Debug)] pub struct EntityMeta { pub generation: u32, From 5740dea945160152eb7a74ef0db1d88078d225af Mon Sep 17 00:00:00 2001 From: Alice Cecile Date: Fri, 17 Dec 2021 20:04:31 -0500 Subject: [PATCH 5/7] Notes on uniqueness --- crates/bevy_ecs/src/archetype.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/crates/bevy_ecs/src/archetype.rs b/crates/bevy_ecs/src/archetype.rs index 7ea0b5b5397d3..ba71b467c180c 100644 --- a/crates/bevy_ecs/src/archetype.rs +++ b/crates/bevy_ecs/src/archetype.rs @@ -15,6 +15,8 @@ use std::{ }; /// The unique identifier of an [`Archetype`] +/// +/// These are only unique (and consistent) within a particular [World](crate::world::World) #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] pub struct ArchetypeId(usize); @@ -348,6 +350,7 @@ pub struct ArchetypeIdentity { /// The unique identifier for a component within a particular archetype /// /// These are unique across archetypes. +/// These are only unique (and consistent) within a particular [World](crate::world::World) #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] pub struct ArchetypeComponentId(usize); From 9d8db8ba4568322d4e4d9f7cec2f1ddb9c76cb80 Mon Sep 17 00:00:00 2001 From: Alice Cecile Date: Fri, 17 Dec 2021 20:06:47 -0500 Subject: [PATCH 6/7] ComponentStatus details Credit to @DJMcNab --- crates/bevy_ecs/src/archetype.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/crates/bevy_ecs/src/archetype.rs b/crates/bevy_ecs/src/archetype.rs index ba71b467c180c..16bd26c1a4aa2 100644 --- a/crates/bevy_ecs/src/archetype.rs +++ b/crates/bevy_ecs/src/archetype.rs @@ -37,6 +37,10 @@ impl ArchetypeId { } /// Records whether a component was modified by addition or mutation +/// +/// When adding a bundle to an archetype, +/// this value will be `Added` if it was not in the archetype, +/// and `Mutated if it was pub enum ComponentStatus { Added, Mutated, From 9ee3ba519f0ea9f80833dfba586f09e725296676 Mon Sep 17 00:00:00 2001 From: Alice Cecile Date: Sun, 19 Dec 2021 09:37:53 -0500 Subject: [PATCH 7/7] Fix broken doc links --- crates/bevy_ecs/src/entity/mod.rs | 2 +- crates/bevy_ecs/src/query/fetch.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/bevy_ecs/src/entity/mod.rs b/crates/bevy_ecs/src/entity/mod.rs index 3fea64bb1b429..07d4f24d052a5 100644 --- a/crates/bevy_ecs/src/entity/mod.rs +++ b/crates/bevy_ecs/src/entity/mod.rs @@ -50,7 +50,7 @@ pub struct Entity { pub(crate) id: u32, } -/// The result of attempting to allocate an entity using [Entity::alloc_at_without_replacement] +/// The result of attempting to allocate an entity using [Entity::alloc_at_without_replacement](Entity) pub enum AllocAtWithoutReplacement { Exists(EntityLocation), DidNotExist, diff --git a/crates/bevy_ecs/src/query/fetch.rs b/crates/bevy_ecs/src/query/fetch.rs index 3e9e160497d4b..c3f089ef4aaa0 100644 --- a/crates/bevy_ecs/src/query/fetch.rs +++ b/crates/bevy_ecs/src/query/fetch.rs @@ -57,7 +57,7 @@ pub type QueryItem<'w, 's, Q> = <::Fetch as Fetch<'w, 's>>::Ite /// Describes the data that is accessed by a [WorldQuery] type. /// -/// See [SystemParamFetch](crate::system::system_param::SystemParamFetch) for the [SystemParam](crate::system::SystemParam) analogue. +/// See [SystemParamFetch](crate::system::SystemParamFetch) for the [SystemParam](crate::system::SystemParam) analogue. /// /// By default, a [Fetch] implies read-write access. /// Structs which implement this trait may also want to implement one of the following extension traits: