Closed
Description
Bevy version
0.14.2
What you did
Run this code:
#[derive(Component)]
struct TestRemoveComp;
#[derive(Component)]
struct CoundownTimer {
pub start: Instant,
pub duration: Duration,
}
#[derive(Component)]
struct TestSpawnComp;
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_systems(Startup, |mut commands: Commands| {
commands.spawn((
TestRemoveComp,
CoundownTimer {
start: Instant::now(),
duration: Duration::from_secs_f32(1.),
},
));
})
.add_systems(
Update,
|mut commands: Commands, query: Query<(Entity, &CoundownTimer)>| {
for (entity, timer) in &mut query.iter() {
if timer.start.elapsed() > timer.duration {
commands.entity(entity).despawn();
}
}
},
)
.observe(
|_: Trigger<OnRemove, TestRemoveComp>, mut commands: Commands| {
commands.spawn(TestSpawnComp);
},
)
.run();
}
What went wrong
App panicked.
I am noticing this behaviour only when Commands::spawn is issued within Trigger<OnRemove> observer. Commands::insert and Commands::add works correctly in this context.
thread 'main' panicked at C:\Users\User\.cargo\registry\src\index.crates.io-6f17d22bba15001f\bevy_ecs-0.14.0\src\entity\mod.rs:582:9:
flush() needs to be called before this operation is legal
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Encountered a panic when applying buffers for system `test::main::{{closure}}`!
Encountered a panic in system `bevy_app::main_schedule::Main::run_main`!
Additional information
As a workaround I am spawning from dedicated Command instead of spawning directly.
...
.observe(
|_: Trigger<OnRemove, TestRemoveComp>, mut commands: Commands| {
commands.add(TriggerOnRemoveSpawnWorkaround {bundle: TestSpawnComp});
},
)
pub struct TriggerOnRemoveSpawnWorkaround<B: Bundle> {
pub bundle: B,
}
impl <B> Command for TriggerOnRemoveSpawnWorkaround<B>
where B: Bundle {
fn apply(self, world: &mut bevy::prelude::World) {
world.spawn(self.bundle);
}
}