From 0c81961d6951ea7eadcc440429327ffa574d319a Mon Sep 17 00:00:00 2001 From: sQu1rr Date: Fri, 18 Nov 2022 18:03:32 +0000 Subject: [PATCH 1/5] Adds get_change_ticks_by_id for EntityRef Also adds get_change_ticks_by_id for EntityMut --- crates/bevy_ecs/src/world/entity_ref.rs | 30 +++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/crates/bevy_ecs/src/world/entity_ref.rs b/crates/bevy_ecs/src/world/entity_ref.rs index 37bf71adad1cd..822a150493bf6 100644 --- a/crates/bevy_ecs/src/world/entity_ref.rs +++ b/crates/bevy_ecs/src/world/entity_ref.rs @@ -82,6 +82,21 @@ impl<'w> EntityRef<'w> { unsafe { get_ticks_with_type(self.world, TypeId::of::(), self.entity, self.location) } } + /// Retrieves the change ticks for the given [`ComponentId`]. This can be useful for implementing change + /// detection in custom runtimes. + /// + /// **You should prefer to use the typed API where possible and only + /// use this in cases where the actual component types are not known at + /// compile time.** + #[inline] + pub fn get_change_ticks_by_id(&self, component_id: ComponentId) -> Option<&'w ComponentTicks> { + // SAFETY: entity location is valid + unsafe { + get_ticks(self.world, component_id, self.entity, self.location) + .map(|ticks| ticks.deref()) + } + } + /// Gets a mutable reference to the component of type `T` associated with /// this entity without ensuring there are no other borrows active and without /// ensuring that the returned reference will stay valid. @@ -206,6 +221,21 @@ impl<'w> EntityMut<'w> { unsafe { get_ticks_with_type(self.world, TypeId::of::(), self.entity, self.location) } } + /// Retrieves the change ticks for the given [`ComponentId`]. This can be useful for implementing change + /// detection in custom runtimes. + /// + /// **You should prefer to use the typed API where possible and only + /// use this in cases where the actual component types are not known at + /// compile time.** + #[inline] + pub fn get_change_ticks_by_id(&self, component_id: ComponentId) -> Option<&ComponentTicks> { + // SAFETY: entity location is valid + unsafe { + get_ticks(self.world, component_id, self.entity, self.location) + .map(|ticks| ticks.deref()) + } + } + /// Gets a mutable reference to the component of type `T` associated with /// this entity without ensuring there are no other borrows active and without /// ensuring that the returned reference will stay valid. From e8752b41d91d6d63592aea9b9f8814f8ea81ea8d Mon Sep 17 00:00:00 2001 From: sQu1rr Date: Sun, 20 Nov 2022 18:04:40 +0000 Subject: [PATCH 2/5] EntityRef::get_change_ticks_by_id safety EntityRef::get_change_ticks_by_id and EntityMut::get_change_ticks_by_id will now validate component_id and return None if it is invalid. --- crates/bevy_ecs/src/world/entity_ref.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/crates/bevy_ecs/src/world/entity_ref.rs b/crates/bevy_ecs/src/world/entity_ref.rs index 822a150493bf6..d9eba0505370d 100644 --- a/crates/bevy_ecs/src/world/entity_ref.rs +++ b/crates/bevy_ecs/src/world/entity_ref.rs @@ -90,7 +90,11 @@ impl<'w> EntityRef<'w> { /// compile time.** #[inline] pub fn get_change_ticks_by_id(&self, component_id: ComponentId) -> Option<&'w ComponentTicks> { - // SAFETY: entity location is valid + if !self.contains_id(component_id) { + return None; + } + + // SAFETY: entity location is valid and component_id exists unsafe { get_ticks(self.world, component_id, self.entity, self.location) .map(|ticks| ticks.deref()) @@ -229,7 +233,11 @@ impl<'w> EntityMut<'w> { /// compile time.** #[inline] pub fn get_change_ticks_by_id(&self, component_id: ComponentId) -> Option<&ComponentTicks> { - // SAFETY: entity location is valid + if !self.contains_id(component_id) { + return None; + } + + // SAFETY: entity location is valid and component_id exists unsafe { get_ticks(self.world, component_id, self.entity, self.location) .map(|ticks| ticks.deref()) From 22d4652b05e147f9e2f89d96a52128cf037c0e22 Mon Sep 17 00:00:00 2001 From: Aleksandr Belkin Date: Thu, 24 Nov 2022 15:51:46 +0000 Subject: [PATCH 3/5] Improve EntityRef::get_change_ticks_by_id docs as suggested by jakobhellermann from code review Co-authored-by: Jakob Hellermann --- crates/bevy_ecs/src/world/entity_ref.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/bevy_ecs/src/world/entity_ref.rs b/crates/bevy_ecs/src/world/entity_ref.rs index d9eba0505370d..19c4915b8e124 100644 --- a/crates/bevy_ecs/src/world/entity_ref.rs +++ b/crates/bevy_ecs/src/world/entity_ref.rs @@ -85,7 +85,7 @@ impl<'w> EntityRef<'w> { /// Retrieves the change ticks for the given [`ComponentId`]. This can be useful for implementing change /// detection in custom runtimes. /// - /// **You should prefer to use the typed API where possible and only + /// **You should prefer to use the typed API [`EntityRef::get_change_ticks`] where possible and only /// use this in cases where the actual component types are not known at /// compile time.** #[inline] @@ -228,7 +228,7 @@ impl<'w> EntityMut<'w> { /// Retrieves the change ticks for the given [`ComponentId`]. This can be useful for implementing change /// detection in custom runtimes. /// - /// **You should prefer to use the typed API where possible and only + /// **You should prefer to use the typed API [`EntityMut::get_change_ticks`] where possible and only /// use this in cases where the actual component types are not known at /// compile time.** #[inline] From 85e108829bad030ea0f36ed8ef1a1db16e7c0f95 Mon Sep 17 00:00:00 2001 From: sQu1rr Date: Thu, 24 Nov 2022 16:16:29 +0000 Subject: [PATCH 4/5] Updated EntityRef::get_change_ticks_by_id branch with upstream --- crates/bevy_ecs/src/world/entity_ref.rs | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/crates/bevy_ecs/src/world/entity_ref.rs b/crates/bevy_ecs/src/world/entity_ref.rs index 19c4915b8e124..4ab385ccd8e46 100644 --- a/crates/bevy_ecs/src/world/entity_ref.rs +++ b/crates/bevy_ecs/src/world/entity_ref.rs @@ -89,16 +89,13 @@ impl<'w> EntityRef<'w> { /// use this in cases where the actual component types are not known at /// compile time.** #[inline] - pub fn get_change_ticks_by_id(&self, component_id: ComponentId) -> Option<&'w ComponentTicks> { + pub fn get_change_ticks_by_id(&self, component_id: ComponentId) -> Option { if !self.contains_id(component_id) { return None; } // SAFETY: entity location is valid and component_id exists - unsafe { - get_ticks(self.world, component_id, self.entity, self.location) - .map(|ticks| ticks.deref()) - } + unsafe { get_ticks(self.world, component_id, self.entity, self.location) } } /// Gets a mutable reference to the component of type `T` associated with @@ -232,16 +229,13 @@ impl<'w> EntityMut<'w> { /// use this in cases where the actual component types are not known at /// compile time.** #[inline] - pub fn get_change_ticks_by_id(&self, component_id: ComponentId) -> Option<&ComponentTicks> { + pub fn get_change_ticks_by_id(&self, component_id: ComponentId) -> Option { if !self.contains_id(component_id) { return None; } // SAFETY: entity location is valid and component_id exists - unsafe { - get_ticks(self.world, component_id, self.entity, self.location) - .map(|ticks| ticks.deref()) - } + unsafe { get_ticks(self.world, component_id, self.entity, self.location) } } /// Gets a mutable reference to the component of type `T` associated with From 3853a314572353117e49f22a84fb99192736724d Mon Sep 17 00:00:00 2001 From: Aleksandr Belkin Date: Sat, 26 Nov 2022 19:02:46 +0000 Subject: [PATCH 5/5] EntityRef:ge_change_ticks_by_id docs improvement Apply suggestions from code review by JoJoJet Co-authored-by: JoJoJet <21144246+JoJoJet@users.noreply.github.com> --- crates/bevy_ecs/src/world/entity_ref.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/bevy_ecs/src/world/entity_ref.rs b/crates/bevy_ecs/src/world/entity_ref.rs index 4ab385ccd8e46..e027ea64364d2 100644 --- a/crates/bevy_ecs/src/world/entity_ref.rs +++ b/crates/bevy_ecs/src/world/entity_ref.rs @@ -94,7 +94,7 @@ impl<'w> EntityRef<'w> { return None; } - // SAFETY: entity location is valid and component_id exists + // SAFETY: Entity location is valid and component_id exists. unsafe { get_ticks(self.world, component_id, self.entity, self.location) } } @@ -234,7 +234,7 @@ impl<'w> EntityMut<'w> { return None; } - // SAFETY: entity location is valid and component_id exists + // SAFETY: Entity location is valid and component_id exists. unsafe { get_ticks(self.world, component_id, self.entity, self.location) } }