diff --git a/crates/bevy_ecs/hecs/src/archetype.rs b/crates/bevy_ecs/hecs/src/archetype.rs index c9d9503b8c..85d1fa331b 100644 --- a/crates/bevy_ecs/hecs/src/archetype.rs +++ b/crates/bevy_ecs/hecs/src/archetype.rs @@ -90,6 +90,7 @@ impl Archetype { } #[allow(missing_docs)] + #[inline] pub fn has(&self) -> bool { self.has_dynamic(TypeId::of::()) } @@ -139,6 +140,7 @@ impl Archetype { } #[allow(missing_docs)] + #[inline] pub fn borrow(&self) { if self .state @@ -150,6 +152,7 @@ impl Archetype { } #[allow(missing_docs)] + #[inline] pub fn borrow_mut(&self) { if self .state @@ -161,6 +164,7 @@ impl Archetype { } #[allow(missing_docs)] + #[inline] pub fn release(&self) { if let Some(x) = self.state.get(&TypeId::of::()) { x.borrow.release(); @@ -168,6 +172,7 @@ impl Archetype { } #[allow(missing_docs)] + #[inline] pub fn release_mut(&self) { if let Some(x) = self.state.get(&TypeId::of::()) { x.borrow.release_mut(); @@ -175,6 +180,7 @@ impl Archetype { } #[allow(missing_docs)] + #[inline] pub fn len(&self) -> u32 { self.len } @@ -184,6 +190,7 @@ impl Archetype { self.entities.iter().take(self.len as usize) } + #[inline] pub(crate) fn entities(&self) -> NonNull { unsafe { NonNull::new_unchecked(self.entities.as_ptr() as *mut _) } } @@ -436,11 +443,13 @@ impl TypeInfo { } #[allow(missing_docs)] + #[inline] pub fn id(&self) -> TypeId { self.id } #[allow(missing_docs)] + #[inline] pub fn layout(&self) -> Layout { self.layout } diff --git a/crates/bevy_ecs/hecs/src/query.rs b/crates/bevy_ecs/hecs/src/query.rs index d02401f75e..21e1029bc1 100644 --- a/crates/bevy_ecs/hecs/src/query.rs +++ b/crates/bevy_ecs/hecs/src/query.rs @@ -125,7 +125,6 @@ impl<'a, T: Component> Fetch<'a> for FetchRead { fn borrow(archetype: &Archetype) { archetype.borrow::(); } - #[inline] unsafe fn get(archetype: &'a Archetype, offset: usize) -> Option { archetype .get::() @@ -151,6 +150,135 @@ impl Query for Option { type Fetch = TryFetch; } + +/// Unique borrow of an entity's component +pub struct Mut<'a, T: Component> { + value: &'a mut T, + modified: &'a mut bool, +} + +unsafe impl Send for Mut<'_, T> {} +unsafe impl Sync for Mut<'_, T> {} + +impl<'a, T: Component> Deref for Mut<'a, T> { + type Target = T; + #[inline] + fn deref(&self) -> &T { + self.value + } +} + +impl<'a, T: Component> DerefMut for Mut<'a, T> { + #[inline] + fn deref_mut(&mut self) -> &mut T { + *self.modified = true; + self.value + } +} + +impl<'a, T: Component> Query for Mut<'a, T> { + type Fetch = FetchMut; +} +#[doc(hidden)] +pub struct FetchMut(NonNull, NonNull); + +impl<'a, T: Component> Fetch<'a> for FetchMut { + type Item = Mut<'a, T>; + + fn access(archetype: &Archetype) -> Option { + if archetype.has::() { + Some(Access::Write) + } else { + None + } + } + + fn borrow(archetype: &Archetype) { + archetype.borrow_mut::(); + } + unsafe fn get(archetype: &'a Archetype, offset: usize) -> Option { + archetype + .get_with_modified::() + .map(|(components, modified)| { + Self( + NonNull::new_unchecked(components.as_ptr().add(offset)), + NonNull::new_unchecked(modified.as_ptr().add(offset)), + ) + }) + } + fn release(archetype: &Archetype) { + archetype.release_mut::(); + } + + #[inline] + unsafe fn next(&mut self) -> Mut<'a, T> { + let component = self.0.as_ptr(); + let modified = self.1.as_ptr(); + self.0 = NonNull::new_unchecked(component.add(1)); + self.1 = NonNull::new_unchecked(modified.add(1)); + Mut { + value: &mut *component, + modified: &mut *modified, + } + } +} + +#[allow(missing_docs)] +pub struct Changed<'a, T> { + value: &'a T, +} + +impl<'a, T: Component> Deref for Changed<'a, T> { + type Target = T; + fn deref(&self) -> &T { + self.value + } +} + +impl<'a, T: Component> Query for Changed<'a, T> { + type Fetch = FetchChanged; +} + +#[doc(hidden)] +pub struct FetchChanged(NonNull, NonNull); + +impl<'a, T: Component> Fetch<'a> for FetchChanged { + type Item = Changed<'a, T>; + + fn access(archetype: &Archetype) -> Option { + if archetype.has::() { + Some(Access::Read) + } else { + None + } + } + + fn borrow(archetype: &Archetype) { + archetype.borrow::(); + } + unsafe fn get(archetype: &'a Archetype, offset: usize) -> Option { + let components = NonNull::new_unchecked(archetype.get::()?.as_ptr().add(offset)); + let modified = NonNull::new_unchecked(archetype.get_modified::()?.as_ptr().add(offset)); + Some(Self(components, modified)) + } + fn release(archetype: &Archetype) { + archetype.release::(); + } + + unsafe fn should_skip(&self) -> bool { + // skip if the current item wasn't changed + !*self.1.as_ref() + } + + #[inline] + unsafe fn next(&mut self) -> Self::Item { + self.1 = NonNull::new_unchecked(self.1.as_ptr().add(1)); + let value = self.0.as_ptr(); + self.0 = NonNull::new_unchecked(value.add(1)); + Changed { value: &*value } + } +} + #[doc(hidden)] pub struct TryFetch(Option); @@ -636,131 +764,6 @@ macro_rules! tuple_impl { //smaller_tuples_too!(tuple_impl, B, A); smaller_tuples_too!(tuple_impl, O, N, M, L, K, J, I, H, G, F, E, D, C, B, A); -/// Unique borrow of an entity's component -pub struct Mut<'a, T: Component> { - value: &'a mut T, - modified: &'a mut bool, -} - -unsafe impl Send for Mut<'_, T> {} -unsafe impl Sync for Mut<'_, T> {} - -impl<'a, T: Component> Deref for Mut<'a, T> { - type Target = T; - fn deref(&self) -> &T { - self.value - } -} - -impl<'a, T: Component> DerefMut for Mut<'a, T> { - fn deref_mut(&mut self) -> &mut T { - *self.modified = true; - self.value - } -} - -impl<'a, T: Component> Query for Mut<'a, T> { - type Fetch = FetchMut; -} -#[doc(hidden)] -pub struct FetchMut(NonNull, NonNull); - -impl<'a, T: Component> Fetch<'a> for FetchMut { - type Item = Mut<'a, T>; - - fn access(archetype: &Archetype) -> Option { - if archetype.has::() { - Some(Access::Write) - } else { - None - } - } - - fn borrow(archetype: &Archetype) { - archetype.borrow_mut::(); - } - unsafe fn get(archetype: &'a Archetype, offset: usize) -> Option { - archetype - .get_with_modified::() - .map(|(components, modified)| { - Self( - NonNull::new_unchecked(components.as_ptr().add(offset)), - NonNull::new_unchecked(modified.as_ptr().add(offset)), - ) - }) - } - fn release(archetype: &Archetype) { - archetype.release_mut::(); - } - - unsafe fn next(&mut self) -> Mut<'a, T> { - let component = self.0.as_ptr(); - let modified = self.1.as_ptr(); - self.0 = NonNull::new_unchecked(component.add(1)); - self.1 = NonNull::new_unchecked(modified.add(1)); - Mut { - value: &mut *component, - modified: &mut *modified, - } - } -} - -#[allow(missing_docs)] -pub struct Changed<'a, T> { - value: &'a T, -} - -impl<'a, T: Component> Deref for Changed<'a, T> { - type Target = T; - fn deref(&self) -> &T { - self.value - } -} - -impl<'a, T: Component> Query for Changed<'a, T> { - type Fetch = FetchChanged; -} - -#[doc(hidden)] -pub struct FetchChanged(NonNull, NonNull); - -impl<'a, T: Component> Fetch<'a> for FetchChanged { - type Item = Changed<'a, T>; - - fn access(archetype: &Archetype) -> Option { - if archetype.has::() { - Some(Access::Read) - } else { - None - } - } - - fn borrow(archetype: &Archetype) { - archetype.borrow::(); - } - unsafe fn get(archetype: &'a Archetype, offset: usize) -> Option { - let components = NonNull::new_unchecked(archetype.get::()?.as_ptr().add(offset)); - let modified = NonNull::new_unchecked(archetype.get_modified::()?.as_ptr().add(offset)); - Some(Self(components, modified)) - } - fn release(archetype: &Archetype) { - archetype.release::(); - } - - unsafe fn should_skip(&self) -> bool { - // skip if the current item wasn't changed - !*self.1.as_ref() - } - - #[inline] - unsafe fn next(&mut self) -> Self::Item { - self.1 = NonNull::new_unchecked(self.1.as_ptr().add(1)); - let value = self.0.as_ptr(); - self.0 = NonNull::new_unchecked(value.add(1)); - Changed { value: &*value } - } -} - #[cfg(test)] mod tests { use crate::{Changed, Entity, Mut, World};