Skip to content

Redo bevy 0.15 update #73

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
merged 3 commits into from
Dec 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 Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,17 @@ members = [

[workspace.dependencies]
tracing = "0.1"
bevy_ecs = "0.14"
bevy_app = "0.14"
bevy_core = "0.14"
bevy_ecs = "0.15"
bevy_app = "0.15"
bevy_core = "0.15"

# proc macro
bevy-trait-query-impl = { version = "0.6.0", path = "./bevy-trait-query-impl" }
proc-macro2 = "1"
syn = { version = "2", features = ["full"] }
quote = "1"
proc-macro-crate = "1"
proc-macro-crate = "3"

# dev deps
criterion = "0.5"
bevy = { version = "0.14", default-features = false }
bevy = { version = "0.15", default-features = false }
10 changes: 10 additions & 0 deletions bevy-trait-query-impl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,11 @@ fn impl_trait_query(arg: TokenStream, item: TokenStream) -> Result<TokenStream2>
) -> bool {
<#my_crate::All<&#trait_object> as #imports::WorldQuery>::matches_component_set(state, set_contains_id)
}

#[inline]
fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
fetch
}
}

unsafe impl #impl_generics_with_lifetime #imports::QueryData for &'__a mut #trait_object
Expand Down Expand Up @@ -351,6 +356,11 @@ fn impl_trait_query(arg: TokenStream, item: TokenStream) -> Result<TokenStream2>
) -> bool {
<#my_crate::All<&mut #trait_object> as #imports::WorldQuery>::matches_component_set(state, set_contains_id)
}

#[inline]
fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
fetch
}
}
};

