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

Remove ComponentStorage and associated types #12311

Merged
merged 3 commits into from
Mar 5, 2024
Merged
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
10 changes: 5 additions & 5 deletions crates/bevy_ecs/macros/src/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ pub fn derive_component(input: TokenStream) -> TokenStream {

TokenStream::from(quote! {
impl #impl_generics #bevy_ecs_path::component::Component for #struct_name #type_generics #where_clause {
type Storage = #storage;
const STORAGE_TYPE: #bevy_ecs_path::component::StorageType = #storage;
}
})
}
Expand Down Expand Up @@ -110,10 +110,10 @@ fn parse_component_attr(ast: &DeriveInput) -> Result<Attrs> {
}

fn storage_path(bevy_ecs_path: &Path, ty: StorageTy) -> TokenStream2 {
let typename = match ty {
StorageTy::Table => Ident::new("TableStorage", Span::call_site()),
StorageTy::SparseSet => Ident::new("SparseStorage", Span::call_site()),
let storage_type = match ty {
StorageTy::Table => Ident::new("Table", Span::call_site()),
StorageTy::SparseSet => Ident::new("SparseSet", Span::call_site()),
};

quote! { #bevy_ecs_path::component::#typename }
quote! { #bevy_ecs_path::component::StorageType::#storage_type }
}
4 changes: 2 additions & 2 deletions crates/bevy_ecs/src/bundle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use crate::{
AddBundle, Archetype, ArchetypeId, Archetypes, BundleComponentStatus, ComponentStatus,
SpawnBundleStatus,
},
component::{Component, ComponentId, ComponentStorage, Components, StorageType, Tick},
component::{Component, ComponentId, Components, StorageType, Tick},
entity::{Entities, Entity, EntityLocation},
prelude::World,
query::DebugCheckedUnwrap,
Expand Down Expand Up @@ -203,7 +203,7 @@ unsafe impl<C: Component> Bundle for C {
impl<C: Component> DynamicBundle for C {
#[inline]
fn get_components(self, func: &mut impl FnMut(StorageType, OwningPtr<'_>)) {
OwningPtr::make(self, |ptr| func(C::Storage::STORAGE_TYPE, ptr));
OwningPtr::make(self, |ptr| func(C::STORAGE_TYPE, ptr));
}
}

Expand Down
37 changes: 4 additions & 33 deletions crates/bevy_ecs/src/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,42 +151,13 @@ 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;
/// A constant indicating the storage type used for this component.
const STORAGE_TYPE: StorageType;

/// Called when registering this component, allowing mutable access to it's [`ComponentHooks`].
fn register_component_hooks(_hooks: &mut ComponentHooks) {}
}

/// 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 {
/// A value indicating the storage strategy specified by this type.
const STORAGE_TYPE: StorageType;
}

impl ComponentStorage for TableStorage {
const STORAGE_TYPE: StorageType = StorageType::Table;
}
impl ComponentStorage for SparseStorage {
const STORAGE_TYPE: StorageType = StorageType::SparseSet;
}

mod sealed {
pub trait Sealed {}
impl Sealed for super::TableStorage {}
impl Sealed for super::SparseStorage {}
}

/// The storage used for a specific component type.
///
/// # Examples
Expand Down Expand Up @@ -471,7 +442,7 @@ impl ComponentDescriptor {
pub fn new<T: Component>() -> Self {
Self {
name: Cow::Borrowed(std::any::type_name::<T>()),
storage_type: T::Storage::STORAGE_TYPE,
storage_type: T::STORAGE_TYPE,
is_send_and_sync: true,
type_id: Some(TypeId::of::<T>()),
layout: Layout::new::<T>(),
Expand Down Expand Up @@ -502,7 +473,7 @@ impl ComponentDescriptor {

/// Create a new `ComponentDescriptor` for a resource.
///
/// The [`StorageType`] for resources is always [`TableStorage`].
/// The [`StorageType`] for resources is always [`StorageType::Table`].
pub fn new_resource<T: Resource>() -> Self {
Self {
name: Cow::Borrowed(std::any::type_name::<T>()),
Expand Down
34 changes: 17 additions & 17 deletions crates/bevy_ecs/src/query/fetch.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::{
archetype::Archetype,
change_detection::{Ticks, TicksMut},
component::{Component, ComponentId, ComponentStorage, StorageType, Tick},
component::{Component, ComponentId, StorageType, Tick},
entity::Entity,
query::{Access, DebugCheckedUnwrap, FilteredAccess, WorldQuery},
storage::{ComponentSparseSet, Table, TableRow},
Expand Down Expand Up @@ -711,9 +711,9 @@ unsafe impl<'a> QueryData for FilteredEntityMut<'a> {

#[doc(hidden)]
pub struct ReadFetch<'w, T> {
// T::Storage = TableStorage
// T::STORAGE_TYPE = StorageType::Table
table_components: Option<ThinSlicePtr<'w, UnsafeCell<T>>>,
// T::Storage = SparseStorage
// T::STORAGE_TYPE = StorageType::SparseSet
sparse_set: Option<&'w ComponentSparseSet>,
}

Expand Down Expand Up @@ -747,7 +747,7 @@ unsafe impl<T: Component> WorldQuery for &T {
) -> ReadFetch<'w, T> {
ReadFetch {
table_components: None,
sparse_set: (T::Storage::STORAGE_TYPE == StorageType::SparseSet).then(|| {
sparse_set: (T::STORAGE_TYPE == StorageType::SparseSet).then(|| {
// SAFETY: The underlying type associated with `component_id` is `T`,
// which we are allowed to access since we registered it in `update_archetype_component_access`.
// Note that we do not actually access any components in this function, we just get a shared
Expand All @@ -764,7 +764,7 @@ unsafe impl<T: Component> WorldQuery for &T {
}

const IS_DENSE: bool = {
match T::Storage::STORAGE_TYPE {
match T::STORAGE_TYPE {
StorageType::Table => true,
StorageType::SparseSet => false,
}
Expand Down Expand Up @@ -806,7 +806,7 @@ unsafe impl<T: Component> WorldQuery for &T {
entity: Entity,
table_row: TableRow,
) -> Self::Item<'w> {
match T::Storage::STORAGE_TYPE {
match T::STORAGE_TYPE {
StorageType::Table => {
// SAFETY: STORAGE_TYPE = Table
let table = unsafe { fetch.table_components.debug_checked_unwrap() };
Expand Down Expand Up @@ -862,13 +862,13 @@ unsafe impl<T: Component> ReadOnlyQueryData for &T {}

#[doc(hidden)]
pub struct RefFetch<'w, T> {
// T::Storage = TableStorage
// T::STORAGE_TYPE = StorageType::Table
table_data: Option<(
ThinSlicePtr<'w, UnsafeCell<T>>,
ThinSlicePtr<'w, UnsafeCell<Tick>>,
ThinSlicePtr<'w, UnsafeCell<Tick>>,
)>,
// T::Storage = SparseStorage
// T::STORAGE_TYPE = StorageType::SparseSet
sparse_set: Option<&'w ComponentSparseSet>,

last_run: Tick,
Expand Down Expand Up @@ -905,7 +905,7 @@ unsafe impl<'__w, T: Component> WorldQuery for Ref<'__w, T> {
) -> RefFetch<'w, T> {
RefFetch {
table_data: None,
sparse_set: (T::Storage::STORAGE_TYPE == StorageType::SparseSet).then(|| {
sparse_set: (T::STORAGE_TYPE == StorageType::SparseSet).then(|| {
// SAFETY: The underlying type associated with `component_id` is `T`,
// which we are allowed to access since we registered it in `update_archetype_component_access`.
// Note that we do not actually access any components in this function, we just get a shared
Expand All @@ -924,7 +924,7 @@ unsafe impl<'__w, T: Component> WorldQuery for Ref<'__w, T> {
}

const IS_DENSE: bool = {
match T::Storage::STORAGE_TYPE {
match T::STORAGE_TYPE {
StorageType::Table => true,
StorageType::SparseSet => false,
}
Expand Down Expand Up @@ -965,7 +965,7 @@ unsafe impl<'__w, T: Component> WorldQuery for Ref<'__w, T> {
entity: Entity,
table_row: TableRow,
) -> Self::Item<'w> {
match T::Storage::STORAGE_TYPE {
match T::STORAGE_TYPE {
StorageType::Table => {
// SAFETY: STORAGE_TYPE = Table
let (table_components, added_ticks, changed_ticks) =
Expand Down Expand Up @@ -1045,13 +1045,13 @@ unsafe impl<'__w, T: Component> ReadOnlyQueryData for Ref<'__w, T> {}

#[doc(hidden)]
pub struct WriteFetch<'w, T> {
// T::Storage = TableStorage
// T::STORAGE_TYPE = StorageType::Table
table_data: Option<(
ThinSlicePtr<'w, UnsafeCell<T>>,
ThinSlicePtr<'w, UnsafeCell<Tick>>,
ThinSlicePtr<'w, UnsafeCell<Tick>>,
)>,
// T::Storage = SparseStorage
// T::STORAGE_TYPE = StorageType::SparseSet
sparse_set: Option<&'w ComponentSparseSet>,

last_run: Tick,
Expand Down Expand Up @@ -1088,7 +1088,7 @@ unsafe impl<'__w, T: Component> WorldQuery for &'__w mut T {
) -> WriteFetch<'w, T> {
WriteFetch {
table_data: None,
sparse_set: (T::Storage::STORAGE_TYPE == StorageType::SparseSet).then(|| {
sparse_set: (T::STORAGE_TYPE == StorageType::SparseSet).then(|| {
// SAFETY: The underlying type associated with `component_id` is `T`,
// which we are allowed to access since we registered it in `update_archetype_component_access`.
// Note that we do not actually access any components in this function, we just get a shared
Expand All @@ -1107,7 +1107,7 @@ unsafe impl<'__w, T: Component> WorldQuery for &'__w mut T {
}

const IS_DENSE: bool = {
match T::Storage::STORAGE_TYPE {
match T::STORAGE_TYPE {
StorageType::Table => true,
StorageType::SparseSet => false,
}
Expand Down Expand Up @@ -1148,7 +1148,7 @@ unsafe impl<'__w, T: Component> WorldQuery for &'__w mut T {
entity: Entity,
table_row: TableRow,
) -> Self::Item<'w> {
match T::Storage::STORAGE_TYPE {
match T::STORAGE_TYPE {
StorageType::Table => {
// SAFETY: STORAGE_TYPE = Table
let (table_components, added_ticks, changed_ticks) =
Expand Down Expand Up @@ -1433,7 +1433,7 @@ unsafe impl<T: Component> WorldQuery for Has<T> {
}

const IS_DENSE: bool = {
match T::Storage::STORAGE_TYPE {
match T::STORAGE_TYPE {
StorageType::Table => true,
StorageType::SparseSet => false,
}
Expand Down
18 changes: 9 additions & 9 deletions crates/bevy_ecs/src/query/filter.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::{
archetype::Archetype,
component::{Component, ComponentId, ComponentStorage, StorageType, Tick},
component::{Component, ComponentId, StorageType, Tick},
entity::Entity,
query::{DebugCheckedUnwrap, FilteredAccess, WorldQuery},
storage::{Column, ComponentSparseSet, Table, TableRow},
Expand Down Expand Up @@ -142,7 +142,7 @@ unsafe impl<T: Component> WorldQuery for With<T> {
}

const IS_DENSE: bool = {
match T::Storage::STORAGE_TYPE {
match T::STORAGE_TYPE {
StorageType::Table => true,
StorageType::SparseSet => false,
}
Expand Down Expand Up @@ -250,7 +250,7 @@ unsafe impl<T: Component> WorldQuery for Without<T> {
}

const IS_DENSE: bool = {
match T::Storage::STORAGE_TYPE {
match T::STORAGE_TYPE {
StorageType::Table => true,
StorageType::SparseSet => false,
}
Expand Down Expand Up @@ -604,15 +604,15 @@ unsafe impl<T: Component> WorldQuery for Added<T> {
) -> Self::Fetch<'w> {
Self::Fetch::<'w> {
table_ticks: None,
sparse_set: (T::Storage::STORAGE_TYPE == StorageType::SparseSet)
sparse_set: (T::STORAGE_TYPE == StorageType::SparseSet)
.then(|| world.storages().sparse_sets.get(id).debug_checked_unwrap()),
last_run,
this_run,
}
}

const IS_DENSE: bool = {
match T::Storage::STORAGE_TYPE {
match T::STORAGE_TYPE {
StorageType::Table => true,
StorageType::SparseSet => false,
}
Expand Down Expand Up @@ -651,7 +651,7 @@ unsafe impl<T: Component> WorldQuery for Added<T> {
entity: Entity,
table_row: TableRow,
) -> Self::Item<'w> {
match T::Storage::STORAGE_TYPE {
match T::STORAGE_TYPE {
StorageType::Table => {
// SAFETY: STORAGE_TYPE = Table
let table = unsafe { fetch.table_ticks.debug_checked_unwrap() };
Expand Down Expand Up @@ -813,15 +813,15 @@ unsafe impl<T: Component> WorldQuery for Changed<T> {
) -> Self::Fetch<'w> {
Self::Fetch::<'w> {
table_ticks: None,
sparse_set: (T::Storage::STORAGE_TYPE == StorageType::SparseSet)
sparse_set: (T::STORAGE_TYPE == StorageType::SparseSet)
.then(|| world.storages().sparse_sets.get(id).debug_checked_unwrap()),
last_run,
this_run,
}
}

const IS_DENSE: bool = {
match T::Storage::STORAGE_TYPE {
match T::STORAGE_TYPE {
StorageType::Table => true,
StorageType::SparseSet => false,
}
Expand Down Expand Up @@ -860,7 +860,7 @@ unsafe impl<T: Component> WorldQuery for Changed<T> {
entity: Entity,
table_row: TableRow,
) -> Self::Item<'w> {
match T::Storage::STORAGE_TYPE {
match T::STORAGE_TYPE {
StorageType::Table => {
// SAFETY: STORAGE_TYPE = Table
let table = unsafe { fetch.table_ticks.debug_checked_unwrap() };
Expand Down
12 changes: 5 additions & 7 deletions crates/bevy_ecs/src/world/unsafe_world_cell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@ use crate::{
archetype::{Archetype, ArchetypeComponentId, Archetypes},
bundle::Bundles,
change_detection::{MutUntyped, Ticks, TicksMut},
component::{
ComponentId, ComponentStorage, ComponentTicks, Components, StorageType, Tick, TickCells,
},
component::{ComponentId, ComponentTicks, Components, StorageType, Tick, TickCells},
entity::{Entities, Entity, EntityLocation},
prelude::Component,
removal_detection::RemovedComponentEvents,
Expand Down Expand Up @@ -713,7 +711,7 @@ impl<'w> UnsafeEntityCell<'w> {
get_component(
self.world,
component_id,
T::Storage::STORAGE_TYPE,
T::STORAGE_TYPE,
self.entity,
self.location,
)
Expand All @@ -740,7 +738,7 @@ impl<'w> UnsafeEntityCell<'w> {
get_component_and_ticks(
self.world,
component_id,
T::Storage::STORAGE_TYPE,
T::STORAGE_TYPE,
self.entity,
self.location,
)
Expand Down Expand Up @@ -770,7 +768,7 @@ impl<'w> UnsafeEntityCell<'w> {
get_ticks(
self.world,
component_id,
T::Storage::STORAGE_TYPE,
T::STORAGE_TYPE,
self.entity,
self.location,
)
Expand Down Expand Up @@ -839,7 +837,7 @@ impl<'w> UnsafeEntityCell<'w> {
get_component_and_ticks(
self.world,
component_id,
T::Storage::STORAGE_TYPE,
T::STORAGE_TYPE,
self.entity,
self.location,
)
Expand Down
4 changes: 2 additions & 2 deletions examples/ecs/component_hooks.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
//! This examples illustrates the different ways you can employ component lifecycle hooks

use bevy::ecs::component::{ComponentHooks, TableStorage};
use bevy::ecs::component::{ComponentHooks, StorageType};
use bevy::prelude::*;
use std::collections::HashMap;

#[derive(Debug)]
struct MyComponent(KeyCode);

impl Component for MyComponent {
type Storage = TableStorage;
const STORAGE_TYPE: StorageType = StorageType::Table;

/// Hooks can also be registered during component initialisation by
/// implementing `register_component_hooks`
Expand Down