Skip to content

Commit f7606e9

Browse files
use UnsafeWorldCell for QueryState/Query
1 parent 989338a commit f7606e9

File tree

11 files changed

+205
-108
lines changed

11 files changed

+205
-108
lines changed

crates/bevy_ecs/macros/src/fetch.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ pub fn derive_world_query_impl(ast: DeriveInput) -> TokenStream {
220220
}
221221

222222
unsafe fn init_fetch<'__w>(
223-
_world: &'__w #path::world::World,
223+
_world: #path::world::unsafe_world_cell::UnsafeWorldCell<'__w>,
224224
state: &Self::State,
225225
_last_change_tick: u32,
226226
_change_tick: u32

crates/bevy_ecs/src/query/fetch.rs

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use crate::{
55
entity::Entity,
66
query::{Access, DebugCheckedUnwrap, FilteredAccess},
77
storage::{ComponentSparseSet, Table, TableRow},
8-
world::{Mut, Ref, World},
8+
world::{unsafe_world_cell::UnsafeWorldCell, Mut, Ref, World},
99
};
1010
use bevy_ecs_macros::all_tuples;
1111
pub use bevy_ecs_macros::WorldQuery;
@@ -328,10 +328,11 @@ pub unsafe trait WorldQuery {
328328
///
329329
/// # Safety
330330
///
331-
/// `state` must have been initialized (via [`WorldQuery::init_state`]) using the same `world` passed
331+
/// - `state` must have been initialized (via [`WorldQuery::init_state`]) using the same `world` passed
332332
/// in to this function.
333+
/// - `world` must be an `UnsafeWorldCell` with access to everything listed in `update_archetype_component_access`
333334
unsafe fn init_fetch<'w>(
334-
world: &'w World,
335+
world: UnsafeWorldCell<'w>,
335336
state: &Self::State,
336337
last_change_tick: u32,
337338
change_tick: u32,
@@ -462,7 +463,7 @@ unsafe impl WorldQuery for Entity {
462463
const IS_ARCHETYPAL: bool = true;
463464

464465
unsafe fn init_fetch<'w>(
465-
_world: &'w World,
466+
_world: UnsafeWorldCell<'w>,
466467
_state: &Self::State,
467468
_last_change_tick: u32,
468469
_change_tick: u32,
@@ -544,19 +545,23 @@ unsafe impl<T: Component> WorldQuery for &T {
544545
const IS_ARCHETYPAL: bool = true;
545546

546547
unsafe fn init_fetch<'w>(
547-
world: &'w World,
548+
world: UnsafeWorldCell<'w>,
548549
&component_id: &ComponentId,
549550
_last_change_tick: u32,
550551
_change_tick: u32,
551552
) -> ReadFetch<'w, T> {
552553
ReadFetch {
553554
table_components: None,
554555
sparse_set: (T::Storage::STORAGE_TYPE == StorageType::SparseSet).then(|| {
555-
world
556-
.storages()
557-
.sparse_sets
558-
.get(component_id)
559-
.debug_checked_unwrap()
556+
// SAFETY: TODO
557+
unsafe {
558+
world
559+
.world()
560+
.storages()
561+
.sparse_sets
562+
.get(component_id)
563+
.debug_checked_unwrap()
564+
}
560565
}),
561566
}
562567
}
@@ -689,19 +694,23 @@ unsafe impl<'__w, T: Component> WorldQuery for Ref<'__w, T> {
689694
const IS_ARCHETYPAL: bool = true;
690695

691696
unsafe fn init_fetch<'w>(
692-
world: &'w World,
697+
world: UnsafeWorldCell<'w>,
693698
&component_id: &ComponentId,
694699
last_change_tick: u32,
695700
change_tick: u32,
696701
) -> RefFetch<'w, T> {
697702
RefFetch {
698703
table_data: None,
699704
sparse_set: (T::Storage::STORAGE_TYPE == StorageType::SparseSet).then(|| {
700-
world
701-
.storages()
702-
.sparse_sets
703-
.get(component_id)
704-
.debug_checked_unwrap()
705+
// SAFETY: world has access to
706+
unsafe {
707+
world
708+
.world()
709+
.storages()
710+
.sparse_sets
711+
.get(component_id)
712+
.debug_checked_unwrap()
713+
}
705714
}),
706715
last_change_tick,
707716
change_tick,
@@ -850,7 +859,7 @@ unsafe impl<'__w, T: Component> WorldQuery for &'__w mut T {
850859
const IS_ARCHETYPAL: bool = true;
851860

852861
unsafe fn init_fetch<'w>(
853-
world: &'w World,
862+
world: UnsafeWorldCell<'w>,
854863
&component_id: &ComponentId,
855864
last_change_tick: u32,
856865
change_tick: u32,
@@ -859,6 +868,7 @@ unsafe impl<'__w, T: Component> WorldQuery for &'__w mut T {
859868
table_data: None,
860869
sparse_set: (T::Storage::STORAGE_TYPE == StorageType::SparseSet).then(|| {
861870
world
871+
.world()
862872
.storages()
863873
.sparse_sets
864874
.get(component_id)
@@ -998,7 +1008,7 @@ unsafe impl<T: WorldQuery> WorldQuery for Option<T> {
9981008
const IS_ARCHETYPAL: bool = T::IS_ARCHETYPAL;
9991009

10001010
unsafe fn init_fetch<'w>(
1001-
world: &'w World,
1011+
world: UnsafeWorldCell<'w>,
10021012
state: &T::State,
10031013
last_change_tick: u32,
10041014
change_tick: u32,
@@ -1192,7 +1202,7 @@ unsafe impl<T: Component> WorldQuery for ChangeTrackers<T> {
11921202
const IS_ARCHETYPAL: bool = true;
11931203

11941204
unsafe fn init_fetch<'w>(
1195-
world: &'w World,
1205+
world: UnsafeWorldCell<'w>,
11961206
&component_id: &ComponentId,
11971207
last_change_tick: u32,
11981208
change_tick: u32,
@@ -1339,7 +1349,7 @@ macro_rules! impl_tuple_fetch {
13391349
}
13401350

13411351
#[allow(clippy::unused_unit)]
1342-
unsafe fn init_fetch<'w>(_world: &'w World, state: &Self::State, _last_change_tick: u32, _change_tick: u32) -> Self::Fetch<'w> {
1352+
unsafe fn init_fetch<'w>(_world: UnsafeWorldCell<'w>, state: &Self::State, _last_change_tick: u32, _change_tick: u32) -> Self::Fetch<'w> {
13431353
let ($($name,)*) = state;
13441354
($($name::init_fetch(_world, $name, _last_change_tick, _change_tick),)*)
13451355
}
@@ -1448,7 +1458,7 @@ macro_rules! impl_anytuple_fetch {
14481458
}
14491459

14501460
#[allow(clippy::unused_unit)]
1451-
unsafe fn init_fetch<'w>(_world: &'w World, state: &Self::State, _last_change_tick: u32, _change_tick: u32) -> Self::Fetch<'w> {
1461+
unsafe fn init_fetch<'w>(_world: UnsafeWorldCell<'w>, state: &Self::State, _last_change_tick: u32, _change_tick: u32) -> Self::Fetch<'w> {
14521462
let ($($name,)*) = state;
14531463
($(($name::init_fetch(_world, $name, _last_change_tick, _change_tick), false),)*)
14541464
}
@@ -1587,7 +1597,7 @@ unsafe impl<Q: WorldQuery> WorldQuery for NopWorldQuery<Q> {
15871597

15881598
#[inline(always)]
15891599
unsafe fn init_fetch(
1590-
_world: &World,
1600+
_world: UnsafeWorldCell<'_>,
15911601
_state: &Q::State,
15921602
_last_change_tick: u32,
15931603
_change_tick: u32,

crates/bevy_ecs/src/query/filter.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::{
44
entity::Entity,
55
query::{Access, DebugCheckedUnwrap, FilteredAccess, WorldQuery},
66
storage::{Column, ComponentSparseSet, Table, TableRow},
7-
world::World,
7+
world::{unsafe_world_cell::UnsafeWorldCell, World},
88
};
99
use bevy_ecs_macros::all_tuples;
1010
use bevy_ptr::{ThinSlicePtr, UnsafeCellDeref};
@@ -51,7 +51,7 @@ unsafe impl<T: Component> WorldQuery for With<T> {
5151
fn shrink<'wlong: 'wshort, 'wshort>(_: Self::Item<'wlong>) -> Self::Item<'wshort> {}
5252

5353
unsafe fn init_fetch(
54-
_world: &World,
54+
_world: UnsafeWorldCell<'_>,
5555
_state: &ComponentId,
5656
_last_change_tick: u32,
5757
_change_tick: u32,
@@ -153,7 +153,7 @@ unsafe impl<T: Component> WorldQuery for Without<T> {
153153
fn shrink<'wlong: 'wshort, 'wshort>(_: Self::Item<'wlong>) -> Self::Item<'wshort> {}
154154

155155
unsafe fn init_fetch(
156-
_world: &World,
156+
_world: UnsafeWorldCell<'_>,
157157
_state: &ComponentId,
158158
_last_change_tick: u32,
159159
_change_tick: u32,
@@ -277,7 +277,7 @@ macro_rules! impl_query_filter_tuple {
277277

278278
const IS_ARCHETYPAL: bool = true $(&& $filter::IS_ARCHETYPAL)*;
279279

280-
unsafe fn init_fetch<'w>(world: &'w World, state: &Self::State, last_change_tick: u32, change_tick: u32) -> Self::Fetch<'w> {
280+
unsafe fn init_fetch<'w>(world: UnsafeWorldCell<'w>, state: &Self::State, last_change_tick: u32, change_tick: u32) -> Self::Fetch<'w> {
281281
let ($($filter,)*) = state;
282282
($(OrFetch {
283283
fetch: $filter::init_fetch(world, $filter, last_change_tick, change_tick),
@@ -432,7 +432,7 @@ macro_rules! impl_tick_filter {
432432
item
433433
}
434434

435-
unsafe fn init_fetch<'w>(world: &'w World, &id: &ComponentId, last_change_tick: u32, change_tick: u32) -> Self::Fetch<'w> {
435+
unsafe fn init_fetch<'w>(world: UnsafeWorldCell<'w>, &id: &ComponentId, last_change_tick: u32, change_tick: u32) -> Self::Fetch<'w> {
436436
Self::Fetch::<'w> {
437437
table_ticks: None,
438438
sparse_set: (T::Storage::STORAGE_TYPE == StorageType::SparseSet)

crates/bevy_ecs/src/query/iter.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
use crate::{
22
archetype::{ArchetypeEntity, ArchetypeId, Archetypes},
33
entity::{Entities, Entity},
4-
prelude::World,
54
query::{ArchetypeFilter, DebugCheckedUnwrap, QueryState, WorldQuery},
65
storage::{TableId, TableRow, Tables},
6+
world::unsafe_world_cell::UnsafeWorldCell,
77
};
88
use std::{borrow::Borrow, iter::FusedIterator, marker::PhantomData, mem::MaybeUninit};
99

@@ -27,15 +27,15 @@ impl<'w, 's, Q: WorldQuery, F: ReadOnlyWorldQuery> QueryIter<'w, 's, Q, F> {
2727
/// This does not validate that `world.id()` matches `query_state.world_id`. Calling this on a `world`
2828
/// with a mismatched [`WorldId`](crate::world::WorldId) is unsound.
2929
pub(crate) unsafe fn new(
30-
world: &'w World,
30+
world: UnsafeWorldCell<'w>,
3131
query_state: &'s QueryState<Q, F>,
3232
last_change_tick: u32,
3333
change_tick: u32,
3434
) -> Self {
3535
QueryIter {
3636
query_state,
3737
tables: &world.storages().tables,
38-
archetypes: &world.archetypes,
38+
archetypes: world.archetypes(),
3939
cursor: QueryIterationCursor::init(world, query_state, last_change_tick, change_tick),
4040
}
4141
}
@@ -95,7 +95,7 @@ where
9595
/// This does not validate that `world.id()` matches `query_state.world_id`. Calling this on a `world`
9696
/// with a mismatched [`WorldId`](crate::world::WorldId) is unsound.
9797
pub(crate) unsafe fn new<EntityList: IntoIterator<IntoIter = I>>(
98-
world: &'w World,
98+
world: UnsafeWorldCell<'w>,
9999
query_state: &'s QueryState<Q, F>,
100100
entity_list: EntityList,
101101
last_change_tick: u32,
@@ -115,9 +115,9 @@ where
115115
);
116116
QueryManyIter {
117117
query_state,
118-
entities: &world.entities,
119-
archetypes: &world.archetypes,
120-
tables: &world.storages.tables,
118+
entities: world.entities(),
119+
archetypes: world.archetypes(),
120+
tables: &world.storages().tables,
121121
fetch,
122122
filter,
123123
entity_iter: entity_list.into_iter(),
@@ -296,7 +296,7 @@ impl<'w, 's, Q: WorldQuery, F: ReadOnlyWorldQuery, const K: usize>
296296
/// This does not validate that `world.id()` matches `query_state.world_id`. Calling this on a
297297
/// `world` with a mismatched [`WorldId`](crate::world::WorldId) is unsound.
298298
pub(crate) unsafe fn new(
299-
world: &'w World,
299+
world: UnsafeWorldCell<'w>,
300300
query_state: &'s QueryState<Q, F>,
301301
last_change_tick: u32,
302302
change_tick: u32,
@@ -328,7 +328,7 @@ impl<'w, 's, Q: WorldQuery, F: ReadOnlyWorldQuery, const K: usize>
328328
QueryCombinationIter {
329329
query_state,
330330
tables: &world.storages().tables,
331-
archetypes: &world.archetypes,
331+
archetypes: world.archetypes(),
332332
cursors: array.assume_init(),
333333
}
334334
}
@@ -494,7 +494,7 @@ impl<'w, 's, Q: WorldQuery, F: ReadOnlyWorldQuery> QueryIterationCursor<'w, 's,
494494
const IS_DENSE: bool = Q::IS_DENSE && F::IS_DENSE;
495495

496496
unsafe fn init_empty(
497-
world: &'w World,
497+
world: UnsafeWorldCell<'w>,
498498
query_state: &'s QueryState<Q, F>,
499499
last_change_tick: u32,
500500
change_tick: u32,
@@ -507,7 +507,7 @@ impl<'w, 's, Q: WorldQuery, F: ReadOnlyWorldQuery> QueryIterationCursor<'w, 's,
507507
}
508508

509509
unsafe fn init(
510-
world: &'w World,
510+
world: UnsafeWorldCell<'w>,
511511
query_state: &'s QueryState<Q, F>,
512512
last_change_tick: u32,
513513
change_tick: u32,

crates/bevy_ecs/src/query/par_iter.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::world::World;
1+
use crate::world::unsafe_world_cell::UnsafeWorldCell;
22
use bevy_tasks::ComputeTaskPool;
33
use std::ops::Range;
44

@@ -79,7 +79,7 @@ impl BatchingStrategy {
7979
/// This struct is created by the [`Query::par_iter`](crate::system::Query::iter) and
8080
/// [`Query::par_iter_mut`](crate::system::Query::iter_mut) methods.
8181
pub struct QueryParIter<'w, 's, Q: WorldQuery, F: ReadOnlyWorldQuery> {
82-
pub(crate) world: &'w World,
82+
pub(crate) world: UnsafeWorldCell<'w>,
8383
pub(crate) state: &'s QueryState<Q, F>,
8484
pub(crate) batching_strategy: BatchingStrategy,
8585
}

0 commit comments

Comments
 (0)