Skip to content

Commit

Permalink
Reorganize fetch.rs and add more documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
InBetweenNames committed Oct 19, 2022
1 parent a06c865 commit 45cd178
Showing 1 changed file with 107 additions and 104 deletions.
211 changes: 107 additions & 104 deletions crates/bevy_ecs/src/query/fetch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -467,23 +467,6 @@ pub trait WorldQueryBatch<const N: usize, const ALIGN: usize>:
) -> <Self as WorldQueryBatchGats<'w, N, ALIGN>>::FullBatch;
}

impl<const N: usize, const ALIGN: usize> WorldQueryBatch<N, ALIGN> for Entity
where
Entity: AlignedBatchGat<N, ALIGN>,
{
#[inline]
unsafe fn table_fetch_batched_aligned<'w>(
fetch: &mut <Self as WorldQueryGats<'w>>::Fetch,
table_row_start: usize,
len: usize,
) -> <Self as WorldQueryBatchGats<'w, N, ALIGN>>::FullBatch {
let entities = fetch
.entities
.unwrap_or_else(|| debug_checked_unreachable());
entities.get_batch_aligned::<N, ALIGN>(table_row_start, len)
}
}

/// A helper trait for [`WorldQueryBatch`] that works around Rust's lack of Generic Associated Types.
///
/// **Note**: Consider using the type alias [`QueryBatch`] for conenvience instead of referring to `FullBatch` directly.
Expand Down Expand Up @@ -597,6 +580,23 @@ unsafe impl WorldQuery for Entity {
}
}

impl<const N: usize, const ALIGN: usize> WorldQueryBatch<N, ALIGN> for Entity
where
Entity: AlignedBatchGat<N, ALIGN>,
{
#[inline]
unsafe fn table_fetch_batched_aligned<'w>(
fetch: &mut <Self as WorldQueryGats<'w>>::Fetch,
table_row_start: usize,
len: usize,
) -> <Self as WorldQueryBatchGats<'w, N, ALIGN>>::FullBatch {
let entities = fetch
.entities
.unwrap_or_else(|| debug_checked_unreachable());
entities.get_batch_aligned::<N, ALIGN>(table_row_start, len)
}
}

impl<'w> WorldQueryGats<'w> for Entity {
type Fetch = EntityFetch<'w>;
type Item = Entity;
Expand All @@ -622,29 +622,6 @@ pub struct ReadFetch<'w, T> {
sparse_set: Option<&'w ComponentSparseSet>,
}

impl<T: Component, const N: usize, const ALIGN: usize> WorldQueryBatch<N, ALIGN> for &T
where
T: AlignedBatchGat<N, ALIGN>,
{
#[inline]
unsafe fn table_fetch_batched_aligned<'w>(
fetch: &mut <Self as WorldQueryGats<'w>>::Fetch,
table_row_start: usize,
len: usize,
) -> <Self as WorldQueryBatchGats<'w, N, ALIGN>>::FullBatch
where
T: AlignedBatchGat<N, ALIGN>,
{
//TODO: when generalized const expresions are stable, want the following:
//gcd::euclid_usize(ptr::MAX_SIMD_ALIGNMENT, N * core::mem::size_of::<T>());

let components = fetch
.table_components
.unwrap_or_else(|| debug_checked_unreachable());
components.get_batch_aligned_deref::<N, ALIGN>(table_row_start, len)
}
}

/// SAFETY: `ROQueryFetch<Self>` is the same as `QueryFetch<Self>`
unsafe impl<T: Component> WorldQuery for &T {
type ReadOnly = Self;
Expand Down Expand Up @@ -775,6 +752,29 @@ unsafe impl<T: Component> WorldQuery for &T {
}
}

