Skip to content

Commit 7e062b0

Browse files
committed
EntityRef/EntityMut scopes
1 parent 637948b commit 7e062b0

19 files changed

Lines changed: 1121 additions & 1674 deletions

File tree

crates/bevy_ecs/src/entity/clone_entities.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use crate::{
1111
entity::{hash_map::EntityHashMap, Entity, EntityAllocator, EntityMapper},
1212
query::DebugCheckedUnwrap,
1313
relationship::RelationshipHookMode,
14-
world::World,
14+
world::{All, World},
1515
};
1616
use alloc::{boxed::Box, collections::VecDeque, vec::Vec};
1717
use bevy_platform::collections::{hash_map::Entry, HashMap, HashSet};
@@ -633,8 +633,11 @@ impl EntityCloner {
633633
// SAFETY:
634634
// - There are no other mutable references to source entity.
635635
// - `component` is from `source_entity`'s archetype
636-
let source_component_ptr =
637-
unsafe { source_entity.get_by_id(component).debug_checked_unwrap() };
636+
let source_component_ptr = unsafe {
637+
source_entity
638+
.get_by_id(&All, component)
639+
.debug_checked_unwrap()
640+
};
638641

639642
let source_component = SourceComponent {
640643
info,

crates/bevy_ecs/src/observer/runner.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use crate::{
99
prelude::*,
1010
query::DebugCheckedUnwrap,
1111
system::{ObserverSystem, RunSystemError},
12-
world::DeferredWorld,
12+
world::{All, DeferredWorld},
1313
};
1414
use bevy_ptr::PtrMut;
1515

@@ -44,7 +44,11 @@ pub(super) unsafe fn observer_system_runner<E: Event, B: Bundle, S: ObserverSyst
4444
// SAFETY: Observer was triggered so must still exist in world
4545
let observer_cell = unsafe { world.get_entity(observer).debug_checked_unwrap() };
4646
// SAFETY: Observer was triggered so must have an `Observer`
47-
let mut state = unsafe { observer_cell.get_mut::<Observer>().debug_checked_unwrap() };
47+
let mut state = unsafe {
48+
observer_cell
49+
.get_mut::<Observer>(&All)
50+
.debug_checked_unwrap()
51+
};
4852

4953
// TODO: Move this check into the observer cache to avoid dynamic dispatch
5054
let last_trigger = world.last_trigger_id();

crates/bevy_ecs/src/query/fetch.rs

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ use crate::{
1010
},
1111
storage::{ComponentSparseSet, Table, TableRow},
1212
world::{
13-
unsafe_world_cell::UnsafeWorldCell, EntityMut, EntityMutExcept, EntityRef, EntityRefExcept,
14-
FilteredEntityMut, FilteredEntityRef, Mut, Ref, World,
13+
unsafe_world_cell::UnsafeWorldCell, All, EntityMut, EntityMutExcept, EntityRef,
14+
EntityRefExcept, Except, Filtered, FilteredEntityMut, FilteredEntityRef, Mut, Ref, World,
1515
},
1616
};
1717
use bevy_ptr::{ThinSlicePtr, UnsafeCellDeref};
@@ -366,10 +366,11 @@ pub type ROQueryItem<'w, 's, D> = QueryItem<'w, 's, <D as QueryData>::ReadOnly>;
366366

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

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

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

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

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

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

14561459
fn iter_access(state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {

crates/bevy_ecs/src/reflect/component.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ use crate::{
6565
prelude::Component,
6666
relationship::RelationshipHookMode,
6767
world::{
68-
unsafe_world_cell::UnsafeEntityCell, EntityMut, EntityWorldMut, FilteredEntityMut,
68+
unsafe_world_cell::UnsafeEntityCell, All, EntityMut, EntityWorldMut, FilteredEntityMut,
6969
FilteredEntityRef, World,
7070
},
7171
};
@@ -383,7 +383,7 @@ impl<C: Component + Reflect + TypePath> FromType<C> for ReflectComponent {
383383
// SAFETY: reflect_unchecked_mut is an unsafe function pointer used by
384384
// `reflect_unchecked_mut` which must be called with an UnsafeEntityCell with access to the component `C` on the `entity`
385385
// guard ensures `C` is a mutable component
386-
let c = unsafe { entity.get_mut_assume_mutable::<C>() };
386+
let c = unsafe { entity.get_mut_assume_mutable::<C>(&All) };
387387
c.map(|c| c.map_unchanged(|value| value as &mut dyn Reflect))
388388
},
389389
register_component: |world: &mut World| -> ComponentId {

0 commit comments

Comments
 (0)