Skip to content

Document Fetch, Access and related types for bevy_ecs #3386

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

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions crates/bevy_ecs/src/archetype.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ use std::{
ops::{Index, IndexMut},
};

/// 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);

Expand All @@ -33,16 +36,26 @@ 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,
}

/// Stores the information needed to add a bundle to the archetype graph.
pub struct AddBundle {
pub archetype_id: ArchetypeId,
pub bundle_status: Vec<ComponentStatus>,
}

/// 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<BundleId, AddBundle>,
Expand Down Expand Up @@ -116,6 +129,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<Entity>,
Expand Down Expand Up @@ -335,6 +351,10 @@ pub struct ArchetypeIdentity {
sparse_set_components: Cow<'static, [ComponentId]>,
}

/// 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);

Expand All @@ -361,6 +381,7 @@ impl SparseSetIndex for ArchetypeComponentId {
}
}

/// The collection of [`Archetype`] stored in the [`World`](crate::world::World)
pub struct Archetypes {
pub(crate) archetypes: Vec<Archetype>,
pub(crate) archetype_component_count: usize,
Expand Down
3 changes: 3 additions & 0 deletions crates/bevy_ecs/src/bundle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -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<ComponentId>,
Expand Down Expand Up @@ -572,6 +574,7 @@ impl<'a, 'b> BundleSpawner<'a, 'b> {
}
}

/// A central storage of [Bundle]s
#[derive(Default)]
pub struct Bundles {
bundle_infos: Vec<BundleInfo>,
Expand Down
23 changes: 23 additions & 0 deletions crates/bevy_ecs/src/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -90,6 +96,7 @@ impl Default for StorageType {
}
}

/// Stores metadata that identify and describe a specific [Component]
#[derive(Debug)]
pub struct ComponentInfo {
id: ComponentId,
Expand Down Expand Up @@ -137,6 +144,10 @@ impl ComponentInfo {
}
}

/// Unique identifier for a component (or resource) type.
///
/// 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);

Expand All @@ -163,6 +174,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,
Expand Down Expand Up @@ -232,6 +246,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<ComponentInfo>,
Expand Down Expand Up @@ -344,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,
Expand Down
4 changes: 4 additions & 0 deletions crates/bevy_ecs/src/entity/map_entities.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Entity, Entity>,
Expand Down
6 changes: 6 additions & 0 deletions crates/bevy_ecs/src/entity/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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](Entity)
pub enum AllocAtWithoutReplacement {
Exists(EntityLocation),
DidNotExist,
Expand Down Expand Up @@ -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<EntityMeta>,
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -516,6 +521,7 @@ impl Entities {
}
}

/// The position within [Entities] of a particular [Entity]
#[derive(Copy, Clone, Debug)]
pub struct EntityMeta {
pub generation: u32,
Expand Down
18 changes: 14 additions & 4 deletions crates/bevy_ecs/src/query/access.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<T: SparseSetIndex> {
/// 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<T>,
_marker: PhantomData<T>,
}

impl<T: SparseSetIndex> Default for Access<T> {
Expand All @@ -20,7 +21,7 @@ impl<T: SparseSetIndex> Default for Access<T> {
reads_all: false,
reads_and_writes: Default::default(),
writes: Default::default(),
marker: PhantomData,
_marker: PhantomData,
}
}
}
Expand Down Expand Up @@ -129,6 +130,10 @@ impl<T: SparseSetIndex> Access<T> {
}
}

/// 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<T: SparseSetIndex> {
access: Access<T>,
Expand Down Expand Up @@ -188,6 +193,11 @@ impl<T: SparseSetIndex> FilteredAccess<T> {
}
}

/// 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<T: SparseSetIndex> {
combined_access: Access<T>,
filtered_accesses: Vec<FilteredAccess<T>>,
Expand Down
Loading