Skip to content

Commit 1691a75

Browse files
use InteriorMutableWorld for System and ParamState
1 parent deb90e5 commit 1691a75

File tree

11 files changed

+104
-59
lines changed

11 files changed

+104
-59
lines changed

crates/bevy_ecs/macros/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ pub fn impl_param_set(_input: TokenStream) -> TokenStream {
292292
unsafe fn get_param<'w, 's>(
293293
state: &'s mut Self::State,
294294
system_meta: &SystemMeta,
295-
world: &'w World,
295+
world: InteriorMutableWorld<'w>,
296296
change_tick: u32,
297297
) -> Self::Item<'w, 's> {
298298
ParamSet {
@@ -496,7 +496,7 @@ pub fn derive_system_param(input: TokenStream) -> TokenStream {
496496
unsafe fn get_param<'w2, 's2>(
497497
state: &'s2 mut Self::State,
498498
system_meta: &#path::system::SystemMeta,
499-
world: &'w2 #path::world::World,
499+
world: #path::world::interior_mutable_world::InteriorMutableWorld<'w2>,
500500
change_tick: u32,
501501
) -> Self::Item<'w2, 's2> {
502502
let (#(#tuple_patterns,)*) = <

crates/bevy_ecs/src/schedule/executor_parallel.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::{
22
archetype::ArchetypeComponentId,
33
query::Access,
44
schedule::{ParallelSystemExecutor, SystemContainer},
5-
world::World,
5+
world::{interior_mutable_world::InteriorMutableWorld, World},
66
};
77
use async_channel::{Receiver, Sender};
88
use bevy_tasks::{ComputeTaskPool, Scope, TaskPool};
@@ -124,6 +124,8 @@ impl ParallelSystemExecutor for ParallelExecutor {
124124
}
125125
}
126126

127+
let world = world.as_interior_mutable();
128+
127129
ComputeTaskPool::init(TaskPool::default).scope(|scope| {
128130
self.prepare_systems(scope, systems, world);
129131
if self.should_run.count_ones(..) == 0 {
@@ -168,7 +170,7 @@ impl ParallelExecutor {
168170
&mut self,
169171
scope: &Scope<'_, 'scope, ()>,
170172
systems: &'scope mut [SystemContainer],
171-
world: &'scope World,
173+
world: InteriorMutableWorld<'scope>,
172174
) {
173175
// These are used as a part of a unit test.
174176
#[cfg(test)]

crates/bevy_ecs/src/system/commands/parallel_scope.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use crate::{
66
entity::Entities,
77
prelude::World,
88
system::{SystemMeta, SystemParam},
9+
world::interior_mutable_world::InteriorMutableWorld,
910
};
1011

1112
use super::{CommandQueue, Commands};
@@ -70,7 +71,7 @@ unsafe impl SystemParam for ParallelCommands<'_, '_> {
7071
unsafe fn get_param<'w, 's>(
7172
state: &'s mut Self::State,
7273
_: &crate::system::SystemMeta,
73-
world: &'w World,
74+
world: InteriorMutableWorld<'w>,
7475
_: u32,
7576
) -> Self::Item<'w, 's> {
7677
ParallelCommands {

crates/bevy_ecs/src/system/exclusive_function_system.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use crate::{
88
check_system_change_tick, AsSystemLabel, ExclusiveSystemParam, ExclusiveSystemParamItem,
99
IntoSystem, System, SystemMeta, SystemTypeIdLabel,
1010
},
11-
world::{World, WorldId},
11+
world::{interior_mutable_world::InteriorMutableWorld, World, WorldId},
1212
};
1313
use bevy_ecs_macros::all_tuples;
1414
use std::{borrow::Cow, marker::PhantomData};
@@ -86,7 +86,11 @@ where
8686
}
8787

8888
#[inline]
89-
unsafe fn run_unsafe(&mut self, _input: Self::In, _world: &World) -> Self::Out {
89+
unsafe fn run_unsafe(
90+
&mut self,
91+
_input: Self::In,
92+
_world: InteriorMutableWorld<'_>,
93+
) -> Self::Out {
9094
panic!("Cannot run exclusive systems with a shared World reference");
9195
}
9296

crates/bevy_ecs/src/system/function_system.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use crate::{
66
query::{Access, FilteredAccessSet},
77
schedule::{SystemLabel, SystemLabelId},
88
system::{check_system_change_tick, ReadOnlySystemParam, System, SystemParam, SystemParamItem},
9-
world::{World, WorldId},
9+
world::{interior_mutable_world::InteriorMutableWorld, World, WorldId},
1010
};
1111
use bevy_ecs_macros::all_tuples;
1212
use std::{borrow::Cow, fmt::Debug, marker::PhantomData};
@@ -172,15 +172,15 @@ impl<Param: SystemParam> SystemState<Param> {
172172
{
173173
self.validate_world_and_update_archetypes(world);
174174
// SAFETY: Param is read-only and doesn't allow mutable access to World. It also matches the World this SystemState was created with.
175-
unsafe { self.get_unchecked_manual(world) }
175+
unsafe { self.get_unchecked_manual(world.as_interior_mutable_readonly()) }
176176
}
177177

178178
/// Retrieve the mutable [`SystemParam`] values.
179179
#[inline]
180180
pub fn get_mut<'w, 's>(&'s mut self, world: &'w mut World) -> SystemParamItem<'w, 's, Param> {
181181
self.validate_world_and_update_archetypes(world);
182182
// SAFETY: World is uniquely borrowed and matches the World this SystemState was created with.
183-
unsafe { self.get_unchecked_manual(world) }
183+
unsafe { self.get_unchecked_manual(world.as_interior_mutable()) }
184184
}
185185

186186
/// Applies all state queued up for [`SystemParam`] values. For example, this will apply commands queued up
@@ -221,7 +221,7 @@ impl<Param: SystemParam> SystemState<Param> {
221221
#[inline]
222222
pub unsafe fn get_unchecked_manual<'w, 's>(
223223
&'s mut self,
224-
world: &'w World,
224+
world: InteriorMutableWorld<'w>,
225225
) -> SystemParamItem<'w, 's, Param> {
226226
let change_tick = world.increment_change_tick();
227227
let param = Param::get_param(&mut self.param_state, &self.meta, world, change_tick);
@@ -389,7 +389,7 @@ where
389389
}
390390

391391
#[inline]
392-
unsafe fn run_unsafe(&mut self, input: Self::In, world: &World) -> Self::Out {
392+
unsafe fn run_unsafe(&mut self, input: Self::In, world: InteriorMutableWorld<'_>) -> Self::Out {
393393
let change_tick = world.increment_change_tick();
394394

395395
// Safety:

crates/bevy_ecs/src/system/system.rs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,12 @@ use bevy_utils::tracing::warn;
22
use core::fmt::Debug;
33

44
use crate::{
5-
archetype::ArchetypeComponentId, change_detection::MAX_CHANGE_AGE, component::ComponentId,
6-
query::Access, schedule::SystemLabelId, world::World,
5+
archetype::ArchetypeComponentId,
6+
change_detection::MAX_CHANGE_AGE,
7+
component::ComponentId,
8+
query::Access,
9+
schedule::SystemLabelId,
10+
world::{interior_mutable_world::InteriorMutableWorld, World},
711
};
812
use std::borrow::Cow;
913

@@ -42,17 +46,14 @@ pub trait System: Send + Sync + 'static {
4246
///
4347
/// # Safety
4448
///
45-
/// This might access world and resources in an unsafe manner. This should only be called in one
46-
/// of the following contexts:
47-
/// 1. This system is the only system running on the given world across all threads.
48-
/// 2. This system only runs in parallel with other systems that do not conflict with the
49-
/// [`System::archetype_component_access()`].
50-
unsafe fn run_unsafe(&mut self, input: Self::In, world: &World) -> Self::Out;
49+
/// This function may only be called with a [`InteriorMutableWorld`] that can be used for
50+
/// everything listed in [`System::archetype_component_access`].
51+
unsafe fn run_unsafe(&mut self, input: Self::In, world: InteriorMutableWorld<'_>) -> Self::Out;
5152
/// Runs the system with the given input in the world.
5253
fn run(&mut self, input: Self::In, world: &mut World) -> Self::Out {
5354
self.update_archetype_component_access(world);
5455
// SAFETY: world and resources are exclusively borrowed
55-
unsafe { self.run_unsafe(input, world) }
56+
unsafe { self.run_unsafe(input, world.as_interior_mutable()) }
5657
}
5758
fn apply_buffers(&mut self, world: &mut World);
5859
/// Initialize the system.

0 commit comments

Comments
 (0)