Skip to content

Commit 989338a

Browse files
use UnsafeWorldCell for System and ParamState
1 parent 1ffeff1 commit 989338a

File tree

9 files changed

+61
-61
lines changed

9 files changed

+61
-61
lines changed

crates/bevy_ecs/macros/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ pub fn impl_param_set(_input: TokenStream) -> TokenStream {
294294
unsafe fn get_param<'w, 's>(
295295
state: &'s mut Self::State,
296296
system_meta: &SystemMeta,
297-
world: &'w World,
297+
world: UnsafeWorldCell<'w>,
298298
change_tick: u32,
299299
) -> Self::Item<'w, 's> {
300300
ParamSet {
@@ -498,7 +498,7 @@ pub fn derive_system_param(input: TokenStream) -> TokenStream {
498498
unsafe fn get_param<'w2, 's2>(
499499
state: &'s2 mut Self::State,
500500
system_meta: &#path::system::SystemMeta,
501-
world: &'w2 #path::world::World,
501+
world: #path::world::unsafe_world_cell::UnsafeWorldCell<'w2>,
502502
change_tick: u32,
503503
) -> Self::Item<'w2, 's2> {
504504
let (#(#tuple_patterns,)*) = <

crates/bevy_ecs/src/removal_detection.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use crate::{
88
prelude::Local,
99
storage::SparseSet,
1010
system::{ReadOnlySystemParam, SystemMeta, SystemParam},
11-
world::World,
11+
world::{unsafe_world_cell::UnsafeWorldCell, World},
1212
};
1313

1414
use std::{
@@ -178,9 +178,10 @@ unsafe impl<'a> SystemParam for &'a RemovedComponentEvents {
178178
unsafe fn get_param<'w, 's>(
179179
_state: &'s mut Self::State,
180180
_system_meta: &SystemMeta,
181-
world: &'w World,
181+
world: UnsafeWorldCell<'w>,
182182
_change_tick: u32,
183183
) -> Self::Item<'w, 's> {
184-
world.removed_components()
184+
// SAFETY: only metadata is accessed
185+
unsafe { world.world_metadata() }.removed_components()
185186
}
186187
}

crates/bevy_ecs/src/schedule/executor/multi_threaded.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use crate::{
1818
is_apply_system_buffers, BoxedCondition, ExecutorKind, SystemExecutor, SystemSchedule,
1919
},
2020
system::BoxedSystem,
21-
world::World,
21+
world::{unsafe_world_cell::UnsafeWorldCell, World},
2222
};
2323

2424
use crate as bevy_ecs;
@@ -281,6 +281,7 @@ impl MultiThreadedExecutor {
281281
// SAFETY: No exclusive system is running.
282282
// Therefore, there is no existing mutable reference to the world.
283283
let world = unsafe { &*cell.get() };
284+
284285
if !self.can_run(system_index, system, conditions, world) {
285286
// NOTE: exclusive systems with ambiguities are susceptible to
286287
// being significantly displaced here (compared to single-threaded order)
@@ -309,6 +310,9 @@ impl MultiThreadedExecutor {
309310
break;
310311
}
311312

313+
// TODO: do this earlier?
314+
let world = world.as_unsafe_world_cell_migration_internal();
315+
312316
// SAFETY: No other reference to this system exists.
313317
unsafe {
314318
self.spawn_system_task(scope, system_index, systems, world);
@@ -425,7 +429,7 @@ impl MultiThreadedExecutor {
425429
scope: &Scope<'_, 'scope, ()>,
426430
system_index: usize,
427431
systems: &'scope [SyncUnsafeCell<BoxedSystem>],
428-
world: &'scope World,
432+
world: UnsafeWorldCell<'scope>,
429433
) {
430434
// SAFETY: this system is not running, no other reference exists
431435
let system = unsafe { &mut *systems[system_index].get() };
@@ -604,6 +608,7 @@ fn apply_system_buffers(
604608
}
605609
}
606610

611+
// TODO: this is unsafe
607612
fn evaluate_and_fold_conditions(conditions: &mut [BoxedCondition], world: &World) -> bool {
608613
// not short-circuiting is intentional
609614
#[allow(clippy::unnecessary_fold)]
@@ -613,7 +618,7 @@ fn evaluate_and_fold_conditions(conditions: &mut [BoxedCondition], world: &World
613618
#[cfg(feature = "trace")]
614619
let _condition_span = info_span!("condition", name = &*condition.name()).entered();
615620
// SAFETY: caller ensures system access is compatible
616-
unsafe { condition.run_unsafe((), world) }
621+
unsafe { condition.run_unsafe((), world.as_unsafe_world_cell_readonly()) }
617622
})
618623
.fold(true, |acc, res| acc && res)
619624
}

crates/bevy_ecs/src/system/exclusive_function_system.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::{
77
check_system_change_tick, ExclusiveSystemParam, ExclusiveSystemParamItem, In, InputMarker,
88
IntoSystem, System, SystemMeta,
99
},
10-
world::{World, WorldId},
10+
world::{unsafe_world_cell::UnsafeWorldCell, World, WorldId},
1111
};
1212
use bevy_ecs_macros::all_tuples;
1313
use std::{any::TypeId, borrow::Cow, marker::PhantomData};
@@ -95,7 +95,7 @@ where
9595
}
9696

9797
#[inline]
98-
unsafe fn run_unsafe(&mut self, _input: Self::In, _world: &World) -> Self::Out {
98+
unsafe fn run_unsafe(&mut self, _input: Self::In, _world: UnsafeWorldCell<'_>) -> Self::Out {
9999
panic!("Cannot run exclusive systems with a shared World reference");
100100
}
101101

crates/bevy_ecs/src/system/function_system.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use crate::{
55
prelude::FromWorld,
66
query::{Access, FilteredAccessSet},
77
system::{check_system_change_tick, ReadOnlySystemParam, System, SystemParam, SystemParamItem},
8-
world::{World, WorldId},
8+
world::{unsafe_world_cell::UnsafeWorldCell, World, WorldId},
99
};
1010
use bevy_ecs_macros::all_tuples;
1111
use std::{any::TypeId, borrow::Cow, marker::PhantomData};
@@ -174,7 +174,7 @@ impl<Param: SystemParam> SystemState<Param> {
174174
self.validate_world(world);
175175
self.update_archetypes(world);
176176
// SAFETY: Param is read-only and doesn't allow mutable access to World. It also matches the World this SystemState was created with.
177-
unsafe { self.get_unchecked_manual(world) }
177+
unsafe { self.get_unchecked_manual(world.as_unsafe_world_cell_readonly()) }
178178
}
179179

180180
/// Retrieve the mutable [`SystemParam`] values.
@@ -183,7 +183,7 @@ impl<Param: SystemParam> SystemState<Param> {
183183
self.validate_world(world);
184184
self.update_archetypes(world);
185185
// SAFETY: World is uniquely borrowed and matches the World this SystemState was created with.
186-
unsafe { self.get_unchecked_manual(world) }
186+
unsafe { self.get_unchecked_manual(world.as_unsafe_world_cell()) }
187187
}
188188

189189
/// Applies all state queued up for [`SystemParam`] values. For example, this will apply commands queued up
@@ -243,7 +243,7 @@ impl<Param: SystemParam> SystemState<Param> {
243243
self.validate_world(world);
244244
let change_tick = world.read_change_tick();
245245
// SAFETY: Param is read-only and doesn't allow mutable access to World. It also matches the World this SystemState was created with.
246-
unsafe { self.fetch(world, change_tick) }
246+
unsafe { self.fetch(world.as_unsafe_world_cell_readonly(), change_tick) }
247247
}
248248

249249
/// Retrieve the mutable [`SystemParam`] values. This will not update the state's view of the world's archetypes
@@ -261,7 +261,7 @@ impl<Param: SystemParam> SystemState<Param> {
261261
self.validate_world(world);
262262
let change_tick = world.change_tick();
263263
// SAFETY: World is uniquely borrowed and matches the World this SystemState was created with.
264-
unsafe { self.fetch(world, change_tick) }
264+
unsafe { self.fetch(world.as_unsafe_world_cell(), change_tick) }
265265
}
266266

267267
/// Retrieve the [`SystemParam`] values. This will not update archetypes automatically.
@@ -273,7 +273,7 @@ impl<Param: SystemParam> SystemState<Param> {
273273
#[inline]
274274
pub unsafe fn get_unchecked_manual<'w, 's>(
275275
&'s mut self,
276-
world: &'w World,
276+
world: UnsafeWorldCell<'w>,
277277
) -> SystemParamItem<'w, 's, Param> {
278278
let change_tick = world.increment_change_tick();
279279
self.fetch(world, change_tick)
@@ -286,7 +286,7 @@ impl<Param: SystemParam> SystemState<Param> {
286286
#[inline]
287287
unsafe fn fetch<'w, 's>(
288288
&'s mut self,
289-
world: &'w World,
289+
world: UnsafeWorldCell<'w>,
290290
change_tick: u32,
291291
) -> SystemParamItem<'w, 's, Param> {
292292
let param = Param::get_param(&mut self.param_state, &self.meta, world, change_tick);
@@ -459,7 +459,7 @@ where
459459
}
460460

461461
#[inline]
462-
unsafe fn run_unsafe(&mut self, input: Self::In, world: &World) -> Self::Out {
462+
unsafe fn run_unsafe(&mut self, input: Self::In, world: UnsafeWorldCell<'_>) -> Self::Out {
463463
let change_tick = world.increment_change_tick();
464464

465465
// Safety:

crates/bevy_ecs/src/system/system.rs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use core::fmt::Debug;
33

44
use crate::{
55
archetype::ArchetypeComponentId, change_detection::MAX_CHANGE_AGE, component::ComponentId,
6-
query::Access, world::World,
6+
query::Access, world::unsafe_world_cell::UnsafeWorldCell, world::World,
77
};
88

99
use std::any::TypeId;
@@ -46,17 +46,14 @@ pub trait System: Send + Sync + 'static {
4646
///
4747
/// # Safety
4848
///
49-
/// This might access world and resources in an unsafe manner. This should only be called in one
50-
/// of the following contexts:
51-
/// 1. This system is the only system running on the given world across all threads.
52-
/// 2. This system only runs in parallel with other systems that do not conflict with the
53-
/// [`System::archetype_component_access()`].
54-
unsafe fn run_unsafe(&mut self, input: Self::In, world: &World) -> Self::Out;
49+
/// This function may only be called with a [`UnsafeWorldCell`] that can be used for
50+
/// everything listed in [`System::archetype_component_access`].
51+
unsafe fn run_unsafe(&mut self, input: Self::In, world: UnsafeWorldCell<'_>) -> Self::Out;
5552
/// Runs the system with the given input in the world.
5653
fn run(&mut self, input: Self::In, world: &mut World) -> Self::Out {
5754
self.update_archetype_component_access(world);
5855
// SAFETY: world and resources are exclusively borrowed
59-
unsafe { self.run_unsafe(input, world) }
56+
unsafe { self.run_unsafe(input, world.as_unsafe_world_cell()) }
6057
}
6158
fn apply_buffers(&mut self, world: &mut World);
6259
/// Initialize the system.

0 commit comments

Comments
 (0)