mirror of
https://github.com/bevyengine/bevy
synced 2024-11-10 07:04:33 +00:00
Document and lock down types in bevy_ecs::archetype (#6742)
# Objective Document `bevy_ecs::archetype` and and declutter the public documentation for the module by making types non-`pub`. Addresses #3362 for `bevy_ecs::archetype`. ## Solution - Add module level documentation. - Add type and API level documentation for all public facing types. - Make `ArchetypeId`, `ArchetypeGeneration`, and `ArchetypeComponentId` truly opaque IDs that are not publicly constructable. - Make `AddBundle` non-pub, make `Edges::get_add_bundle` return a `Option<ArchetypeId>` and fork the existing function into `Edges::get_add_bundle_internal`. - Remove `pub(crate)` on fields that have a corresponding pub accessor function. - Removed the `Archetypes: Default` impl, opting for a `pub(crate) fn new` alternative instead. --- ## Changelog Added: `ArchetypeGeneration` now implements `Ord` and `PartialOrd`. Removed: `Archetypes`'s `Default` implementation. Removed: `Archetype::new` and `Archetype::is_empty`. Removed: `ArchetypeId::new` and `ArchetypeId::value`. Removed: `ArchetypeGeneration::value` Removed: `ArchetypeIdentity`. Removed: `ArchetypeComponentId::new` and `ArchetypeComponentId::value`. Removed: `AddBundle`. `Edges::get_add_bundle` now returns `Option<ArchetypeId>`
This commit is contained in:
parent
bbb652a438
commit
d79888bdae
5 changed files with 224 additions and 54 deletions
|
@ -1,5 +1,23 @@
|
|||
//! Types for defining [`Archetype`]s, collections of entities that have the same set of
|
||||
//! components.
|
||||
//!
|
||||
//! An archetype uniquely describes a group of entities that share the same components:
|
||||
//! a world only has one archetype for each unique combination of components, and all
|
||||
//! entities that have those components and only those components belong to that
|
||||
//! archetype.
|
||||
//!
|
||||
//! Archetypes are not to be confused with [`Table`]s. Each archetype stores its table
|
||||
//! components in one table, and each archetype uniquely points to one table, but multiple
|
||||
//! archetypes may store their table components in the same table. These archetypes
|
||||
//! differ only by the [`SparseSet`] components.
|
||||
//!
|
||||
//! Like tables, archetypes can be created but are never cleaned up. Empty archetypes are
|
||||
//! not removed, and persist until the world is dropped.
|
||||
//!
|
||||
//! Archetypes can be fetched from [`Archetypes`], which is accessible via [`World::archetypes`].
|
||||
//!
|
||||
//! [`Table`]: crate::storage::Table
|
||||
//! [`World::archetypes`]: crate::world::World::archetypes
|
||||
|
||||
use crate::{
|
||||
bundle::BundleId,
|
||||
|
@ -13,11 +31,21 @@ use std::{
|
|||
ops::{Index, IndexMut},
|
||||
};
|
||||
|
||||
/// An opaque unique ID for a single [`Archetype`] within a [`World`].
|
||||
///
|
||||
/// Archetype IDs are only valid for a given World, and are not globally unique.
|
||||
/// Attempting to use an archetype ID on a world that it wasn't sourced from will
|
||||
/// not return the archetype with the same components. The only exception to this is
|
||||
/// [`EMPTY`] which is guarenteed to be identical for all Worlds.
|
||||
///
|
||||
/// [`World`]: crate::world::World
|
||||
/// [`EMPTY`]: crate::archetype::ArchetypeId::EMPTY
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
|
||||
#[repr(transparent)]
|
||||
pub struct ArchetypeId(usize);
|
||||
|
||||
impl ArchetypeId {
|
||||
/// The ID for the [`Archetype`] without any components.
|
||||
pub const EMPTY: ArchetypeId = ArchetypeId(0);
|
||||
/// # Safety:
|
||||
///
|
||||
|
@ -25,12 +53,12 @@ impl ArchetypeId {
|
|||
pub const INVALID: ArchetypeId = ArchetypeId(usize::MAX);
|
||||
|
||||
#[inline]
|
||||
pub const fn new(index: usize) -> Self {
|
||||
pub(crate) const fn new(index: usize) -> Self {
|
||||
ArchetypeId(index)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn index(self) -> usize {
|
||||
pub(crate) fn index(self) -> usize {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
@ -41,9 +69,9 @@ pub(crate) enum ComponentStatus {
|
|||
Mutated,
|
||||
}
|
||||
|
||||
pub struct AddBundle {
|
||||
pub(crate) struct AddBundle {
|
||||
pub archetype_id: ArchetypeId,
|
||||
pub(crate) bundle_status: Vec<ComponentStatus>,
|
||||
pub bundle_status: Vec<ComponentStatus>,
|
||||
}
|
||||
|
||||
/// This trait is used to report the status of [`Bundle`](crate::bundle::Bundle) components
|
||||
|
@ -98,11 +126,29 @@ pub struct Edges {
|
|||
}
|
||||
|
||||
impl Edges {
|
||||
/// Checks the cache for the target archetype when adding a bundle to the
|
||||
/// source archetype. For more information, see [`EntityMut::insert`].
|
||||
///
|
||||
/// If this returns `None`, it means there has not been a transition from
|
||||
/// the source archetype via the provided bundle.
|
||||
///
|
||||
/// [`EntityMut::insert`]: crate::world::EntityMut::insert
|
||||
#[inline]
|
||||
pub fn get_add_bundle(&self, bundle_id: BundleId) -> Option<&AddBundle> {
|
||||
pub fn get_add_bundle(&self, bundle_id: BundleId) -> Option<ArchetypeId> {
|
||||
self.get_add_bundle_internal(bundle_id)
|
||||
.map(|bundle| bundle.archetype_id)
|
||||
}
|
||||
|
||||
/// Internal version of `get_add_bundle` that fetches the full `AddBundle`.
|
||||
#[inline]
|
||||
pub(crate) fn get_add_bundle_internal(&self, bundle_id: BundleId) -> Option<&AddBundle> {
|
||||
self.add_bundle.get(bundle_id)
|
||||
}
|
||||
|
||||
/// Caches the target archetype when adding a bundle to the source archetype.
|
||||
/// For more information, see [`EntityMut::insert`].
|
||||
///
|
||||
/// [`EntityMut::insert`]: crate::world::EntityMut::insert
|
||||
#[inline]
|
||||
pub(crate) fn insert_add_bundle(
|
||||
&mut self,
|
||||
|
@ -119,11 +165,25 @@ impl Edges {
|
|||
);
|
||||
}
|
||||
|
||||
/// Checks the cache for the target archetype when removing a bundle to the
|
||||
/// source archetype. For more information, see [`EntityMut::remove`].
|
||||
///
|
||||
/// If this returns `None`, it means there has not been a transition from
|
||||
/// the source archetype via the provided bundle.
|
||||
///
|
||||
/// If this returns `Some(None)`, it means that the bundle cannot be removed
|
||||
/// from the source archetype.
|
||||
///
|
||||
/// [`EntityMut::remove`]: crate::world::EntityMut::remove
|
||||
#[inline]
|
||||
pub fn get_remove_bundle(&self, bundle_id: BundleId) -> Option<Option<ArchetypeId>> {
|
||||
self.remove_bundle.get(bundle_id).cloned()
|
||||
}
|
||||
|
||||
/// Caches the target archetype when removing a bundle to the source archetype.
|
||||
/// For more information, see [`EntityMut::remove`].
|
||||
///
|
||||
/// [`EntityMut::remove`]: crate::world::EntityMut::remove
|
||||
#[inline]
|
||||
pub(crate) fn insert_remove_bundle(
|
||||
&mut self,
|
||||
|
@ -133,6 +193,13 @@ impl Edges {
|
|||
self.remove_bundle.insert(bundle_id, archetype_id);
|
||||
}
|
||||
|
||||
/// Checks the cache for the target archetype when removing a bundle to the
|
||||
/// source archetype. For more information, see [`EntityMut::remove_intersection`].
|
||||
///
|
||||
/// If this returns `None`, it means there has not been a transition from
|
||||
/// the source archetype via the provided bundle.
|
||||
///
|
||||
/// [`EntityMut::remove_intersection`]: crate::world::EntityMut::remove_intersection
|
||||
#[inline]
|
||||
pub fn get_remove_bundle_intersection(
|
||||
&self,
|
||||
|
@ -141,6 +208,10 @@ impl Edges {
|
|||
self.remove_bundle_intersection.get(bundle_id).cloned()
|
||||
}
|
||||
|
||||
/// Caches the target archetype when removing a bundle to the source archetype.
|
||||
/// For more information, see [`EntityMut::remove_intersection`].
|
||||
///
|
||||
/// [`EntityMut::remove_intersection`]: crate::world::EntityMut::remove_intersection
|
||||
#[inline]
|
||||
pub(crate) fn insert_remove_bundle_intersection(
|
||||
&mut self,
|
||||
|
@ -152,17 +223,24 @@ impl Edges {
|
|||
}
|
||||
}
|
||||
|
||||
/// Metadata about an [`Entity`] in a [`Archetype`].
|
||||
pub struct ArchetypeEntity {
|
||||
pub(crate) entity: Entity,
|
||||
pub(crate) table_row: usize,
|
||||
entity: Entity,
|
||||
table_row: usize,
|
||||
}
|
||||
|
||||
impl ArchetypeEntity {
|
||||
pub fn entity(&self) -> Entity {
|
||||
/// The ID of the entity.
|
||||
#[inline]
|
||||
pub const fn entity(&self) -> Entity {
|
||||
self.entity
|
||||
}
|
||||
|
||||
pub fn table_row(&self) -> usize {
|
||||
/// The row in the [`Table`] where the entity's components are stored.
|
||||
///
|
||||
/// [`Table`]: crate::storage::Table
|
||||
#[inline]
|
||||
pub const fn table_row(&self) -> usize {
|
||||
self.table_row
|
||||
}
|
||||
}
|
||||
|
@ -172,11 +250,20 @@ pub(crate) struct ArchetypeSwapRemoveResult {
|
|||
pub(crate) table_row: usize,
|
||||
}
|
||||
|
||||
pub(crate) struct ArchetypeComponentInfo {
|
||||
pub(crate) storage_type: StorageType,
|
||||
pub(crate) archetype_component_id: ArchetypeComponentId,
|
||||
/// Internal metadata for a [`Component`] within a given [`Archetype`].
|
||||
///
|
||||
/// [`Component`]: crate::component::Component
|
||||
struct ArchetypeComponentInfo {
|
||||
storage_type: StorageType,
|
||||
archetype_component_id: ArchetypeComponentId,
|
||||
}
|
||||
|
||||
/// Metadata for a single archetype within a [`World`].
|
||||
///
|
||||
/// For more information, see the *[module level documentation]*.
|
||||
///
|
||||
/// [`World`]: crate::world::World
|
||||
/// [module level documentation]: crate::archetype
|
||||
pub struct Archetype {
|
||||
id: ArchetypeId,
|
||||
table_id: TableId,
|
||||
|
@ -186,7 +273,7 @@ pub struct Archetype {
|
|||
}
|
||||
|
||||
impl Archetype {
|
||||
pub fn new(
|
||||
pub(crate) fn new(
|
||||
id: ArchetypeId,
|
||||
table_id: TableId,
|
||||
table_components: impl Iterator<Item = (ComponentId, ArchetypeComponentId)>,
|
||||
|
@ -223,11 +310,15 @@ impl Archetype {
|
|||
}
|
||||
}
|
||||
|
||||
/// Fetches the ID for the archetype.
|
||||
#[inline]
|
||||
pub fn id(&self) -> ArchetypeId {
|
||||
self.id
|
||||
}
|
||||
|
||||
/// Fetches the archetype's [`Table`] ID.
|
||||
///
|
||||
/// [`Table`]: crate::storage::Table
|
||||
#[inline]
|
||||
pub fn table_id(&self) -> TableId {
|
||||
self.table_id
|
||||
|
@ -238,6 +329,11 @@ impl Archetype {
|
|||
&self.entities
|
||||
}
|
||||
|
||||
/// Gets an iterator of all of the components stored in [`Table`]s.
|
||||
///
|
||||
/// All of the IDs are unique.
|
||||
///
|
||||
/// [`Table`]: crate::storage::Table
|
||||
#[inline]
|
||||
pub fn table_components(&self) -> impl Iterator<Item = ComponentId> + '_ {
|
||||
self.components
|
||||
|
@ -246,6 +342,11 @@ impl Archetype {
|
|||
.map(|(id, _)| *id)
|
||||
}
|
||||
|
||||
/// Gets an iterator of all of the components stored in [`ComponentSparseSet`]s.
|
||||
///
|
||||
/// All of the IDs are unique.
|
||||
///
|
||||
/// [`ComponentSparseSet`]: crate::storage::ComponentSparseSet
|
||||
#[inline]
|
||||
pub fn sparse_set_components(&self) -> impl Iterator<Item = ComponentId> + '_ {
|
||||
self.components
|
||||
|
@ -254,31 +355,57 @@ impl Archetype {
|
|||
.map(|(id, _)| *id)
|
||||
}
|
||||
|
||||
/// Gets an iterator of all of the components in the archetype.
|
||||
///
|
||||
/// All of the IDs are unique.
|
||||
#[inline]
|
||||
pub fn components(&self) -> impl Iterator<Item = ComponentId> + '_ {
|
||||
self.components.indices()
|
||||
}
|
||||
|
||||
/// Fetches a immutable reference to the archetype's [`Edges`], a cache of
|
||||
/// archetypal relationships.
|
||||
#[inline]
|
||||
pub fn edges(&self) -> &Edges {
|
||||
&self.edges
|
||||
}
|
||||
|
||||
/// Fetches a mutable reference to the archetype's [`Edges`], a cache of
|
||||
/// archetypal relationships.
|
||||
#[inline]
|
||||
pub(crate) fn edges_mut(&mut self) -> &mut Edges {
|
||||
&mut self.edges
|
||||
}
|
||||
|
||||
/// Fetches the row in the [`Table`] where the components for the entity at `index`
|
||||
/// is stored.
|
||||
///
|
||||
/// An entity's archetype index can be fetched from [`EntityLocation::index`], which
|
||||
/// can be retrieved from [`Entities::get`].
|
||||
///
|
||||
/// # Panics
|
||||
/// This function will panic if `index >= self.len()`.
|
||||
///
|
||||
/// [`Table`]: crate::storage::Table
|
||||
/// [`EntityLocation`]: crate::entity::EntityLocation::index
|
||||
/// [`Entities::get`]: crate::entity::Entities::get
|
||||
#[inline]
|
||||
pub fn entity_table_row(&self, index: usize) -> usize {
|
||||
self.entities[index].table_row
|
||||
}
|
||||
|
||||
/// Updates if the components for the entity at `index` can be found
|
||||
/// in the corresponding table.
|
||||
///
|
||||
/// # Panics
|
||||
/// This function will panic if `index >= self.len()`.
|
||||
#[inline]
|
||||
pub(crate) fn set_entity_table_row(&mut self, index: usize, table_row: usize) {
|
||||
self.entities[index].table_row = table_row;
|
||||
}
|
||||
|
||||
/// Allocates an entity to the archetype.
|
||||
///
|
||||
/// # Safety
|
||||
/// valid component values must be immediately written to the relevant storages
|
||||
/// `table_row` must be valid
|
||||
|
@ -297,6 +424,9 @@ impl Archetype {
|
|||
|
||||
/// Removes the entity at `index` by swapping it out. Returns the table row the entity is stored
|
||||
/// in.
|
||||
///
|
||||
/// # Panics
|
||||
/// This function will panic if `index >= self.len()`
|
||||
pub(crate) fn swap_remove(&mut self, index: usize) -> ArchetypeSwapRemoveResult {
|
||||
let is_last = index == self.entities.len() - 1;
|
||||
let entity = self.entities.swap_remove(index);
|
||||
|
@ -310,21 +440,27 @@ impl Archetype {
|
|||
}
|
||||
}
|
||||
|
||||
/// Gets the total number of entities that belong to the archetype.
|
||||
#[inline]
|
||||
pub fn len(&self) -> usize {
|
||||
self.entities.len()
|
||||
}
|
||||
|
||||
/// Checks if the archetype has any entities.
|
||||
#[inline]
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.entities.is_empty()
|
||||
}
|
||||
|
||||
/// Checks if the archetype contains a specific component. This runs in `O(1)` time.
|
||||
#[inline]
|
||||
pub fn contains(&self, component_id: ComponentId) -> bool {
|
||||
self.components.contains(component_id)
|
||||
}
|
||||
|
||||
/// Gets the type of storage where a component in the archetype can be found.
|
||||
/// Returns `None` if the component is not part of the archetype.
|
||||
/// This runs in `O(1)` time.
|
||||
#[inline]
|
||||
pub fn get_storage_type(&self, component_id: ComponentId) -> Option<StorageType> {
|
||||
self.components
|
||||
|
@ -332,6 +468,9 @@ impl Archetype {
|
|||
.map(|info| info.storage_type)
|
||||
}
|
||||
|
||||
/// Fetches the corresponding [`ArchetypeComponentId`] for a component in the archetype.
|
||||
/// Returns `None` if the component is not part of the archetype.
|
||||
/// This runs in `O(1)` time.
|
||||
#[inline]
|
||||
pub fn get_archetype_component_id(
|
||||
&self,
|
||||
|
@ -342,46 +481,68 @@ impl Archetype {
|
|||
.map(|info| info.archetype_component_id)
|
||||
}
|
||||
|
||||
/// Clears all entities from the archetype.
|
||||
pub(crate) fn clear_entities(&mut self) {
|
||||
self.entities.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/// A generational id that changes every time the set of archetypes changes
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||
/// An opaque generational id that changes every time the set of [`Archetypes`] changes.
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
|
||||
pub struct ArchetypeGeneration(usize);
|
||||
|
||||
impl ArchetypeGeneration {
|
||||
#[inline]
|
||||
pub const fn initial() -> Self {
|
||||
pub(crate) const fn initial() -> Self {
|
||||
ArchetypeGeneration(0)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn value(self) -> usize {
|
||||
pub(crate) fn value(self) -> usize {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Hash, PartialEq, Eq)]
|
||||
pub struct ArchetypeIdentity {
|
||||
struct ArchetypeIdentity {
|
||||
table_components: Box<[ComponentId]>,
|
||||
sparse_set_components: Box<[ComponentId]>,
|
||||
}
|
||||
|
||||
/// An opaque unique joint ID for a [`Component`] in an [`Archetype`] within a [`World`].
|
||||
///
|
||||
/// A component may be present within multiple archetypes, but each component within
|
||||
/// each archetype has its own unique `ArchetypeComponentId`. This is leveraged by the system
|
||||
/// schedulers to opportunistically run multiple systems in parallel that would otherwise
|
||||
/// conflict. For example, `Query<&mut A, With<B>>` and `Query<&mut A, Without<B>>` can run in
|
||||
/// parallel as the matched `ArchetypeComponentId` sets for both queries are disjoint, even
|
||||
/// though `&mut A` on both queries point to the same [`ComponentId`].
|
||||
///
|
||||
/// In SQL terms, these IDs are composite keys on a [many-to-many relationship] between archetypes
|
||||
/// and components. Each component type will have only one [`ComponentId`], but may have many
|
||||
/// [`ArchetypeComponentId`]s, one for every archetype the component is present in. Likewise, each
|
||||
/// archetype will have only one [`ArchetypeId`] but may have many [`ArchetypeComponentId`]s, one
|
||||
/// for each component that belongs to the archetype.
|
||||
///
|
||||
/// Every [`Resource`] is also assigned one of these IDs. As resources do not belong to any
|
||||
/// particular archetype, a resource's ID uniquely identifies it.
|
||||
///
|
||||
/// These IDs are only valid within a given World, and are not globally unique.
|
||||
/// Attempting to use an ID on a world that it wasn't sourced from will
|
||||
/// not point to the same archetype nor the same component.
|
||||
///
|
||||
/// [`Component`]: crate::component::Component
|
||||
/// [`World`]: crate::world::World
|
||||
/// [`Resource`]: crate::system::Resource
|
||||
/// [many-to-many relationship]: https://en.wikipedia.org/wiki/Many-to-many_(data_model)
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
|
||||
pub struct ArchetypeComponentId(usize);
|
||||
|
||||
impl ArchetypeComponentId {
|
||||
#[inline]
|
||||
pub const fn new(index: usize) -> Self {
|
||||
pub(crate) const fn new(index: usize) -> Self {
|
||||
Self(index)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn index(self) -> usize {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl SparseSetIndex for ArchetypeComponentId {
|
||||
|
@ -395,14 +556,20 @@ impl SparseSetIndex for ArchetypeComponentId {
|
|||
}
|
||||
}
|
||||
|
||||
/// The backing store of all [`Archetype`]s within a [`World`].
|
||||
///
|
||||
/// For more information, see the *[module level documentation]*.
|
||||
///
|
||||
/// [`World`]: crate::world::World
|
||||
/// [*module level documentation]: crate::archetype
|
||||
pub struct Archetypes {
|
||||
pub(crate) archetypes: Vec<Archetype>,
|
||||
pub(crate) archetype_component_count: usize,
|
||||
archetype_ids: HashMap<ArchetypeIdentity, ArchetypeId>,
|
||||
}
|
||||
|
||||
impl Default for Archetypes {
|
||||
fn default() -> Self {
|
||||
impl Archetypes {
|
||||
pub(crate) fn new() -> Self {
|
||||
let mut archetypes = Archetypes {
|
||||
archetypes: Vec::new(),
|
||||
archetype_ids: Default::default(),
|
||||
|
@ -411,25 +578,29 @@ impl Default for Archetypes {
|
|||
archetypes.get_id_or_insert(TableId::empty(), Vec::new(), Vec::new());
|
||||
archetypes
|
||||
}
|
||||
}
|
||||
|
||||
impl Archetypes {
|
||||
#[inline]
|
||||
pub fn generation(&self) -> ArchetypeGeneration {
|
||||
ArchetypeGeneration(self.archetypes.len())
|
||||
}
|
||||
|
||||
/// Fetches the total number of [`Archetype`]s within the world.
|
||||
#[inline]
|
||||
#[allow(clippy::len_without_is_empty)] // the internal vec is never empty.
|
||||
pub fn len(&self) -> usize {
|
||||
self.archetypes.len()
|
||||
}
|
||||
|
||||
/// Fetches an immutable reference to the archetype without any compoennts.
|
||||
///
|
||||
/// Shorthand for `archetypes.get(ArchetypeId::EMPTY).unwrap()`
|
||||
#[inline]
|
||||
pub fn empty(&self) -> &Archetype {
|
||||
// SAFETY: empty archetype always exists
|
||||
unsafe { self.archetypes.get_unchecked(ArchetypeId::EMPTY.index()) }
|
||||
}
|
||||
|
||||
/// Fetches an mutable reference to the archetype without any compoennts.
|
||||
#[inline]
|
||||
pub(crate) fn empty_mut(&mut self) -> &mut Archetype {
|
||||
// SAFETY: empty archetype always exists
|
||||
|
@ -439,11 +610,8 @@ impl Archetypes {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.archetypes.is_empty()
|
||||
}
|
||||
|
||||
/// Fetches an immutable reference to an [`Archetype`] using its
|
||||
/// ID. Returns `None` if no corresponding archetype exists.
|
||||
#[inline]
|
||||
pub fn get(&self, id: ArchetypeId) -> Option<&Archetype> {
|
||||
self.archetypes.get(id.index())
|
||||
|
@ -464,6 +632,7 @@ impl Archetypes {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns a read-only iterator over all archetypes.
|
||||
#[inline]
|
||||
pub fn iter(&self) -> impl Iterator<Item = &Archetype> {
|
||||
self.archetypes.iter()
|
||||
|
@ -517,6 +686,7 @@ impl Archetypes {
|
|||
self.archetype_component_count
|
||||
}
|
||||
|
||||
/// Clears all entities from all archetypes.
|
||||
pub(crate) fn clear_entities(&mut self) {
|
||||
for archetype in &mut self.archetypes {
|
||||
archetype.clear_entities();
|
||||
|
|
|
@ -420,8 +420,8 @@ impl BundleInfo {
|
|||
components: &mut Components,
|
||||
archetype_id: ArchetypeId,
|
||||
) -> ArchetypeId {
|
||||
if let Some(add_bundle) = archetypes[archetype_id].edges().get_add_bundle(self.id) {
|
||||
return add_bundle.archetype_id;
|
||||
if let Some(add_bundle_id) = archetypes[archetype_id].edges().get_add_bundle(self.id) {
|
||||
return add_bundle_id;
|
||||
}
|
||||
let mut new_table_components = Vec::new();
|
||||
let mut new_sparse_set_components = Vec::new();
|
||||
|
@ -537,7 +537,7 @@ impl<'a, 'b> BundleInserter<'a, 'b> {
|
|||
let add_bundle = self
|
||||
.archetype
|
||||
.edges()
|
||||
.get_add_bundle(self.bundle_info.id)
|
||||
.get_add_bundle_internal(self.bundle_info.id)
|
||||
.unwrap();
|
||||
self.bundle_info.write_components(
|
||||
self.table,
|
||||
|
@ -562,7 +562,7 @@ impl<'a, 'b> BundleInserter<'a, 'b> {
|
|||
let add_bundle = self
|
||||
.archetype
|
||||
.edges()
|
||||
.get_add_bundle(self.bundle_info.id)
|
||||
.get_add_bundle_internal(self.bundle_info.id)
|
||||
.unwrap();
|
||||
self.bundle_info.write_components(
|
||||
self.table,
|
||||
|
@ -614,7 +614,7 @@ impl<'a, 'b> BundleInserter<'a, 'b> {
|
|||
let add_bundle = self
|
||||
.archetype
|
||||
.edges()
|
||||
.get_add_bundle(self.bundle_info.id)
|
||||
.get_add_bundle_internal(self.bundle_info.id)
|
||||
.unwrap();
|
||||
self.bundle_info.write_components(
|
||||
new_table,
|
||||
|
|
|
@ -550,8 +550,8 @@ impl<'w, 's, Q: WorldQuery, F: ReadOnlyWorldQuery> QueryIterationCursor<'w, 's,
|
|||
let archetype_entity = self.archetype_entities.get_unchecked(index);
|
||||
Some(Q::fetch(
|
||||
&mut self.fetch,
|
||||
archetype_entity.entity,
|
||||
archetype_entity.table_row,
|
||||
archetype_entity.entity(),
|
||||
archetype_entity.table_row(),
|
||||
))
|
||||
}
|
||||
} else {
|
||||
|
@ -644,8 +644,8 @@ impl<'w, 's, Q: WorldQuery, F: ReadOnlyWorldQuery> QueryIterationCursor<'w, 's,
|
|||
let archetype_entity = self.archetype_entities.get_unchecked(self.current_index);
|
||||
if !F::filter_fetch(
|
||||
&mut self.filter,
|
||||
archetype_entity.entity,
|
||||
archetype_entity.table_row,
|
||||
archetype_entity.entity(),
|
||||
archetype_entity.table_row(),
|
||||
) {
|
||||
self.current_index += 1;
|
||||
continue;
|
||||
|
@ -655,8 +655,8 @@ impl<'w, 's, Q: WorldQuery, F: ReadOnlyWorldQuery> QueryIterationCursor<'w, 's,
|
|||
// `current_index` is an archetype index row in range of the current archetype, because if it was not, then the if above would have been executed.
|
||||
let item = Q::fetch(
|
||||
&mut self.fetch,
|
||||
archetype_entity.entity,
|
||||
archetype_entity.table_row,
|
||||
archetype_entity.entity(),
|
||||
archetype_entity.table_row(),
|
||||
);
|
||||
self.current_index += 1;
|
||||
return Some(item);
|
||||
|
|
|
@ -966,15 +966,15 @@ impl<Q: WorldQuery, F: ReadOnlyWorldQuery> QueryState<Q, F> {
|
|||
let archetype_entity = entities.get_unchecked(idx);
|
||||
if !F::filter_fetch(
|
||||
&mut filter,
|
||||
archetype_entity.entity,
|
||||
archetype_entity.table_row,
|
||||
archetype_entity.entity(),
|
||||
archetype_entity.table_row(),
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
func(Q::fetch(
|
||||
&mut fetch,
|
||||
archetype_entity.entity,
|
||||
archetype_entity.table_row,
|
||||
archetype_entity.entity(),
|
||||
archetype_entity.table_row(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -1097,15 +1097,15 @@ impl<Q: WorldQuery, F: ReadOnlyWorldQuery> QueryState<Q, F> {
|
|||
let archetype_entity = entities.get_unchecked(archetype_index);
|
||||
if !F::filter_fetch(
|
||||
&mut filter,
|
||||
archetype_entity.entity,
|
||||
archetype_entity.table_row,
|
||||
archetype_entity.entity(),
|
||||
archetype_entity.table_row(),
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
func(Q::fetch(
|
||||
&mut fetch,
|
||||
archetype_entity.entity,
|
||||
archetype_entity.table_row,
|
||||
archetype_entity.entity(),
|
||||
archetype_entity.table_row(),
|
||||
));
|
||||
}
|
||||
};
|
||||
|
|
|
@ -70,7 +70,7 @@ impl Default for World {
|
|||
id: WorldId::new().expect("More `bevy` `World`s have been created than is supported"),
|
||||
entities: Default::default(),
|
||||
components: Default::default(),
|
||||
archetypes: Default::default(),
|
||||
archetypes: Archetypes::new(),
|
||||
storages: Default::default(),
|
||||
bundles: Default::default(),
|
||||
removed_components: Default::default(),
|
||||
|
@ -327,7 +327,7 @@ impl World {
|
|||
self.archetypes
|
||||
.iter()
|
||||
.flat_map(|archetype| archetype.entities().iter())
|
||||
.map(|archetype_entity| archetype_entity.entity)
|
||||
.map(|archetype_entity| archetype_entity.entity())
|
||||
}
|
||||
|
||||
/// Retrieves an [`EntityMut`] that exposes read and write operations for the given `entity`.
|
||||
|
|
Loading…
Reference in a new issue