Skip to content

Commit

Permalink
Update the safety comments
Browse files Browse the repository at this point in the history
  • Loading branch information
james7132 committed Nov 30, 2022
1 parent 46c138a commit 6e06d97
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 12 deletions.
63 changes: 52 additions & 11 deletions crates/bevy_ecs/src/world/entity_ref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,10 @@ impl<'w> EntityRef<'w> {

#[inline]
pub fn get<T: Component>(&self) -> Option<&'w T> {
// SAFETY: entity location is valid and returned component is of type T
// SAFETY:
// - entity location and entity is valid
// - returned component is of type T
// - the storage type provided is correct for T
unsafe {
get_component_with_type(
self.world,
Expand All @@ -87,7 +90,9 @@ impl<'w> EntityRef<'w> {
/// detection in custom runtimes.
#[inline]
pub fn get_change_ticks<T: Component>(&self) -> Option<ComponentTicks> {
// SAFETY: entity location is valid
// SAFETY:
// - entity location and entity is valid
// - the storage type provided is correct for T
unsafe {
get_ticks_with_type(
self.world,
Expand Down Expand Up @@ -115,6 +120,10 @@ impl<'w> EntityRef<'w> {
last_change_tick: u32,
change_tick: u32,
) -> Option<Mut<'w, T>> {
// SAFETY:
// - entity location and entity is valid
// - returned component is of type T
// - the storage type provided is correct for T
get_component_and_ticks_with_type(
self.world,
TypeId::of::<T>(),
Expand All @@ -141,7 +150,10 @@ impl<'w> EntityRef<'w> {
#[inline]
pub fn get_by_id(&self, component_id: ComponentId) -> Option<Ptr<'w>> {
let info = self.world.components().get_info(component_id)?;
// SAFETY: entity_location is valid, component_id is valid as checked by the line above
// SAFETY:
// - entity_location is valid,
// - component_id is valid as checked by the line above
// - the storage type is accurate as checked by the fetched ComponentInfo
unsafe {
get_component(
self.world,
Expand Down Expand Up @@ -216,7 +228,11 @@ impl<'w> EntityMut<'w> {

#[inline]
pub fn get<T: Component>(&self) -> Option<&'_ T> {
// SAFETY: lifetimes enforce correct usage of returned borrow
// SAFETY:
// - lifetimes enforce correct usage of returned borrow
// - entity location and entity is valid
// - returned component is of type T
// - the storage type provided is correct for T
unsafe {
get_component_with_type(
self.world,
Expand All @@ -239,7 +255,9 @@ impl<'w> EntityMut<'w> {
/// detection in custom runtimes.
#[inline]
pub fn get_change_ticks<T: Component>(&self) -> Option<ComponentTicks> {
// SAFETY: entity location is valid
// SAFETY:
// - entity location and entity is valid
// - the storage type provided is correct for T
unsafe {
get_ticks_with_type(
self.world,
Expand All @@ -263,6 +281,10 @@ impl<'w> EntityMut<'w> {
/// operation on this world (non-exhaustive list).
#[inline]
pub unsafe fn get_unchecked_mut<T: Component>(&self) -> Option<Mut<'_, T>> {
// SAFETY:
// - entity location and entity is valid
// - returned component is of type T
// - the storage type provided is correct for T
get_component_and_ticks_with_type(
self.world,
TypeId::of::<T>(),
Expand Down Expand Up @@ -617,7 +639,10 @@ impl<'w> EntityMut<'w> {
#[inline]
pub fn get_by_id(&self, component_id: ComponentId) -> Option<Ptr<'_>> {
let info = self.world.components().get_info(component_id)?;
// SAFETY: entity_location is valid, component_id is valid as checked by the line above
// SAFETY:
// - entity_location is valid
// - component_id is valid as checked by the line above
// - the storage type is accurate as checked by the fetched ComponentInfo
unsafe {
get_component(
self.world,
Expand Down Expand Up @@ -670,6 +695,7 @@ fn fetch_sparse_set(world: &World, component_id: ComponentId) -> Option<&Compone
/// - `entity_location` must be within bounds of the given archetype and `entity` must exist inside
/// the archetype
/// - `component_id` must be valid
/// - `storage_type` must accurately reflect where the components for `component_id` are stored.
#[inline]
pub(crate) unsafe fn get_component(
world: &World,
Expand All @@ -692,7 +718,10 @@ pub(crate) unsafe fn get_component(
/// Get a raw pointer to the [`ComponentTicks`] of a particular [`Component`] on a particular [`Entity`] in the provided [World].
///
/// # Safety
/// Caller must ensure that `component_id` is valid
/// - `entity_location` must be within bounds of the given archetype and `entity` must exist inside
/// the archetype
/// - `component_id` must be valid
/// - `storage_type` must accurately reflect where the components for `component_id` are stored.
#[inline]
unsafe fn get_component_and_ticks(
world: &World,
Expand All @@ -718,7 +747,10 @@ unsafe fn get_component_and_ticks(
}

/// # Safety
/// `entity_location` must be within bounds of an archetype that exists.
/// - `entity_location` must be within bounds of the given archetype and `entity` must exist inside
/// the archetype
/// - `component_id` must be valid
/// - `storage_type` must accurately reflect where the components for `component_id` are stored.
unsafe fn get_ticks(
world: &World,
component_id: ComponentId,
Expand Down Expand Up @@ -781,7 +813,10 @@ unsafe fn take_component<'a>(
/// Get a raw pointer to a particular [`Component`] by [`TypeId`] on a particular [`Entity`] in the provided [`World`].
///
/// # Safety
/// `entity_location` must be within bounds of an archetype that exists.
/// - `entity_location` must be within bounds of the given archetype and `entity` must exist inside
/// the archetype
/// - `type_id` must be correspond to a type that implements [`Component`]
/// - `storage_type` must accurately reflect where the components for `component_id` are stored.
#[inline]
unsafe fn get_component_with_type(
world: &World,
Expand All @@ -802,7 +837,10 @@ unsafe fn get_component_with_type(
/// Get a raw pointer to the [`ComponentTicks`] of a particular [`Component`] by [`TypeId`] on a particular [`Entity`] in the provided [`World`].
///
/// # Safety
/// `entity_location` must be within bounds of an archetype that exists.
/// - `entity_location` must be within bounds of the given archetype and `entity` must exist inside
/// the archetype
/// - `type_id` must be correspond to a type that implements [`Component`]
/// - `storage_type` must accurately reflect where the components for `component_id` are stored.
#[inline]
unsafe fn get_component_and_ticks_with_type(
world: &World,
Expand All @@ -821,7 +859,10 @@ unsafe fn get_component_and_ticks_with_type(
}

/// # Safety
/// `entity_location` must be within bounds of an archetype that exists.
/// - `entity_location` must be within bounds of the given archetype and `entity` must exist inside
/// the archetype
/// - `type_id` must be correspond to a type that implements [`Component`]
/// - `storage_type` must accurately reflect where the components for `component_id` are stored.
#[inline]
unsafe fn get_ticks_with_type(
world: &World,
Expand Down
5 changes: 4 additions & 1 deletion crates/bevy_ecs/src/world/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1491,7 +1491,10 @@ impl World {
#[inline]
pub fn get_by_id(&self, entity: Entity, component_id: ComponentId) -> Option<Ptr<'_>> {
let info = self.components().get_info(component_id)?;
// SAFETY: entity_location is valid, component_id is valid as checked by the line above
// SAFETY:
// - entity_location is valid
// - component_id is valid as checked by the line above
// - the storage type is accurate as checked by the fetched ComponentInfo
unsafe {
get_component(
self,
Expand Down

0 comments on commit 6e06d97

Please sign in to comment.