Expand Down
39 changes: 22 additions & 17 deletions bevy-trait-query/src/all/core/read.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,20 +52,26 @@ impl<'a, Trait: ?Sized + TraitQuery> Iterator for ReadTableTraitsIter<'a, Trait>
fn next(&mut self) -> Option<Self::Item> {
// Iterate the remaining table components that are registered,
// until we find one that exists in the table.
let (column, meta) = unsafe { zip_exact(&mut self.components, &mut self.meta) }
.find_map(|(&component, meta)| self.table.get_column(component).zip(Some(meta)))?;
// SAFETY: We have shared access to the entire column.
let ptr = unsafe {
column
.get_data_ptr()
.byte_add(self.table_row.as_usize() * meta.size_bytes)
};
let (ptr, component, meta) = unsafe { zip_exact(&mut self.components, &mut self.meta) }
.find_map(|(&component, meta)| {
// SAFETY: we know that the `table_row` is a valid index.
let ptr = unsafe { self.table.get_component(component, self.table_row) }?;
Some((ptr, component, meta))
})?;
let trait_object = unsafe { meta.dyn_ctor.cast(ptr) };

// SAFETY: we know that the `table_row` is a valid index.
// SAFETY:
// Read access has been registered, so we can dereference it immutably.
let added_tick = unsafe { column.get_added_tick_unchecked(self.table_row).deref() };
let changed_tick = unsafe { column.get_changed_tick_unchecked(self.table_row).deref() };
let added_tick = unsafe {
self.table
.get_added_tick(component, self.table_row)?
.deref()
};
let changed_tick = unsafe {
self.table
.get_changed_tick(component, self.table_row)?
.deref()
};

Some(Ref::new(
trait_object,
Expand Down Expand Up @@ -94,13 +100,12 @@ impl<'a, Trait: ?Sized + TraitQuery> Iterator for ReadSparseTraitsIter<'a, Trait
fn next(&mut self) -> Option<Self::Item> {
// Iterate the remaining sparse set components that are registered,
// until we find one that exists in the archetype.
let ((ptr, ticks_ptr), meta) = unsafe { zip_exact(&mut self.components, &mut self.meta) }
let (ptr, ticks_ptr, meta) = unsafe { zip_exact(&mut self.components, &mut self.meta) }
.find_map(|(&component, meta)| {
self.sparse_sets
.get(component)
.and_then(|set| set.get_with_ticks(self.entity))
.zip(Some(meta))
})?;
let set = self.sparse_sets.get(component)?;
let (ptr, ticks, _) = set.get_with_ticks(self.entity)?;
Some((ptr, ticks, meta))
})?;
let trait_object = unsafe { meta.dyn_ctor.cast(ptr) };
let added_tick = unsafe { ticks_ptr.added.deref() };
let changed_tick = unsafe { ticks_ptr.changed.deref() };
Expand Down
40 changes: 19 additions & 21 deletions bevy-trait-query/src/all/core/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,12 @@ impl<'a, Trait: ?Sized + TraitQuery> Iterator for WriteTableTraitsIter<'a, Trait
fn next(&mut self) -> Option<Self::Item> {
// Iterate the remaining table components that are registered,
// until we find one that exists in the table.
let (column, meta) = unsafe { zip_exact(&mut self.components, &mut self.meta) }
.find_map(|(&component, meta)| self.table.get_column(component).zip(Some(meta)))?;
let ptr = unsafe {
column
.get_data_ptr()
.byte_add(self.table_row.as_usize() * meta.size_bytes)
};
let (ptr, component, meta) = unsafe { zip_exact(&mut self.components, &mut self.meta) }
.find_map(|(&component, meta)| {
// SAFETY: we know that the `table_row` is a valid index.
let ptr = unsafe { self.table.get_component(component, self.table_row) }?;
Some((ptr, component, meta))
})?;
// SAFETY: The instance of `WriteTraits` that created this iterator
// has exclusive access to all table components registered with the trait.
//
Expand All @@ -74,10 +73,14 @@ impl<'a, Trait: ?Sized + TraitQuery> Iterator for WriteTableTraitsIter<'a, Trait
let trait_object = unsafe { meta.dyn_ctor.cast_mut(ptr) };
// SAFETY: We have exclusive access to the component, so by extension
// we have exclusive access to the corresponding `ComponentTicks`.
let added = unsafe { column.get_added_tick_unchecked(self.table_row).deref_mut() };
let added = unsafe {
self.table
.get_added_tick(component, self.table_row)?
.deref_mut()
};
let changed = unsafe {
column
.get_changed_tick_unchecked(self.table_row)
self.table
.get_changed_tick(component, self.table_row)?
.deref_mut()
};
Some(Mut::new(
Expand Down Expand Up @@ -108,13 +111,12 @@ impl<'a, Trait: ?Sized + TraitQuery> Iterator for WriteSparseTraitsIter<'a, Trai
fn next(&mut self) -> Option<Self::Item> {
// Iterate the remaining sparse set components we have registered,
// until we find one that exists in the archetype.
let ((ptr, component_ticks), meta) =
let (ptr, component_ticks, meta) =
unsafe { zip_exact(&mut self.components, &mut self.meta) }.find_map(
|(&component, meta)| {
self.sparse_sets
.get(component)
.and_then(|set| set.get_with_ticks(self.entity))
.zip(Some(meta))
let set = self.sparse_sets.get(component)?;
let (ptr, ticks, _) = set.get_with_ticks(self.entity)?;
Some((ptr, ticks, meta))
},
)?;

Expand Down Expand Up @@ -201,9 +203,7 @@ impl<'w, Trait: ?Sized + TraitQuery> IntoIterator for WriteTraits<'w, Trait> {
}
}

impl<'world, 'local, Trait: ?Sized + TraitQuery> IntoIterator
for &'local WriteTraits<'world, Trait>
{
impl<'local, Trait: ?Sized + TraitQuery> IntoIterator for &'local WriteTraits<'_, Trait> {
type Item = Ref<'local, Trait>;
type IntoIter = CombinedReadTraitsIter<'local, Trait>;
#[inline]
Expand All @@ -228,9 +228,7 @@ impl<'world, 'local, Trait: ?Sized + TraitQuery> IntoIterator
}
}

impl<'world, 'local, Trait: ?Sized + TraitQuery> IntoIterator
for &'local mut WriteTraits<'world, Trait>
{
impl<'local, Trait: ?Sized + TraitQuery> IntoIterator for &'local mut WriteTraits<'_, Trait> {
type Item = Mut<'local, Trait>;
type IntoIter = CombinedWriteTraitsIter<'local, Trait>;
#[inline]
Expand Down
30 changes: 20 additions & 10 deletions bevy-trait-query/src/all/impls/all.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,15 @@ use crate::{
/// - `Query<&mut dyn Trait>` yields a [`WriteTraits`] object
pub struct All<T: ?Sized>(T);

unsafe impl<'a, Trait: ?Sized + TraitQuery> QueryData for All<&'a Trait> {
unsafe impl<Trait: ?Sized + TraitQuery> QueryData for All<&Trait> {
type ReadOnly = Self;
}
unsafe impl<'a, Trait: ?Sized + TraitQuery> ReadOnlyQueryData for All<&'a Trait> {}
unsafe impl<Trait: ?Sized + TraitQuery> ReadOnlyQueryData for All<&Trait> {}

// SAFETY: We only access the components registered in the trait registry.
// This is known to match the set of components in the TraitQueryState,
// which is used to match archetypes and register world access.
unsafe impl<'a, Trait: ?Sized + TraitQuery> WorldQuery for All<&'a Trait> {
unsafe impl<Trait: ?Sized + TraitQuery> WorldQuery for All<&Trait> {
type Item<'w> = ReadTraits<'w, Trait>;
type Fetch<'w> = AllTraitsFetch<'w, Trait>;
type State = TraitQueryState<Trait>;
Expand Down Expand Up @@ -109,18 +109,18 @@ unsafe impl<'a, Trait: ?Sized + TraitQuery> WorldQuery for All<&'a Trait> {
let mut new_access = access.clone();
for &component in &*state.components {
assert!(
!access.access().has_write(component),
!access.access().has_component_write(component),
"&{} conflicts with a previous access in this query. Shared access cannot coincide with exclusive access.",
std::any::type_name::<Trait>(),
);
if not_first {
let mut intermediate = access.clone();
intermediate.add_read(component);
intermediate.add_component_read(component);
new_access.append_or(&intermediate);
new_access.extend_access(&intermediate);
} else {
new_access.and_with(component);
new_access.access_mut().add_read(component);
new_access.access_mut().add_component_read(component);
not_first = true;
}
}
Expand All @@ -145,6 +145,11 @@ unsafe impl<'a, Trait: ?Sized + TraitQuery> WorldQuery for All<&'a Trait> {
) -> bool {
state.matches_component_set_any(set_contains_id)
}

#[inline]
fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
fetch
}
}

unsafe impl<'a, Trait: ?Sized + TraitQuery> QueryData for All<&'a mut Trait> {
Expand All @@ -154,7 +159,7 @@ unsafe impl<'a, Trait: ?Sized + TraitQuery> QueryData for All<&'a mut Trait> {
// SAFETY: We only access the components registered in the trait registry.
// This is known to match the set of components in the TraitQueryState,
// which is used to match archetypes and register world access.
unsafe impl<'a, Trait: ?Sized + TraitQuery> WorldQuery for All<&'a mut Trait> {
unsafe impl<Trait: ?Sized + TraitQuery> WorldQuery for All<&mut Trait> {
type Item<'w> = WriteTraits<'w, Trait>;
type Fetch<'w> = AllTraitsFetch<'w, Trait>;
type State = TraitQueryState<Trait>;
Expand Down Expand Up @@ -230,18 +235,18 @@ unsafe impl<'a, Trait: ?Sized + TraitQuery> WorldQuery for All<&'a mut Trait> {
let mut new_access = access.clone();
for &component in &*state.components {
assert!(
!access.access().has_write(component),
!access.access().has_component_write(component),
"&mut {} conflicts with a previous access in this query. Mutable component access must be unique.",
std::any::type_name::<Trait>(),
);
if not_first {
let mut intermediate = access.clone();
intermediate.add_write(component);
intermediate.add_component_write(component);
new_access.append_or(&intermediate);
new_access.extend_access(&intermediate);
} else {
new_access.and_with(component);
new_access.access_mut().add_write(component);
new_access.access_mut().add_component_write(component);
not_first = true;
}
}
Expand All @@ -266,4 +271,9 @@ unsafe impl<'a, Trait: ?Sized + TraitQuery> WorldQuery for All<&'a mut Trait> {
) -> bool {
state.matches_component_set_any(set_contains_id)
}

#[inline]
fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
fetch
}
}
2 changes: 1 addition & 1 deletion bevy-trait-query/src/internal/register_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ impl RegisterExt for World {
where
(C,): TraitQueryMarker<Trait, Covered = C>,
{
let component_id = self.init_component::<C>();
let component_id = self.register_component::<C>();
let registry = self
.get_resource_or_insert_with::<TraitImplRegistry<Trait>>(Default::default)
.into_inner();
Expand Down
Loading
Loading