Skip to content
Open
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
9 changes: 6 additions & 3 deletions crates/bevy_ecs/src/entity/clone_entities.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use crate::{
entity::{hash_map::EntityHashMap, Entity, EntityAllocator, EntityMapper},
query::DebugCheckedUnwrap,
relationship::RelationshipHookMode,
world::World,
world::{All, World},
};
use alloc::{boxed::Box, collections::VecDeque, vec::Vec};
use bevy_platform::collections::{hash_map::Entry, HashMap, HashSet};
Expand Down Expand Up @@ -633,8 +633,11 @@ impl EntityCloner {
// SAFETY:
// - There are no other mutable references to source entity.
// - `component` is from `source_entity`'s archetype
let source_component_ptr =
unsafe { source_entity.get_by_id(component).debug_checked_unwrap() };
let source_component_ptr = unsafe {
source_entity
.get_by_id(All, component)
.debug_checked_unwrap()
};

let source_component = SourceComponent {
info,
Expand Down
8 changes: 6 additions & 2 deletions crates/bevy_ecs/src/observer/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::{
prelude::*,
query::DebugCheckedUnwrap,
system::{ObserverSystem, RunSystemError},
world::DeferredWorld,
world::{All, DeferredWorld},
};
use bevy_ptr::PtrMut;

Expand Down Expand Up @@ -44,7 +44,11 @@ pub(super) unsafe fn observer_system_runner<E: Event, B: Bundle, S: ObserverSyst
// SAFETY: Observer was triggered so must still exist in world
let observer_cell = unsafe { world.get_entity(observer).debug_checked_unwrap() };
// SAFETY: Observer was triggered so must have an `Observer`
let mut state = unsafe { observer_cell.get_mut::<Observer>().debug_checked_unwrap() };
let mut state = unsafe {
observer_cell
.get_mut::<Observer>(All)
.debug_checked_unwrap()
};

// TODO: Move this check into the observer cache to avoid dynamic dispatch
let last_trigger = world.last_trigger_id();
Expand Down
31 changes: 17 additions & 14 deletions crates/bevy_ecs/src/query/fetch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ use crate::{
},
storage::{ComponentSparseSet, Table, TableRow},
world::{
unsafe_world_cell::UnsafeWorldCell, EntityMut, EntityMutExcept, EntityRef, EntityRefExcept,
FilteredEntityMut, FilteredEntityRef, Mut, Ref, World,
unsafe_world_cell::UnsafeWorldCell, All, EntityMut, EntityMutExcept, EntityRef,
EntityRefExcept, Except, Filtered, FilteredEntityMut, FilteredEntityRef, Mut, Ref, World,
},
};
use bevy_ptr::{ThinSlicePtr, UnsafeCellDeref};
Expand Down Expand Up @@ -366,10 +366,11 @@ pub type ROQueryItem<'w, 's, D> = QueryItem<'w, 's, <D as QueryData>::ReadOnly>;

/// A [`QueryData`] that does not borrow from its [`QueryState`](crate::query::QueryState).
///
/// This is implemented by most `QueryData` types.
/// The main exceptions are [`FilteredEntityRef`], [`FilteredEntityMut`], [`EntityRefExcept`], and [`EntityMutExcept`],
/// which borrow an access list from their query state.
/// Consider using a full [`EntityRef`] or [`EntityMut`] if you would need those.
/// This is implemented by most `QueryData` types. The main exceptions are
/// [`FilteredEntityRef`], [`FilteredEntityMut`], [`EntityRefExcept`], and
/// [`EntityMutExcept`], which borrow an access list from their query state.
/// Consider using a full [`EntityRef<All>`] or [`EntityMut<All>`] if you would
/// need those.
pub trait ReleaseStateQueryData: QueryData {
/// Releases the borrow from the query state by converting an item to have a `'static` state lifetime.
fn release_state<'w>(item: Self::Item<'w, '_>) -> Self::Item<'w, 'static>;
Expand Down Expand Up @@ -856,7 +857,7 @@ unsafe impl<'a> QueryData for EntityRef<'a> {
.debug_checked_unwrap()
};
// SAFETY: Read-only access to every component has been registered.
Some(unsafe { EntityRef::new(cell) })
Some(unsafe { EntityRef::new(cell, All) })
}

fn iter_access(_state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
Expand Down Expand Up @@ -966,7 +967,7 @@ unsafe impl<'a> QueryData for EntityMut<'a> {
.debug_checked_unwrap()
};
// SAFETY: mutable access to every component has been registered.
Some(unsafe { EntityMut::new(cell) })
Some(unsafe { EntityMut::new(cell, All) })
}

fn iter_access(_state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
Expand Down Expand Up @@ -1093,8 +1094,8 @@ unsafe impl<'a, 'b> QueryData for FilteredEntityRef<'a, 'b> {
.get_entity_with_ticks(entity, fetch.last_run, fetch.this_run)
.debug_checked_unwrap()
};
// SAFETY: mutable access to every component has been registered.
Some(unsafe { FilteredEntityRef::new(cell, access) })
// SAFETY: read-only access to the components in `access` has been registered.
Some(unsafe { EntityRef::new(cell, Filtered(access)) })
}

fn iter_access(state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
Expand Down Expand Up @@ -1216,8 +1217,8 @@ unsafe impl<'a, 'b> QueryData for FilteredEntityMut<'a, 'b> {
.get_entity_with_ticks(entity, fetch.last_run, fetch.this_run)
.debug_checked_unwrap()
};
// SAFETY: mutable access to every component has been registered.
Some(unsafe { FilteredEntityMut::new(cell, access) })
// SAFETY: mutable access to the components in `access` has been registered.
Some(unsafe { EntityMut::new(cell, Filtered(access)) })
}

fn iter_access(state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
Expand Down Expand Up @@ -1331,7 +1332,8 @@ where
.world
.get_entity_with_ticks(entity, fetch.last_run, fetch.this_run)
.unwrap();
Some(EntityRefExcept::new(cell, access))
// SAFETY: `access` was constructed based on the components in `B`, and read-only access registered.
Some(unsafe { EntityRef::new(cell, Except::new(access)) })
}

fn iter_access(state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
Expand Down Expand Up @@ -1450,7 +1452,8 @@ where
.world
.get_entity_with_ticks(entity, fetch.last_run, fetch.this_run)
.unwrap();
Some(EntityMutExcept::new(cell, access))
// SAFETY: `access` was constructed based on the components in `B`, and mutable access registered.
Some(unsafe { EntityMut::new(cell, Except::new(access)) })
}

fn iter_access(state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
Expand Down
4 changes: 2 additions & 2 deletions crates/bevy_ecs/src/reflect/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ use crate::{
prelude::Component,
relationship::RelationshipHookMode,
world::{
unsafe_world_cell::UnsafeEntityCell, EntityMut, EntityWorldMut, FilteredEntityMut,
unsafe_world_cell::UnsafeEntityCell, All, EntityMut, EntityWorldMut, FilteredEntityMut,
FilteredEntityRef, World,
},
};
Expand Down Expand Up @@ -383,7 +383,7 @@ impl<C: Component + Reflect + TypePath> FromType<C> for ReflectComponent {
// SAFETY: reflect_unchecked_mut is an unsafe function pointer used by
// `reflect_unchecked_mut` which must be called with an UnsafeEntityCell with access to the component `C` on the `entity`
// guard ensures `C` is a mutable component
let c = unsafe { entity.get_mut_assume_mutable::<C>() };
let c = unsafe { entity.get_mut_assume_mutable::<C>(All) };
c.map(|c| c.map_unchanged(|value| value as &mut dyn Reflect))
},
register_component: |world: &mut World| -> ComponentId {
Expand Down
Loading