Remove ComponentStorage and associated types (#12311)
# Objective When doing a final pass for #3362, it appeared that `ComponentStorage` as a trait, the two types implementing it, and the associated type on `Component` aren't really necessary anymore. This likely was due to an earlier constraint on the use of consts in traits, but that definitely doesn't seem to be a problem in Rust 1.76. ## Solution Remove them. --- ## Changelog Changed: `Component::Storage` has been replaced with `Component::STORAGE_TYPE` as a const. Removed: `bevy::ecs::component::ComponentStorage` trait Removed: `bevy::ecs::component::TableStorage` struct Removed: `bevy::ecs::component::SparseSetStorage` struct ## Migration Guide If you were manually implementing `Component` instead of using the derive macro, replace the associated `Storage` associated type with the `STORAGE_TYPE` const: ```rust // in Bevy 0.13 impl Component for MyComponent { type Storage = TableStorage; } // in Bevy 0.14 impl Component for MyComponent { const STORAGE_TYPE: StorageType = StorageType::Table; } ``` Component is no longer object safe. If you were relying on `&dyn Component`, `Box<dyn Component>`, etc. please [file an issue ](https://github.com/bevyengine/bevy/issues) to get [this change](https://github.com/bevyengine/bevy/pull/12311) reverted. --------- Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
This commit is contained in:
parent
70b70cd323
commit
dc40cd134f
@ -60,7 +60,7 @@ pub fn derive_component(input: TokenStream) -> TokenStream {
|
|||||||
|
|
||||||
TokenStream::from(quote! {
|
TokenStream::from(quote! {
|
||||||
impl #impl_generics #bevy_ecs_path::component::Component for #struct_name #type_generics #where_clause {
|
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;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -110,10 +110,10 @@ fn parse_component_attr(ast: &DeriveInput) -> Result<Attrs> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn storage_path(bevy_ecs_path: &Path, ty: StorageTy) -> TokenStream2 {
|
fn storage_path(bevy_ecs_path: &Path, ty: StorageTy) -> TokenStream2 {
|
||||||
let typename = match ty {
|
let storage_type = match ty {
|
||||||
StorageTy::Table => Ident::new("TableStorage", Span::call_site()),
|
StorageTy::Table => Ident::new("Table", Span::call_site()),
|
||||||
StorageTy::SparseSet => Ident::new("SparseStorage", 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 }
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ use crate::{
|
|||||||
AddBundle, Archetype, ArchetypeId, Archetypes, BundleComponentStatus, ComponentStatus,
|
AddBundle, Archetype, ArchetypeId, Archetypes, BundleComponentStatus, ComponentStatus,
|
||||||
SpawnBundleStatus,
|
SpawnBundleStatus,
|
||||||
},
|
},
|
||||||
component::{Component, ComponentId, ComponentStorage, Components, StorageType, Tick},
|
component::{Component, ComponentId, Components, StorageType, Tick},
|
||||||
entity::{Entities, Entity, EntityLocation},
|
entity::{Entities, Entity, EntityLocation},
|
||||||
prelude::World,
|
prelude::World,
|
||||||
query::DebugCheckedUnwrap,
|
query::DebugCheckedUnwrap,
|
||||||
@ -203,7 +203,7 @@ unsafe impl<C: Component> Bundle for C {
|
|||||||
impl<C: Component> DynamicBundle for C {
|
impl<C: Component> DynamicBundle for C {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get_components(self, func: &mut impl FnMut(StorageType, OwningPtr<'_>)) {
|
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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,42 +151,13 @@ use std::{
|
|||||||
/// [`SyncCell`]: bevy_utils::synccell::SyncCell
|
/// [`SyncCell`]: bevy_utils::synccell::SyncCell
|
||||||
/// [`Exclusive`]: https://doc.rust-lang.org/nightly/std/sync/struct.Exclusive.html
|
/// [`Exclusive`]: https://doc.rust-lang.org/nightly/std/sync/struct.Exclusive.html
|
||||||
pub trait Component: Send + Sync + 'static {
|
pub trait Component: Send + Sync + 'static {
|
||||||
/// A marker type indicating the storage type used for this component.
|
/// A constant indicating the storage type used for this component.
|
||||||
/// This must be either [`TableStorage`] or [`SparseStorage`].
|
const STORAGE_TYPE: StorageType;
|
||||||
type Storage: ComponentStorage;
|
|
||||||
|
|
||||||
/// Called when registering this component, allowing mutable access to it's [`ComponentHooks`].
|
/// Called when registering this component, allowing mutable access to it's [`ComponentHooks`].
|
||||||
fn register_component_hooks(_hooks: &mut 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.
|
/// The storage used for a specific component type.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
@ -472,7 +443,7 @@ impl ComponentDescriptor {
|
|||||||
pub fn new<T: Component>() -> Self {
|
pub fn new<T: Component>() -> Self {
|
||||||
Self {
|
Self {
|
||||||
name: Cow::Borrowed(std::any::type_name::<T>()),
|
name: Cow::Borrowed(std::any::type_name::<T>()),
|
||||||
storage_type: T::Storage::STORAGE_TYPE,
|
storage_type: T::STORAGE_TYPE,
|
||||||
is_send_and_sync: true,
|
is_send_and_sync: true,
|
||||||
type_id: Some(TypeId::of::<T>()),
|
type_id: Some(TypeId::of::<T>()),
|
||||||
layout: Layout::new::<T>(),
|
layout: Layout::new::<T>(),
|
||||||
@ -503,7 +474,7 @@ impl ComponentDescriptor {
|
|||||||
|
|
||||||
/// Create a new `ComponentDescriptor` for a resource.
|
/// 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 {
|
pub fn new_resource<T: Resource>() -> Self {
|
||||||
Self {
|
Self {
|
||||||
name: Cow::Borrowed(std::any::type_name::<T>()),
|
name: Cow::Borrowed(std::any::type_name::<T>()),
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
archetype::Archetype,
|
archetype::Archetype,
|
||||||
change_detection::{Ticks, TicksMut},
|
change_detection::{Ticks, TicksMut},
|
||||||
component::{Component, ComponentId, ComponentStorage, StorageType, Tick},
|
component::{Component, ComponentId, StorageType, Tick},
|
||||||
entity::Entity,
|
entity::Entity,
|
||||||
query::{Access, DebugCheckedUnwrap, FilteredAccess, WorldQuery},
|
query::{Access, DebugCheckedUnwrap, FilteredAccess, WorldQuery},
|
||||||
storage::{ComponentSparseSet, Table, TableRow},
|
storage::{ComponentSparseSet, Table, TableRow},
|
||||||
@ -711,9 +711,9 @@ unsafe impl<'a> QueryData for FilteredEntityMut<'a> {
|
|||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub struct ReadFetch<'w, T> {
|
pub struct ReadFetch<'w, T> {
|
||||||
// T::Storage = TableStorage
|
// T::STORAGE_TYPE = StorageType::Table
|
||||||
table_components: Option<ThinSlicePtr<'w, UnsafeCell<T>>>,
|
table_components: Option<ThinSlicePtr<'w, UnsafeCell<T>>>,
|
||||||
// T::Storage = SparseStorage
|
// T::STORAGE_TYPE = StorageType::SparseSet
|
||||||
sparse_set: Option<&'w ComponentSparseSet>,
|
sparse_set: Option<&'w ComponentSparseSet>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -747,7 +747,7 @@ unsafe impl<T: Component> WorldQuery for &T {
|
|||||||
) -> ReadFetch<'w, T> {
|
) -> ReadFetch<'w, T> {
|
||||||
ReadFetch {
|
ReadFetch {
|
||||||
table_components: None,
|
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`,
|
// 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`.
|
// 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
|
// Note that we do not actually access any components in this function, we just get a shared
|
||||||
@ -764,7 +764,7 @@ unsafe impl<T: Component> WorldQuery for &T {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const IS_DENSE: bool = {
|
const IS_DENSE: bool = {
|
||||||
match T::Storage::STORAGE_TYPE {
|
match T::STORAGE_TYPE {
|
||||||
StorageType::Table => true,
|
StorageType::Table => true,
|
||||||
StorageType::SparseSet => false,
|
StorageType::SparseSet => false,
|
||||||
}
|
}
|
||||||
@ -806,7 +806,7 @@ unsafe impl<T: Component> WorldQuery for &T {
|
|||||||
entity: Entity,
|
entity: Entity,
|
||||||
table_row: TableRow,
|
table_row: TableRow,
|
||||||
) -> Self::Item<'w> {
|
) -> Self::Item<'w> {
|
||||||
match T::Storage::STORAGE_TYPE {
|
match T::STORAGE_TYPE {
|
||||||
StorageType::Table => {
|
StorageType::Table => {
|
||||||
// SAFETY: STORAGE_TYPE = Table
|
// SAFETY: STORAGE_TYPE = Table
|
||||||
let table = unsafe { fetch.table_components.debug_checked_unwrap() };
|
let table = unsafe { fetch.table_components.debug_checked_unwrap() };
|
||||||
@ -862,13 +862,13 @@ unsafe impl<T: Component> ReadOnlyQueryData for &T {}
|
|||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub struct RefFetch<'w, T> {
|
pub struct RefFetch<'w, T> {
|
||||||
// T::Storage = TableStorage
|
// T::STORAGE_TYPE = StorageType::Table
|
||||||
table_data: Option<(
|
table_data: Option<(
|
||||||
ThinSlicePtr<'w, UnsafeCell<T>>,
|
ThinSlicePtr<'w, UnsafeCell<T>>,
|
||||||
ThinSlicePtr<'w, UnsafeCell<Tick>>,
|
ThinSlicePtr<'w, UnsafeCell<Tick>>,
|
||||||
ThinSlicePtr<'w, UnsafeCell<Tick>>,
|
ThinSlicePtr<'w, UnsafeCell<Tick>>,
|
||||||
)>,
|
)>,
|
||||||
// T::Storage = SparseStorage
|
// T::STORAGE_TYPE = StorageType::SparseSet
|
||||||
sparse_set: Option<&'w ComponentSparseSet>,
|
sparse_set: Option<&'w ComponentSparseSet>,
|
||||||
|
|
||||||
last_run: Tick,
|
last_run: Tick,
|
||||||
@ -905,7 +905,7 @@ unsafe impl<'__w, T: Component> WorldQuery for Ref<'__w, T> {
|
|||||||
) -> RefFetch<'w, T> {
|
) -> RefFetch<'w, T> {
|
||||||
RefFetch {
|
RefFetch {
|
||||||
table_data: None,
|
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`,
|
// 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`.
|
// 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
|
// Note that we do not actually access any components in this function, we just get a shared
|
||||||
@ -924,7 +924,7 @@ unsafe impl<'__w, T: Component> WorldQuery for Ref<'__w, T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const IS_DENSE: bool = {
|
const IS_DENSE: bool = {
|
||||||
match T::Storage::STORAGE_TYPE {
|
match T::STORAGE_TYPE {
|
||||||
StorageType::Table => true,
|
StorageType::Table => true,
|
||||||
StorageType::SparseSet => false,
|
StorageType::SparseSet => false,
|
||||||
}
|
}
|
||||||
@ -965,7 +965,7 @@ unsafe impl<'__w, T: Component> WorldQuery for Ref<'__w, T> {
|
|||||||
entity: Entity,
|
entity: Entity,
|
||||||
table_row: TableRow,
|
table_row: TableRow,
|
||||||
) -> Self::Item<'w> {
|
) -> Self::Item<'w> {
|
||||||
match T::Storage::STORAGE_TYPE {
|
match T::STORAGE_TYPE {
|
||||||
StorageType::Table => {
|
StorageType::Table => {
|
||||||
// SAFETY: STORAGE_TYPE = Table
|
// SAFETY: STORAGE_TYPE = Table
|
||||||
let (table_components, added_ticks, changed_ticks) =
|
let (table_components, added_ticks, changed_ticks) =
|
||||||
@ -1045,13 +1045,13 @@ unsafe impl<'__w, T: Component> ReadOnlyQueryData for Ref<'__w, T> {}
|
|||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub struct WriteFetch<'w, T> {
|
pub struct WriteFetch<'w, T> {
|
||||||
// T::Storage = TableStorage
|
// T::STORAGE_TYPE = StorageType::Table
|
||||||
table_data: Option<(
|
table_data: Option<(
|
||||||
ThinSlicePtr<'w, UnsafeCell<T>>,
|
ThinSlicePtr<'w, UnsafeCell<T>>,
|
||||||
ThinSlicePtr<'w, UnsafeCell<Tick>>,
|
ThinSlicePtr<'w, UnsafeCell<Tick>>,
|
||||||
ThinSlicePtr<'w, UnsafeCell<Tick>>,
|
ThinSlicePtr<'w, UnsafeCell<Tick>>,
|
||||||
)>,
|
)>,
|
||||||
// T::Storage = SparseStorage
|
// T::STORAGE_TYPE = StorageType::SparseSet
|
||||||
sparse_set: Option<&'w ComponentSparseSet>,
|
sparse_set: Option<&'w ComponentSparseSet>,
|
||||||
|
|
||||||
last_run: Tick,
|
last_run: Tick,
|
||||||
@ -1088,7 +1088,7 @@ unsafe impl<'__w, T: Component> WorldQuery for &'__w mut T {
|
|||||||
) -> WriteFetch<'w, T> {
|
) -> WriteFetch<'w, T> {
|
||||||
WriteFetch {
|
WriteFetch {
|
||||||
table_data: None,
|
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`,
|
// 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`.
|
// 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
|
// Note that we do not actually access any components in this function, we just get a shared
|
||||||
@ -1107,7 +1107,7 @@ unsafe impl<'__w, T: Component> WorldQuery for &'__w mut T {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const IS_DENSE: bool = {
|
const IS_DENSE: bool = {
|
||||||
match T::Storage::STORAGE_TYPE {
|
match T::STORAGE_TYPE {
|
||||||
StorageType::Table => true,
|
StorageType::Table => true,
|
||||||
StorageType::SparseSet => false,
|
StorageType::SparseSet => false,
|
||||||
}
|
}
|
||||||
@ -1148,7 +1148,7 @@ unsafe impl<'__w, T: Component> WorldQuery for &'__w mut T {
|
|||||||
entity: Entity,
|
entity: Entity,
|
||||||
table_row: TableRow,
|
table_row: TableRow,
|
||||||
) -> Self::Item<'w> {
|
) -> Self::Item<'w> {
|
||||||
match T::Storage::STORAGE_TYPE {
|
match T::STORAGE_TYPE {
|
||||||
StorageType::Table => {
|
StorageType::Table => {
|
||||||
// SAFETY: STORAGE_TYPE = Table
|
// SAFETY: STORAGE_TYPE = Table
|
||||||
let (table_components, added_ticks, changed_ticks) =
|
let (table_components, added_ticks, changed_ticks) =
|
||||||
@ -1433,7 +1433,7 @@ unsafe impl<T: Component> WorldQuery for Has<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const IS_DENSE: bool = {
|
const IS_DENSE: bool = {
|
||||||
match T::Storage::STORAGE_TYPE {
|
match T::STORAGE_TYPE {
|
||||||
StorageType::Table => true,
|
StorageType::Table => true,
|
||||||
StorageType::SparseSet => false,
|
StorageType::SparseSet => false,
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
archetype::Archetype,
|
archetype::Archetype,
|
||||||
component::{Component, ComponentId, ComponentStorage, StorageType, Tick},
|
component::{Component, ComponentId, StorageType, Tick},
|
||||||
entity::Entity,
|
entity::Entity,
|
||||||
query::{DebugCheckedUnwrap, FilteredAccess, WorldQuery},
|
query::{DebugCheckedUnwrap, FilteredAccess, WorldQuery},
|
||||||
storage::{Column, ComponentSparseSet, Table, TableRow},
|
storage::{Column, ComponentSparseSet, Table, TableRow},
|
||||||
@ -142,7 +142,7 @@ unsafe impl<T: Component> WorldQuery for With<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const IS_DENSE: bool = {
|
const IS_DENSE: bool = {
|
||||||
match T::Storage::STORAGE_TYPE {
|
match T::STORAGE_TYPE {
|
||||||
StorageType::Table => true,
|
StorageType::Table => true,
|
||||||
StorageType::SparseSet => false,
|
StorageType::SparseSet => false,
|
||||||
}
|
}
|
||||||
@ -250,7 +250,7 @@ unsafe impl<T: Component> WorldQuery for Without<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const IS_DENSE: bool = {
|
const IS_DENSE: bool = {
|
||||||
match T::Storage::STORAGE_TYPE {
|
match T::STORAGE_TYPE {
|
||||||
StorageType::Table => true,
|
StorageType::Table => true,
|
||||||
StorageType::SparseSet => false,
|
StorageType::SparseSet => false,
|
||||||
}
|
}
|
||||||
@ -604,7 +604,7 @@ unsafe impl<T: Component> WorldQuery for Added<T> {
|
|||||||
) -> Self::Fetch<'w> {
|
) -> Self::Fetch<'w> {
|
||||||
Self::Fetch::<'w> {
|
Self::Fetch::<'w> {
|
||||||
table_ticks: None,
|
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()),
|
.then(|| world.storages().sparse_sets.get(id).debug_checked_unwrap()),
|
||||||
last_run,
|
last_run,
|
||||||
this_run,
|
this_run,
|
||||||
@ -612,7 +612,7 @@ unsafe impl<T: Component> WorldQuery for Added<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const IS_DENSE: bool = {
|
const IS_DENSE: bool = {
|
||||||
match T::Storage::STORAGE_TYPE {
|
match T::STORAGE_TYPE {
|
||||||
StorageType::Table => true,
|
StorageType::Table => true,
|
||||||
StorageType::SparseSet => false,
|
StorageType::SparseSet => false,
|
||||||
}
|
}
|
||||||
@ -651,7 +651,7 @@ unsafe impl<T: Component> WorldQuery for Added<T> {
|
|||||||
entity: Entity,
|
entity: Entity,
|
||||||
table_row: TableRow,
|
table_row: TableRow,
|
||||||
) -> Self::Item<'w> {
|
) -> Self::Item<'w> {
|
||||||
match T::Storage::STORAGE_TYPE {
|
match T::STORAGE_TYPE {
|
||||||
StorageType::Table => {
|
StorageType::Table => {
|
||||||
// SAFETY: STORAGE_TYPE = Table
|
// SAFETY: STORAGE_TYPE = Table
|
||||||
let table = unsafe { fetch.table_ticks.debug_checked_unwrap() };
|
let table = unsafe { fetch.table_ticks.debug_checked_unwrap() };
|
||||||
@ -813,7 +813,7 @@ unsafe impl<T: Component> WorldQuery for Changed<T> {
|
|||||||
) -> Self::Fetch<'w> {
|
) -> Self::Fetch<'w> {
|
||||||
Self::Fetch::<'w> {
|
Self::Fetch::<'w> {
|
||||||
table_ticks: None,
|
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()),
|
.then(|| world.storages().sparse_sets.get(id).debug_checked_unwrap()),
|
||||||
last_run,
|
last_run,
|
||||||
this_run,
|
this_run,
|
||||||
@ -821,7 +821,7 @@ unsafe impl<T: Component> WorldQuery for Changed<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const IS_DENSE: bool = {
|
const IS_DENSE: bool = {
|
||||||
match T::Storage::STORAGE_TYPE {
|
match T::STORAGE_TYPE {
|
||||||
StorageType::Table => true,
|
StorageType::Table => true,
|
||||||
StorageType::SparseSet => false,
|
StorageType::SparseSet => false,
|
||||||
}
|
}
|
||||||
@ -860,7 +860,7 @@ unsafe impl<T: Component> WorldQuery for Changed<T> {
|
|||||||
entity: Entity,
|
entity: Entity,
|
||||||
table_row: TableRow,
|
table_row: TableRow,
|
||||||
) -> Self::Item<'w> {
|
) -> Self::Item<'w> {
|
||||||
match T::Storage::STORAGE_TYPE {
|
match T::STORAGE_TYPE {
|
||||||
StorageType::Table => {
|
StorageType::Table => {
|
||||||
// SAFETY: STORAGE_TYPE = Table
|
// SAFETY: STORAGE_TYPE = Table
|
||||||
let table = unsafe { fetch.table_ticks.debug_checked_unwrap() };
|
let table = unsafe { fetch.table_ticks.debug_checked_unwrap() };
|
||||||
|
@ -7,9 +7,7 @@ use crate::{
|
|||||||
archetype::{Archetype, ArchetypeComponentId, Archetypes},
|
archetype::{Archetype, ArchetypeComponentId, Archetypes},
|
||||||
bundle::Bundles,
|
bundle::Bundles,
|
||||||
change_detection::{MutUntyped, Ticks, TicksMut},
|
change_detection::{MutUntyped, Ticks, TicksMut},
|
||||||
component::{
|
component::{ComponentId, ComponentTicks, Components, StorageType, Tick, TickCells},
|
||||||
ComponentId, ComponentStorage, ComponentTicks, Components, StorageType, Tick, TickCells,
|
|
||||||
},
|
|
||||||
entity::{Entities, Entity, EntityLocation},
|
entity::{Entities, Entity, EntityLocation},
|
||||||
prelude::Component,
|
prelude::Component,
|
||||||
removal_detection::RemovedComponentEvents,
|
removal_detection::RemovedComponentEvents,
|
||||||
@ -713,7 +711,7 @@ impl<'w> UnsafeEntityCell<'w> {
|
|||||||
get_component(
|
get_component(
|
||||||
self.world,
|
self.world,
|
||||||
component_id,
|
component_id,
|
||||||
T::Storage::STORAGE_TYPE,
|
T::STORAGE_TYPE,
|
||||||
self.entity,
|
self.entity,
|
||||||
self.location,
|
self.location,
|
||||||
)
|
)
|
||||||
@ -740,7 +738,7 @@ impl<'w> UnsafeEntityCell<'w> {
|
|||||||
get_component_and_ticks(
|
get_component_and_ticks(
|
||||||
self.world,
|
self.world,
|
||||||
component_id,
|
component_id,
|
||||||
T::Storage::STORAGE_TYPE,
|
T::STORAGE_TYPE,
|
||||||
self.entity,
|
self.entity,
|
||||||
self.location,
|
self.location,
|
||||||
)
|
)
|
||||||
@ -770,7 +768,7 @@ impl<'w> UnsafeEntityCell<'w> {
|
|||||||
get_ticks(
|
get_ticks(
|
||||||
self.world,
|
self.world,
|
||||||
component_id,
|
component_id,
|
||||||
T::Storage::STORAGE_TYPE,
|
T::STORAGE_TYPE,
|
||||||
self.entity,
|
self.entity,
|
||||||
self.location,
|
self.location,
|
||||||
)
|
)
|
||||||
@ -839,7 +837,7 @@ impl<'w> UnsafeEntityCell<'w> {
|
|||||||
get_component_and_ticks(
|
get_component_and_ticks(
|
||||||
self.world,
|
self.world,
|
||||||
component_id,
|
component_id,
|
||||||
T::Storage::STORAGE_TYPE,
|
T::STORAGE_TYPE,
|
||||||
self.entity,
|
self.entity,
|
||||||
self.location,
|
self.location,
|
||||||
)
|
)
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
//! - Enforcing structural rules: When you have systems that depend on specific relationships
|
//! - Enforcing structural rules: When you have systems that depend on specific relationships
|
||||||
//! between components (like hierarchies or parent-child links) and need to maintain correctness.
|
//! between components (like hierarchies or parent-child links) and need to maintain correctness.
|
||||||
|
|
||||||
use bevy::ecs::component::{ComponentHooks, TableStorage};
|
use bevy::ecs::component::{ComponentHooks, StorageType};
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
@ -21,7 +21,7 @@ use std::collections::HashMap;
|
|||||||
struct MyComponent(KeyCode);
|
struct MyComponent(KeyCode);
|
||||||
|
|
||||||
impl Component for MyComponent {
|
impl Component for MyComponent {
|
||||||
type Storage = TableStorage;
|
const STORAGE_TYPE: StorageType = StorageType::Table;
|
||||||
|
|
||||||
/// Hooks can also be registered during component initialisation by
|
/// Hooks can also be registered during component initialisation by
|
||||||
/// implementing `register_component_hooks`
|
/// implementing `register_component_hooks`
|
||||||
|
Loading…
Reference in New Issue
Block a user