mirror of
https://github.com/bevyengine/bevy
synced 2024-12-23 11:33:06 +00:00
af20cad830
# Objective Sometimes, the unwraps in `entity_mut` could fail here, if the entity was despawned *before* this command was applied. The simplest case involves two command buffers: ```rust use bevy::prelude::*; fn b(mut commands1: Commands, mut commands2: Commands) { let id = commands2.spawn().insert_bundle(()).id(); commands1.entity(id).despawn(); } fn main() { App::build().add_system(b.system()).run(); } ``` However, a more complicated version arises in the case of ambiguity: ```rust use std::time::Duration; use bevy::{app::ScheduleRunnerPlugin, prelude::*}; use rand::Rng; fn cleanup(mut e: ResMut<Option<Entity>>) { *e = None; } fn sleep_randomly() { let mut rng = rand::thread_rng(); std:🧵:sleep(Duration::from_millis(rng.gen_range(0..50))); } fn spawn(mut commands: Commands, mut e: ResMut<Option<Entity>>) { *e = Some(commands.spawn().insert_bundle(()).id()); } fn despawn(mut commands: Commands, e: Res<Option<Entity>>) { let mut rng = rand::thread_rng(); std:🧵:sleep(Duration::from_millis(rng.gen_range(0..50))); if let Some(e) = *e { commands.entity(e).despawn(); } } fn main() { App::build() .add_system(cleanup.system().label("cleanup")) .add_system(sleep_randomly.system().label("before_despawn")) .add_system(despawn.system().after("cleanup").after("before_despawn")) .add_system(sleep_randomly.system().label("before_spawn")) .add_system(spawn.system().after("cleanup").after("before_spawn")) .insert_resource(None::<Entity>) .add_plugin(ScheduleRunnerPlugin::default()) .run(); } ``` In the cases where this example crashes, it's because `despawn` was ordered before `spawn` in the topological ordering of systems (which determines when buffers are applied). However, `despawn` actually ran *after* `spawn`, because these systems are ambiguous, so the jiggles in the sleeping time triggered a case where this works. ## Solution - Give a better error message |
||
---|---|---|
.. | ||
command_queue.rs | ||
mod.rs |