impl<T: Component, const N: usize, const ALIGN: usize> WorldQueryBatch<N, ALIGN> for &T
where
T: AlignedBatchGat<N, ALIGN>,
{
#[inline]
unsafe fn table_fetch_batched_aligned<'w>(
fetch: &mut <Self as WorldQueryGats<'w>>::Fetch,
table_row_start: usize,
len: usize,
) -> <Self as WorldQueryBatchGats<'w, N, ALIGN>>::FullBatch
where
T: AlignedBatchGat<N, ALIGN>,
{
//TODO: when generalized const expresions are stable, want the following:
//gcd::euclid_usize(ptr::MAX_SIMD_ALIGNMENT, N * core::mem::size_of::<T>());

let components = fetch
.table_components
.unwrap_or_else(|| debug_checked_unreachable());
components.get_batch_aligned_deref::<N, ALIGN>(table_row_start, len)
}
}

impl<T> Clone for ReadFetch<'_, T> {
fn clone(&self) -> Self {
Self {
Expand Down Expand Up @@ -815,39 +815,6 @@ pub struct WriteFetch<'w, T> {
change_tick: u32,
}

//TODO: inlines

impl<'__w, T: Component, const N: usize, const ALIGN: usize> WorldQueryBatch<N, ALIGN>
for &'__w mut T
where
T: AlignedBatchGat<N, ALIGN>,
ComponentTicks: AlignedBatchGat<N, ALIGN>,
{
#[inline]
unsafe fn table_fetch_batched_aligned<'w>(
fetch: &mut <Self as WorldQueryGats<'w>>::Fetch,
table_row_start: usize,
len: usize,
) -> <Self as WorldQueryBatchGats<'w, N, ALIGN>>::FullBatch {
let (table_components, table_ticks) = fetch
.table_components
.zip(fetch.table_ticks)
.unwrap_or_else(|| debug_checked_unreachable());

MutBatch::<T, N, ALIGN> {
value: table_components.get_batch_aligned_deref_mut::<N, ALIGN>(table_row_start, len),
ticks: TicksBatch {
// SAFETY: [table_row_start..+batch.len()] is in range
component_ticks: table_ticks
.get_batch_aligned_deref_mut::<N, ALIGN>(table_row_start, len),
change_tick: fetch.change_tick,
last_change_tick: fetch.last_change_tick,
},
_marker: PhantomData,
}
}
}

/// SAFETY: access of `&T` is a subset of `&mut T`
unsafe impl<'__w, T: Component> WorldQuery for &'__w mut T {
type ReadOnly = &'__w T;
Expand Down Expand Up @@ -1010,6 +977,37 @@ unsafe impl<'__w, T: Component> WorldQuery for &'__w mut T {
}
}

impl<'__w, T: Component, const N: usize, const ALIGN: usize> WorldQueryBatch<N, ALIGN>
for &'__w mut T
where
T: AlignedBatchGat<N, ALIGN>,
ComponentTicks: AlignedBatchGat<N, ALIGN>,
{
#[inline]
unsafe fn table_fetch_batched_aligned<'w>(
fetch: &mut <Self as WorldQueryGats<'w>>::Fetch,
table_row_start: usize,
len: usize,
) -> <Self as WorldQueryBatchGats<'w, N, ALIGN>>::FullBatch {
let (table_components, table_ticks) = fetch
.table_components
.zip(fetch.table_ticks)
.unwrap_or_else(|| debug_checked_unreachable());

MutBatch::<T, N, ALIGN> {
value: table_components.get_batch_aligned_deref_mut::<N, ALIGN>(table_row_start, len),
ticks: TicksBatch {
// SAFETY: [table_row_start..+batch.len()] is in range
component_ticks: table_ticks
.get_batch_aligned_deref_mut::<N, ALIGN>(table_row_start, len),
change_tick: fetch.change_tick,
last_change_tick: fetch.last_change_tick,
},
_marker: PhantomData,
}
}
}

impl<T> Clone for WriteFetch<'_, T> {
fn clone(&self) -> Self {
Self {
Expand Down Expand Up @@ -1055,28 +1053,6 @@ where
}
}

impl<T: WorldQuery, const N: usize, const ALIGN: usize> WorldQueryBatch<N, ALIGN> for Option<T>
where
T: WorldQueryBatch<N, ALIGN>,
{
#[inline]
unsafe fn table_fetch_batched_aligned<'w>(
fetch: &mut <Self as WorldQueryGats<'w>>::Fetch,
table_row_start: usize,
len: usize,
) -> <Self as WorldQueryBatchGats<'w, N, ALIGN>>::FullBatch {
if fetch.matches {
Some(T::table_fetch_batched_aligned(
&mut fetch.fetch,
table_row_start,
len,
))
} else {
None
}
}
}

