diff --git a/crates/bevy_ecs/macros/src/fetch.rs b/crates/bevy_ecs/macros/src/fetch.rs index 50adea5691e2e..f7d0433306e5b 100644 --- a/crates/bevy_ecs/macros/src/fetch.rs +++ b/crates/bevy_ecs/macros/src/fetch.rs @@ -279,9 +279,12 @@ pub fn derive_world_query_impl(ast: DeriveInput) -> TokenStream { #(self.#field_idents.update_archetype_component_access(_archetype, _access);)* } - fn matches_component_set(&self, _set_contains_id: &impl Fn(#path::component::ComponentId) -> bool) -> bool { - true #(&& self.#field_idents.matches_component_set(_set_contains_id))* + fn matches_archetype(&self, _archetype: &#path::archetype::Archetype) -> bool { + true #(&& self.#field_idents.matches_archetype(_archetype))* + } + fn matches_table(&self, _table: &#path::storage::Table) -> bool { + true #(&& self.#field_idents.matches_table(_table))* } } }; diff --git a/crates/bevy_ecs/src/query/fetch.rs b/crates/bevy_ecs/src/query/fetch.rs index fafd634f8a464..ff2a629277502 100644 --- a/crates/bevy_ecs/src/query/fetch.rs +++ b/crates/bevy_ecs/src/query/fetch.rs @@ -421,7 +421,7 @@ pub trait Fetch<'world>: Sized { /// /// Implementor must ensure that [`FetchState::update_component_access`] and /// [`FetchState::update_archetype_component_access`] exactly reflects the results of -/// [`FetchState::matches_component_set`], [`Fetch::archetype_fetch`], and +/// [`FetchState::matches_archetype`], [`FetchState::matches_table`], [`Fetch::archetype_fetch`], and /// [`Fetch::table_fetch`]. pub unsafe trait FetchState: Send + Sync + Sized { fn init(world: &mut World) -> Self; @@ -431,7 +431,8 @@ pub unsafe trait FetchState: Send + Sync + Sized { archetype: &Archetype, access: &mut Access, ); - fn matches_component_set(&self, set_contains_id: &impl Fn(ComponentId) -> bool) -> bool; + fn matches_archetype(&self, archetype: &Archetype) -> bool; + fn matches_table(&self, table: &Table) -> bool; } /// A fetch that is read only. @@ -479,7 +480,12 @@ unsafe impl FetchState for EntityState { } #[inline] - fn matches_component_set(&self, _set_contains_id: &impl Fn(ComponentId) -> bool) -> bool { + fn matches_archetype(&self, _archetype: &Archetype) -> bool { + true + } + + #[inline] + fn matches_table(&self, _table: &Table) -> bool { true } } @@ -582,8 +588,12 @@ unsafe impl FetchState for ReadState { } } - fn matches_component_set(&self, set_contains_id: &impl Fn(ComponentId) -> bool) -> bool { - set_contains_id(self.component_id) + fn matches_archetype(&self, archetype: &Archetype) -> bool { + archetype.contains(self.component_id) + } + + fn matches_table(&self, table: &Table) -> bool { + table.has_column(self.component_id) } } @@ -815,8 +825,12 @@ unsafe impl FetchState for WriteState { } } - fn matches_component_set(&self, set_contains_id: &impl Fn(ComponentId) -> bool) -> bool { - set_contains_id(self.component_id) + fn matches_archetype(&self, archetype: &Archetype) -> bool { + archetype.contains(self.component_id) + } + + fn matches_table(&self, table: &Table) -> bool { + table.has_column(self.component_id) } } @@ -1091,16 +1105,17 @@ unsafe impl FetchState for OptionState { archetype: &Archetype, access: &mut Access, ) { - if self - .state - .matches_component_set(&|id| archetype.contains(id)) - { + if self.state.matches_archetype(archetype) { self.state .update_archetype_component_access(archetype, access); } } - fn matches_component_set(&self, _set_contains_id: &impl Fn(ComponentId) -> bool) -> bool { + fn matches_archetype(&self, _archetype: &Archetype) -> bool { + true + } + + fn matches_table(&self, _table: &Table) -> bool { true } } @@ -1138,9 +1153,7 @@ impl<'w, T: Fetch<'w>> Fetch<'w> for OptionFetch { archetype: &'w Archetype, tables: &'w Tables, ) { - self.matches = state - .state - .matches_component_set(&|id| archetype.contains(id)); + self.matches = state.state.matches_archetype(archetype); if self.matches { self.fetch.set_archetype(&state.state, archetype, tables); } @@ -1148,9 +1161,7 @@ impl<'w, T: Fetch<'w>> Fetch<'w> for OptionFetch { #[inline] unsafe fn set_table(&mut self, state: &Self::State, table: &'w Table) { - self.matches = state - .state - .matches_component_set(&|id| table.has_column(id)); + self.matches = state.state.matches_table(table); if self.matches { self.fetch.set_table(&state.state, table); } @@ -1286,8 +1297,12 @@ unsafe impl FetchState for ChangeTrackersState { } } - fn matches_component_set(&self, set_contains_id: &impl Fn(ComponentId) -> bool) -> bool { - set_contains_id(self.component_id) + fn matches_archetype(&self, archetype: &Archetype) -> bool { + archetype.contains(self.component_id) + } + + fn matches_table(&self, table: &Table) -> bool { + table.has_column(self.component_id) } } @@ -1536,9 +1551,14 @@ macro_rules! impl_tuple_fetch { $($name.update_archetype_component_access(_archetype, _access);)* } - fn matches_component_set(&self, _set_contains_id: &impl Fn(ComponentId) -> bool) -> bool { + fn matches_archetype(&self, _archetype: &Archetype) -> bool { + let ($($name,)*) = self; + true $(&& $name.matches_archetype(_archetype))* + } + + fn matches_table(&self, _table: &Table) -> bool { let ($($name,)*) = self; - true $(&& $name.matches_component_set(_set_contains_id))* + true $(&& $name.matches_table(_table))* } } @@ -1598,7 +1618,7 @@ macro_rules! impl_anytuple_fetch { let ($($name,)*) = &mut self.0; let ($($state,)*) = &_state.0; $( - $name.1 = $state.matches_component_set(&|id| _archetype.contains(id)); + $name.1 = $state.matches_archetype(_archetype); if $name.1 { $name.0.set_archetype($state, _archetype, _tables); } @@ -1610,7 +1630,7 @@ macro_rules! impl_anytuple_fetch { let ($($name,)*) = &mut self.0; let ($($state,)*) = &_state.0; $( - $name.1 = $state.matches_component_set(&|id| _table.has_column(id)); + $name.1 = $state.matches_table(_table); if $name.1 { $name.0.set_table($state, _table); } @@ -1679,14 +1699,20 @@ macro_rules! impl_anytuple_fetch { fn update_archetype_component_access(&self, _archetype: &Archetype, _access: &mut Access) { let ($($name,)*) = &self.0; $( - if $name.matches_component_set(&|id| _archetype.contains(id)) { + if $name.matches_archetype(_archetype) { $name.update_archetype_component_access(_archetype, _access); } )* } - fn matches_component_set(&self, _set_contains_id: &impl Fn(ComponentId) -> bool) -> bool { + + fn matches_archetype(&self, _archetype: &Archetype) -> bool { + let ($($name,)*) = &self.0; + false $(|| $name.matches_archetype(_archetype))* + } + + fn matches_table(&self, _table: &Table) -> bool { let ($($name,)*) = &self.0; - false $(|| $name.matches_component_set(_set_contains_id))* + false $(|| $name.matches_table(_table))* } } diff --git a/crates/bevy_ecs/src/query/filter.rs b/crates/bevy_ecs/src/query/filter.rs index f7ef292d6b10f..cded72911af6b 100644 --- a/crates/bevy_ecs/src/query/filter.rs +++ b/crates/bevy_ecs/src/query/filter.rs @@ -91,8 +91,12 @@ unsafe impl FetchState for WithState { ) { } - fn matches_component_set(&self, set_contains_id: &impl Fn(ComponentId) -> bool) -> bool { - set_contains_id(self.component_id) + fn matches_archetype(&self, archetype: &Archetype) -> bool { + archetype.contains(self.component_id) + } + + fn matches_table(&self, table: &Table) -> bool { + table.has_column(self.component_id) } } @@ -230,8 +234,13 @@ unsafe impl FetchState for WithoutState { _access: &mut Access, ) { } - fn matches_component_set(&self, set_contains_id: &impl Fn(ComponentId) -> bool) -> bool { - !set_contains_id(self.component_id) + + fn matches_archetype(&self, archetype: &Archetype) -> bool { + !archetype.contains(self.component_id) + } + + fn matches_table(&self, table: &Table) -> bool { + !table.has_column(self.component_id) } } @@ -383,7 +392,7 @@ macro_rules! impl_query_filter_tuple { let ($($filter,)*) = &mut self.0; let ($($state,)*) = &state.0; $( - $filter.matches = $state.matches_component_set(&|id| table.has_column(id)); + $filter.matches = $state.matches_table(table); if $filter.matches { $filter.fetch.set_table($state, table); } @@ -395,7 +404,7 @@ macro_rules! impl_query_filter_tuple { let ($($filter,)*) = &mut self.0; let ($($state,)*) = &state.0; $( - $filter.matches = $state.matches_component_set(&|id| archetype.contains(id)); + $filter.matches = $state.matches_archetype(archetype); if $filter.matches { $filter.fetch.set_archetype($state, archetype, tables); } @@ -470,9 +479,14 @@ macro_rules! impl_query_filter_tuple { $($filter.update_archetype_component_access(archetype, access);)* } - fn matches_component_set(&self, _set_contains_id: &impl Fn(ComponentId) -> bool) -> bool { + fn matches_archetype(&self, archetype: &Archetype) -> bool { let ($($filter,)*) = &self.0; - false $(|| $filter.matches_component_set(_set_contains_id))* + false $(|| $filter.matches_archetype(archetype))* + } + + fn matches_table(&self, table: &Table) -> bool { + let ($($filter,)*) = &self.0; + false $(|| $filter.matches_table(table))* } } @@ -552,8 +566,12 @@ macro_rules! impl_tick_filter { } } - fn matches_component_set(&self, set_contains_id: &impl Fn(ComponentId) -> bool) -> bool { - set_contains_id(self.component_id) + fn matches_archetype(&self, archetype: &Archetype) -> bool { + archetype.contains(self.component_id) + } + + fn matches_table(&self, table: &Table) -> bool { + table.has_column(self.component_id) } } diff --git a/crates/bevy_ecs/src/query/state.rs b/crates/bevy_ecs/src/query/state.rs index a01fc4019de4f..200ddd809a55f 100644 --- a/crates/bevy_ecs/src/query/state.rs +++ b/crates/bevy_ecs/src/query/state.rs @@ -115,12 +115,8 @@ impl QueryState { /// Creates a new [`Archetype`]. pub fn new_archetype(&mut self, archetype: &Archetype) { - if self - .fetch_state - .matches_component_set(&|id| archetype.contains(id)) - && self - .filter_state - .matches_component_set(&|id| archetype.contains(id)) + if self.fetch_state.matches_archetype(archetype) + && self.filter_state.matches_archetype(archetype) { self.fetch_state .update_archetype_component_access(archetype, &mut self.archetype_component_access);