From 9d13ae3113c508cb66b533641fd02127ef01dca4 Mon Sep 17 00:00:00 2001 From: SpecificProtagonist Date: Sat, 24 Feb 2024 10:52:25 +0100 Subject: [PATCH] Fix SimpleExecutor crash (#12076) # Objective Since #9822, `SimpleExecutor` panics when an automatic sync point is inserted: ```rust let mut sched = Schedule::default(); sched.set_executor_kind(ExecutorKind::Simple); sched.add_systems((|_: Commands| (), || ()).chain()); sched.run(&mut World::new()); ``` ``` System's param_state was not found. Did you forget to initialize this system before running it? note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace Encountered a panic in system `bevy_ecs::schedule::executor::apply_deferred`! ``` ## Solution Don't try to run the `apply_deferred` system. --- .../bevy_ecs/src/schedule/executor/simple.rs | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/crates/bevy_ecs/src/schedule/executor/simple.rs b/crates/bevy_ecs/src/schedule/executor/simple.rs index 002ba532ad..6c1b7437ac 100644 --- a/crates/bevy_ecs/src/schedule/executor/simple.rs +++ b/crates/bevy_ecs/src/schedule/executor/simple.rs @@ -4,7 +4,9 @@ use fixedbitset::FixedBitSet; use std::panic::AssertUnwindSafe; use crate::{ - schedule::{BoxedCondition, ExecutorKind, SystemExecutor, SystemSchedule}, + schedule::{ + executor::is_apply_deferred, BoxedCondition, ExecutorKind, SystemExecutor, SystemSchedule, + }, world::World, }; @@ -86,6 +88,10 @@ impl SystemExecutor for SimpleExecutor { } let system = &mut schedule.systems[system_index]; + if is_apply_deferred(system) { + continue; + } + let res = std::panic::catch_unwind(AssertUnwindSafe(|| { system.run((), world); })); @@ -125,3 +131,16 @@ fn evaluate_and_fold_conditions(conditions: &mut [BoxedCondition], world: &mut W .map(|condition| condition.run((), world)) .fold(true, |acc, res| acc && res) } + +#[cfg(test)] +#[test] +fn skip_automatic_sync_points() { + // Schedules automatically insert appy_deferred systems, but these should + // not be executed as they only serve as markers and are not initialized + use crate::prelude::*; + let mut sched = Schedule::default(); + sched.set_executor_kind(ExecutorKind::Simple); + sched.add_systems((|_: Commands| (), || ()).chain()); + let mut world = World::new(); + sched.run(&mut world); +}