// SAFETY: defers to soundness of `T: WorldQuery` impl
unsafe impl<T: WorldQuery> WorldQuery for Option<T> {
type ReadOnly = Option<T::ReadOnly>;
Expand Down Expand Up @@ -1179,6 +1155,28 @@ unsafe impl<T: WorldQuery> WorldQuery for Option<T> {
}
}

impl<T: WorldQuery, const N: usize, const ALIGN: usize> WorldQueryBatch<N, ALIGN> for Option<T>
where
T: WorldQueryBatch<N, ALIGN>,
{
#[inline]
unsafe fn table_fetch_batched_aligned<'w>(
fetch: &mut <Self as WorldQueryGats<'w>>::Fetch,
table_row_start: usize,
len: usize,
) -> <Self as WorldQueryBatchGats<'w, N, ALIGN>>::FullBatch {
if fetch.matches {
Some(T::table_fetch_batched_aligned(
&mut fetch.fetch,
table_row_start,
len,
))
} else {
None
}
}
}

/// SAFETY: [`OptionFetch`] is read only because `T` is read only
unsafe impl<T: ReadOnlyWorldQuery> ReadOnlyWorldQuery for Option<T> {}

Expand Down Expand Up @@ -1259,6 +1257,8 @@ impl<T: Component> ChangeTrackers<T> {
}
}

/// A batch of [`ChangeTrackers`]. This is used when performing queries with Change Trackers using the
/// [`Query::for_each_mut_batched`](crate::system::Query::for_each_mut_batched) and [`Query::for_each_batched`](crate::system::Query::for_each_batched) functions.
#[derive(Clone)]
pub struct ChangeTrackersBatch<'a, T, const N: usize, const ALIGN: usize>
where
Expand All @@ -1275,6 +1275,7 @@ where
ComponentTicks: AlignedBatchGat<N, ALIGN>,
{
/// Returns true if this component has been added since the last execution of this system.
#[inline]
pub fn is_added(&self) -> bool {
self.component_ticks
.as_array()
Expand All @@ -1283,6 +1284,7 @@ where
}

/// Returns true if this component has been changed since the last execution of this system.
#[inline]
pub fn is_changed(&self) -> bool {
self.component_ticks
.as_array()
Expand Down Expand Up @@ -1615,15 +1617,6 @@ macro_rules! impl_tuple_fetch {
}
}

/// SAFETY: each item in the tuple is read only
unsafe impl<$($name: ReadOnlyWorldQuery),*> ReadOnlyWorldQuery for ($($name,)*) {}

#[allow(unused_variables)]
#[allow(non_snake_case)]
impl<'w, const N: usize, const ALIGN: usize, $($name: WorldQueryBatchGats<'w, N, ALIGN>),*> WorldQueryBatchGats<'w, N, ALIGN> for ($($name,)*) {
type FullBatch = ($($name::FullBatch,)*);
}

#[allow(unused_variables)]
#[allow(non_snake_case)]
#[allow(clippy::unused_unit)]
Expand All @@ -1641,6 +1634,16 @@ macro_rules! impl_tuple_fetch {
($($name::table_fetch_batched_aligned($name, _table_row_start, _len),)*)
}
}

/// SAFETY: each item in the tuple is read only
unsafe impl<$($name: ReadOnlyWorldQuery),*> ReadOnlyWorldQuery for ($($name,)*) {}

#[allow(unused_variables)]
#[allow(non_snake_case)]
impl<'w, const N: usize, const ALIGN: usize, $($name: WorldQueryBatchGats<'w, N, ALIGN>),*> WorldQueryBatchGats<'w, N, ALIGN> for ($($name,)*) {
type FullBatch = ($($name::FullBatch,)*);
}

};
}

Expand Down

0 comments on commit 45cd178

Please sign in to comment.