Skip to content

Commit

Permalink
unify exclusive system params with normal system params
Browse files Browse the repository at this point in the history
  • Loading branch information
ItsDoot committed Dec 3, 2024
1 parent c02696b commit 761edc6
Show file tree
Hide file tree
Showing 10 changed files with 274 additions and 548 deletions.
4 changes: 4 additions & 0 deletions crates/bevy_ecs/macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,10 @@ pub fn impl_param_set(_input: TokenStream) -> TokenStream {
change_tick,
}
}

fn is_exclusive() -> bool {
false #(|| <#param as SystemParam>::is_exclusive())*
}
}

impl<'w, 's, #(#param: SystemParam,)*> ParamSet<'w, 's, (#(#param,)*)>
Expand Down
127 changes: 120 additions & 7 deletions crates/bevy_ecs/src/schedule/executor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ mod multi_threaded;
mod simple;
mod single_threaded;

use core::any::TypeId;

use alloc::borrow::Cow;

pub use self::{
multi_threaded::{MainThreadExecutor, MultiThreadedExecutor},
simple::SimpleExecutor,
Expand All @@ -11,9 +15,13 @@ pub use self::{
use fixedbitset::FixedBitSet;

use crate::{
schedule::{BoxedCondition, NodeId},
system::BoxedSystem,
world::World,
archetype::ArchetypeComponentId,
component::{ComponentId, Tick},
prelude::{IntoSystemSet, SystemIn, SystemSet},
query::Access,
schedule::{BoxedCondition, NodeId, SystemTypeSet},
system::{check_system_change_tick, BoxedSystem, System},
world::{unsafe_world_cell::UnsafeWorldCell, World},
};

/// Types that can run a [`SystemSchedule`] on a [`World`].
Expand Down Expand Up @@ -118,14 +126,119 @@ impl SystemSchedule {
/// - This function (currently) does nothing if it's called manually or wrapped inside a [`PipeSystem`](crate::system::PipeSystem).
/// - Modifying a [`Schedule`](super::Schedule) may change the order buffers are applied.
#[doc(alias = "apply_system_buffers")]
#[allow(unused_variables)]
pub fn apply_deferred(world: &mut World) {}
#[allow(unused_variables, non_upper_case_globals)]
pub const apply_deferred: ApplyDeferred = ApplyDeferred {
last_run: Tick::MAX,
};

/// Returns `true` if the [`System`](crate::system::System) is an instance of [`apply_deferred`].
pub(super) fn is_apply_deferred(system: &BoxedSystem) -> bool {
use crate::system::IntoSystem;
// deref to use `System::type_id` instead of `Any::type_id`
system.as_ref().type_id() == apply_deferred.system_type_id()
system.as_ref().type_id() == TypeId::of::<ApplyDeferred>()
}

/// Instructs the executor to call [`System::apply_deferred`](crate::system::System::apply_deferred)
/// on the systems that have run but not applied their [`Deferred`](crate::system::Deferred) system parameters
/// (like [`Commands`](crate::prelude::Commands)) or other system buffers.
///
/// ## Scheduling
///
/// `ApplyDeferred` systems are scheduled *by default*
/// - later in the same schedule run (for example, if a system with `Commands` param
/// is scheduled in `Update`, all the changes will be visible in `PostUpdate`)
/// - between systems with dependencies if the dependency
/// [has deferred buffers](crate::system::System::has_deferred)
/// (if system `bar` directly or indirectly depends on `foo`, and `foo` uses `Commands` param,
/// changes to the world in `foo` will be visible in `bar`)
///
/// ## Notes
/// - This system (currently) does nothing if it's called manually or wrapped inside a [`PipeSystem`](crate::system::PipeSystem).
/// - Modifying a [`Schedule`](super::Schedule) may change the order buffers are applied.
pub struct ApplyDeferred {
last_run: Tick,
}

impl ApplyDeferred {
const NAME: &'static str = "bevy_ecs::apply_deferred";
}

impl System for ApplyDeferred {
type In = ();
type Out = ();

fn name(&self) -> Cow<'static, str> {
Cow::Borrowed(Self::NAME)
}

fn component_access(&self) -> &Access<ComponentId> {
const { &Access::new() }
}

fn archetype_component_access(&self) -> &Access<ArchetypeComponentId> {
const { &Access::new() }
}

fn is_send(&self) -> bool {
true
}

fn is_exclusive(&self) -> bool {
true
}

fn has_deferred(&self) -> bool {
false
}

unsafe fn run_unsafe(
&mut self,
_input: SystemIn<'_, Self>,
_world: UnsafeWorldCell,
) -> Self::Out {
panic!("`bevy_ecs::apply_deferred` should not be run directly")
}

fn run(&mut self, _input: SystemIn<'_, Self>, world: &mut World) -> Self::Out {
self.last_run = world.change_tick().relative_to(Tick::MAX);
}

fn apply_deferred(&mut self, _world: &mut World) {}

fn queue_deferred(&mut self, _world: crate::world::DeferredWorld) {}

unsafe fn validate_param_unsafe(&mut self, _world: UnsafeWorldCell) -> bool {
true
}

fn initialize(&mut self, world: &mut World) {
self.last_run = world.change_tick().relative_to(Tick::MAX);
}

fn update_archetype_component_access(&mut self, _world: UnsafeWorldCell) {}

fn check_change_tick(&mut self, change_tick: Tick) {
check_system_change_tick(&mut self.last_run, change_tick, Self::NAME);
}

fn default_system_sets(&self) -> Vec<super::InternedSystemSet> {
vec![SystemTypeSet::<Self>::new().intern()]
}

fn get_last_run(&self) -> Tick {
self.last_run
}

fn set_last_run(&mut self, last_run: Tick) {
self.last_run = last_run;
}
}

impl IntoSystemSet<()> for ApplyDeferred {
type Set = SystemTypeSet<Self>;

fn into_system_set(self) -> Self::Set {
SystemTypeSet::<Self>::new()
}
}

/// These functions hide the bottom of the callstack from `RUST_BACKTRACE=1` (assuming the default panic handler is used).
Expand Down
19 changes: 1 addition & 18 deletions crates/bevy_ecs/src/schedule/set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,7 @@ pub use bevy_ecs_macros::{ScheduleLabel, SystemSet};
use crate::{
define_label,
intern::Interned,
system::{
ExclusiveFunctionSystem, ExclusiveSystemParamFunction, FunctionSystem,
IsExclusiveFunctionSystem, IsFunctionSystem, SystemParamFunction,
},
system::{FunctionSystem, IsFunctionSystem, SystemParamFunction},
};

define_label!(
Expand Down Expand Up @@ -187,20 +184,6 @@ where
}
}

// exclusive systems
impl<Marker, F> IntoSystemSet<(IsExclusiveFunctionSystem, Marker)> for F
where
Marker: 'static,
F: ExclusiveSystemParamFunction<Marker>,
{
type Set = SystemTypeSet<ExclusiveFunctionSystem<Marker, F>>;

#[inline]
fn into_system_set(self) -> Self::Set {
SystemTypeSet::<ExclusiveFunctionSystem<Marker, F>>::new()
}
}

#[cfg(test)]
mod tests {
use crate::{
Expand Down
Loading

0 comments on commit 761edc6

Please sign in to comment.