Skip to content

Commit

Permalink
use InteriorMutableWorld for System and ParamState
Browse files Browse the repository at this point in the history
  • Loading branch information
jakobhellermann committed Dec 17, 2022
1 parent 588fa82 commit 4f04a57
Show file tree
Hide file tree
Showing 12 changed files with 92 additions and 68 deletions.
4 changes: 2 additions & 2 deletions crates/bevy_ecs/macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ pub fn impl_param_set(_input: TokenStream) -> TokenStream {
unsafe fn get_param(
state: &'s mut Self,
system_meta: &SystemMeta,
world: &'w World,
world: InteriorMutableWorld<'w>,
change_tick: u32,
) -> Self::Item {
ParamSet {
Expand Down Expand Up @@ -460,7 +460,7 @@ pub fn derive_system_param(input: TokenStream) -> TokenStream {
unsafe fn get_param(
state: &'s mut Self,
system_meta: &#path::system::SystemMeta,
world: &'w #path::world::World,
world: #path::world::interior_mutable_world::InteriorMutableWorld<'w>,
change_tick: u32,
) -> Self::Item {
#struct_name {
Expand Down
6 changes: 4 additions & 2 deletions crates/bevy_ecs/src/schedule/executor_parallel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::{
archetype::ArchetypeComponentId,
query::Access,
schedule::{ParallelSystemExecutor, SystemContainer},
world::World,
world::{interior_mutable_world::InteriorMutableWorld, World},
};
use async_channel::{Receiver, Sender};
use bevy_tasks::{ComputeTaskPool, Scope, TaskPool};
Expand Down Expand Up @@ -124,6 +124,8 @@ impl ParallelSystemExecutor for ParallelExecutor {
}
}

let world = world.as_interior_mutable();

ComputeTaskPool::init(TaskPool::default).scope(|scope| {
self.prepare_systems(scope, systems, world);
if self.should_run.count_ones(..) == 0 {
Expand Down Expand Up @@ -168,7 +170,7 @@ impl ParallelExecutor {
&mut self,
scope: &Scope<'_, 'scope, ()>,
systems: &'scope mut [SystemContainer],
world: &'scope World,
world: InteriorMutableWorld<'scope>,
) {
// These are used as a part of a unit test.
#[cfg(test)]
Expand Down
3 changes: 2 additions & 1 deletion crates/bevy_ecs/src/system/commands/parallel_scope.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use crate::{
entity::Entities,
prelude::World,
system::{SystemParam, SystemParamFetch, SystemParamState},
world::interior_mutable_world::InteriorMutableWorld,
};

use super::{CommandQueue, Commands};
Expand Down Expand Up @@ -58,7 +59,7 @@ impl<'w, 's> SystemParamFetch<'w, 's> for ParallelCommandsState {
unsafe fn get_param(
state: &'s mut Self,
_: &crate::system::SystemMeta,
world: &'w World,
world: InteriorMutableWorld<'w>,
_: u32,
) -> Self::Item {
ParallelCommands {
Expand Down
8 changes: 6 additions & 2 deletions crates/bevy_ecs/src/system/exclusive_function_system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::{
ExclusiveSystemParamItem, ExclusiveSystemParamState, IntoSystem, System, SystemMeta,
SystemTypeIdLabel,
},
world::{World, WorldId},
world::{interior_mutable_world::InteriorMutableWorld, World, WorldId},
};
use bevy_ecs_macros::all_tuples;
use std::{borrow::Cow, marker::PhantomData};
Expand Down Expand Up @@ -87,7 +87,11 @@ where
}

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

Expand Down
10 changes: 5 additions & 5 deletions crates/bevy_ecs/src/system/function_system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::{
check_system_change_tick, ReadOnlySystemParamFetch, System, SystemParam, SystemParamFetch,
SystemParamItem, SystemParamState,
},
world::{World, WorldId},
world::{interior_mutable_world::InteriorMutableWorld, World, WorldId},
};
use bevy_ecs_macros::all_tuples;
use std::{borrow::Cow, fmt::Debug, marker::PhantomData};
Expand Down Expand Up @@ -169,7 +169,7 @@ impl<Param: SystemParam> SystemState<Param> {
{
self.validate_world_and_update_archetypes(world);
// SAFETY: Param is read-only and doesn't allow mutable access to World. It also matches the World this SystemState was created with.
unsafe { self.get_unchecked_manual(world) }
unsafe { self.get_unchecked_manual(world.as_interior_mutable_readonly()) }
}

/// Retrieve the mutable [`SystemParam`] values.
Expand All @@ -180,7 +180,7 @@ impl<Param: SystemParam> SystemState<Param> {
) -> <Param::Fetch as SystemParamFetch<'w, 's>>::Item {
self.validate_world_and_update_archetypes(world);
// SAFETY: World is uniquely borrowed and matches the World this SystemState was created with.
unsafe { self.get_unchecked_manual(world) }
unsafe { self.get_unchecked_manual(world.as_interior_mutable()) }
}

/// Applies all state queued up for [`SystemParam`] values. For example, this will apply commands queued up
Expand Down Expand Up @@ -220,7 +220,7 @@ impl<Param: SystemParam> SystemState<Param> {
#[inline]
pub unsafe fn get_unchecked_manual<'w, 's>(
&'s mut self,
world: &'w World,
world: InteriorMutableWorld<'w>,
) -> <Param::Fetch as SystemParamFetch<'w, 's>>::Item {
let change_tick = world.increment_change_tick();
let param = <Param::Fetch as SystemParamFetch>::get_param(
Expand Down Expand Up @@ -393,7 +393,7 @@ where
}

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

// Safety:
Expand Down
19 changes: 10 additions & 9 deletions crates/bevy_ecs/src/system/system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@ use bevy_utils::tracing::warn;
use core::fmt::Debug;

use crate::{
archetype::ArchetypeComponentId, change_detection::MAX_CHANGE_AGE, component::ComponentId,
query::Access, schedule::SystemLabelId, world::World,
archetype::ArchetypeComponentId,
change_detection::MAX_CHANGE_AGE,
component::ComponentId,
query::Access,
schedule::SystemLabelId,
world::{interior_mutable_world::InteriorMutableWorld, World},
};
use std::borrow::Cow;

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

0 comments on commit 4f04a57

Please sign in to comment.