Skip to content
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

[Merged by Bors] - Newtype ArchetypeRow and TableRow #4878

Closed
wants to merge 32 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
65d8b1b
Change archetype rows to u32
james7132 May 31, 2022
211edb4
Fix CI
james7132 May 31, 2022
9a593c9
Fix miri test
james7132 May 31, 2022
70e4da3
Merge branch 'main' into archetype-row-u32
james7132 Nov 2, 2022
798a38a
Fix build
james7132 Nov 2, 2022
579bbe8
Merge branch 'main' into archetype-row-u32
james7132 Nov 4, 2022
507b4d6
Merge branch 'main' into archetype-row-u32
james7132 Nov 14, 2022
3dfddd0
Merge branch 'main' into archetype-row-u32
james7132 Nov 16, 2022
e534e8e
Merge branch 'main' into archetype-row-u32
james7132 Nov 27, 2022
69f5fa1
Fix CI
james7132 Nov 27, 2022
7c80354
Newtype TableRows
james7132 Nov 27, 2022
eb5992d
Formatting
james7132 Nov 27, 2022
e350658
Fix CI... again
james7132 Nov 27, 2022
c82c553
Reset TableRow to usize
james7132 Nov 30, 2022
c6ece74
Merge branch 'main' into archetype-row-u32
james7132 Nov 30, 2022
2bd6328
Newtype ArchetypeIndex
james7132 Nov 30, 2022
e8225c8
Force use of TableRow in WorldQuery
james7132 Nov 30, 2022
617a5ca
ArchetypeIndex -> ArchetypeRow
james7132 Dec 2, 2022
e539dd3
index -> archetype_row
james7132 Dec 2, 2022
9e1778a
Make them pub and fix component initialization
james7132 Dec 2, 2022
2d4b235
Docs
james7132 Dec 2, 2022
0367fa1
Formatting
james7132 Dec 2, 2022
4612526
currrent_index -> current_row
james7132 Dec 2, 2022
b8f011d
Fix docs for CI
james7132 Dec 2, 2022
ad40659
Revert internals of ComponentSparseSet to use u32
james7132 Dec 4, 2022
028cebf
Cause less churn
james7132 Dec 4, 2022
23a36ab
Less churn
james7132 Dec 4, 2022
f3fec82
Fix CI
james7132 Dec 5, 2022
bd0d620
Merge branch 'main' into archetype-row-u32
james7132 Dec 5, 2022
38c3964
Resolve issues with iter_entities
james7132 Dec 6, 2022
e61162f
Merge branch 'main' into archetype-row-u32
james7132 Dec 6, 2022
f8b088e
Add ArchetypeRow::index
james7132 Dec 6, 2022
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
4 changes: 2 additions & 2 deletions crates/bevy_ecs/macros/src/fetch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ pub fn derive_world_query_impl(ast: DeriveInput) -> TokenStream {
unsafe fn fetch<'__w>(
_fetch: &mut <Self as #path::query::WorldQuery>::Fetch<'__w>,
_entity: #path::entity::Entity,
_table_row: usize
_table_row: #path::storage::TableRow,
) -> <Self as #path::query::WorldQuery>::Item<'__w> {
Self::Item {
#(#field_idents: <#field_types>::fetch(&mut _fetch.#field_idents, _entity, _table_row),)*
Expand All @@ -296,7 +296,7 @@ pub fn derive_world_query_impl(ast: DeriveInput) -> TokenStream {
unsafe fn filter_fetch<'__w>(
_fetch: &mut <Self as #path::query::WorldQuery>::Fetch<'__w>,
_entity: #path::entity::Entity,
_table_row: usize
_table_row: #path::storage::TableRow,
) -> bool {
true #(&& <#field_types>::filter_fetch(&mut _fetch.#field_idents, _entity, _table_row))*
}
Expand Down
63 changes: 47 additions & 16 deletions crates/bevy_ecs/src/archetype.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,41 @@ use crate::{
bundle::BundleId,
component::{ComponentId, StorageType},
entity::{Entity, EntityLocation},
storage::{ImmutableSparseSet, SparseArray, SparseSet, SparseSetIndex, TableId},
storage::{ImmutableSparseSet, SparseArray, SparseSet, SparseSetIndex, TableId, TableRow},
};
use std::{
collections::HashMap,
hash::Hash,
ops::{Index, IndexMut},
};

/// An opaque location within a [`Archetype`].
///
/// This can be used in conjunction with [`ArchetypeId`] to find the exact location
/// of an [`Entity`] within a [`World`]. An entity's archetype and index can be
/// retrieved via [`Entities::get`].
///
/// [`World`]: crate::world::World
/// [`Entities::get`]: crate::entity::Entities
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
#[repr(transparent)]
pub struct ArchetypeRow(usize);

impl ArchetypeRow {
pub const INVALID: ArchetypeRow = ArchetypeRow(usize::MAX);

/// Creates a `ArchetypeRow`.
pub const fn new(index: usize) -> Self {
Self(index)
}

/// Gets the index of the row.
#[inline]
pub const fn index(self) -> usize {
self.0
}
}

/// 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.
Expand Down Expand Up @@ -226,7 +253,7 @@ impl Edges {
/// Metadata about an [`Entity`] in a [`Archetype`].
pub struct ArchetypeEntity {
entity: Entity,
table_row: usize,
table_row: TableRow,
}

impl ArchetypeEntity {
Expand All @@ -240,14 +267,14 @@ impl ArchetypeEntity {
///
/// [`Table`]: crate::storage::Table
#[inline]
pub const fn table_row(&self) -> usize {
pub const fn table_row(&self) -> TableRow {
self.table_row
}
}

pub(crate) struct ArchetypeSwapRemoveResult {
pub(crate) swapped_entity: Option<Entity>,
pub(crate) table_row: usize,
pub(crate) table_row: TableRow,
}

/// Internal metadata for a [`Component`] within a given [`Archetype`].
Expand Down Expand Up @@ -380,18 +407,18 @@ impl Archetype {
/// 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
/// An entity's archetype index can be fetched from [`EntityLocation::archetype_row`], 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
/// [`EntityLocation`]: crate::entity::EntityLocation::archetype_row
/// [`Entities::get`]: crate::entity::Entities::get
#[inline]
pub fn entity_table_row(&self, index: usize) -> usize {
self.entities[index].table_row
pub fn entity_table_row(&self, index: ArchetypeRow) -> TableRow {
self.entities[index.0].table_row
}

/// Updates if the components for the entity at `index` can be found
Expand All @@ -400,21 +427,25 @@ impl Archetype {
/// # 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;
pub(crate) fn set_entity_table_row(&mut self, index: ArchetypeRow, table_row: TableRow) {
self.entities[index.0].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
pub(crate) unsafe fn allocate(&mut self, entity: Entity, table_row: usize) -> EntityLocation {
pub(crate) unsafe fn allocate(
&mut self,
entity: Entity,
table_row: TableRow,
) -> EntityLocation {
self.entities.push(ArchetypeEntity { entity, table_row });

EntityLocation {
archetype_id: self.id,
index: self.entities.len() - 1,
archetype_row: ArchetypeRow(self.entities.len() - 1),
}
}

Expand All @@ -427,14 +458,14 @@ impl Archetype {
///
/// # 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);
pub(crate) fn swap_remove(&mut self, index: ArchetypeRow) -> ArchetypeSwapRemoveResult {
let is_last = index.0 == self.entities.len() - 1;
let entity = self.entities.swap_remove(index.0);
ArchetypeSwapRemoveResult {
swapped_entity: if is_last {
None
} else {
Some(self.entities[index].entity)
Some(self.entities[index.0].entity)
},
table_row: entity.table_row,
}
Expand Down
20 changes: 10 additions & 10 deletions crates/bevy_ecs/src/bundle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ pub use bevy_ecs_macros::Bundle;

use crate::{
archetype::{
Archetype, ArchetypeId, Archetypes, BundleComponentStatus, ComponentStatus,
Archetype, ArchetypeId, ArchetypeRow, Archetypes, BundleComponentStatus, ComponentStatus,
SpawnBundleStatus,
},
component::{Component, ComponentId, Components, StorageType, Tick},
entity::{Entities, Entity, EntityLocation},
storage::{SparseSetIndex, SparseSets, Storages, Table},
storage::{SparseSetIndex, SparseSets, Storages, Table, TableRow},
};
use bevy_ecs_macros::all_tuples;
use bevy_ptr::OwningPtr;
Expand Down Expand Up @@ -379,7 +379,7 @@ impl BundleInfo {
sparse_sets: &mut SparseSets,
bundle_component_status: &S,
entity: Entity,
table_row: usize,
table_row: TableRow,
change_tick: u32,
bundle: T,
) {
Expand Down Expand Up @@ -518,17 +518,17 @@ pub(crate) enum InsertBundleResult<'a> {

impl<'a, 'b> BundleInserter<'a, 'b> {
/// # Safety
/// `entity` must currently exist in the source archetype for this inserter. `archetype_index`
/// `entity` must currently exist in the source archetype for this inserter. `archetype_row`
/// must be `entity`'s location in the archetype. `T` must match this [`BundleInfo`]'s type
#[inline]
pub unsafe fn insert<T: Bundle>(
&mut self,
entity: Entity,
archetype_index: usize,
archetype_row: ArchetypeRow,
bundle: T,
) -> EntityLocation {
let location = EntityLocation {
index: archetype_index,
archetype_row,
archetype_id: self.archetype.id(),
};
match &mut self.result {
Expand All @@ -544,14 +544,14 @@ impl<'a, 'b> BundleInserter<'a, 'b> {
self.sparse_sets,
add_bundle,
entity,
self.archetype.entity_table_row(archetype_index),
self.archetype.entity_table_row(archetype_row),
self.change_tick,
bundle,
);
location
}
InsertBundleResult::NewArchetypeSameTable { new_archetype } => {
let result = self.archetype.swap_remove(location.index);
let result = self.archetype.swap_remove(location.archetype_row);
if let Some(swapped_entity) = result.swapped_entity {
self.entities.set(swapped_entity.index(), location);
}
Expand Down Expand Up @@ -579,7 +579,7 @@ impl<'a, 'b> BundleInserter<'a, 'b> {
new_archetype,
new_table,
} => {
let result = self.archetype.swap_remove(location.index);
let result = self.archetype.swap_remove(location.archetype_row);
if let Some(swapped_entity) = result.swapped_entity {
self.entities.set(swapped_entity.index(), location);
}
Expand Down Expand Up @@ -607,7 +607,7 @@ impl<'a, 'b> BundleInserter<'a, 'b> {
};

swapped_archetype
.set_entity_table_row(swapped_location.index, result.table_row);
.set_entity_table_row(swapped_location.archetype_row, result.table_row);
}

// PERF: this could be looked up during Inserter construction and stored (but borrowing makes this nasty)
Expand Down
9 changes: 6 additions & 3 deletions crates/bevy_ecs/src/entity/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@ mod map_entities;

pub use map_entities::*;

use crate::{archetype::ArchetypeId, storage::SparseSetIndex};
use crate::{
archetype::{ArchetypeId, ArchetypeRow},
storage::SparseSetIndex,
};
use serde::{Deserialize, Serialize};
use std::{convert::TryFrom, fmt, mem, sync::atomic::Ordering};

Expand Down Expand Up @@ -727,7 +730,7 @@ impl EntityMeta {
generation: 0,
location: EntityLocation {
archetype_id: ArchetypeId::INVALID,
index: usize::MAX, // dummy value, to be filled in
archetype_row: ArchetypeRow::INVALID, // dummy value, to be filled in
},
};
}
Expand All @@ -740,7 +743,7 @@ pub struct EntityLocation {
pub archetype_id: ArchetypeId,

/// The index of the entity in the archetype
pub index: usize,
pub archetype_row: ArchetypeRow,
}

#[cfg(test)]
Expand Down
Loading