I have some spawning code that randomly adds entities to a level, and I want to be able to save that level to a resource so it can be restarted by nuking it and re-spawning the same stuff in the same configuration. I tried saving:
- a Vec of bundles. Doesn't work unless the bundles have contents with a specific known type, and mine are heterogeneously typed.
- a random seed. Doesn't seem like a good option with nondeterministically ordered usage across multiple systems.
- a Vec of closures that run spawn commands. This finally worked, after some finagling with the type system.
Is there a simpler way to do this? A subset of my code for reference:
#[derive(Resource, Default)]
struct Level {
// A list of closures that spawn entities.
spawn: Vec<Box<dyn Fn(&mut Commands) + Send + Sync>>,
}
fn add_foos_to_level(level: ResMut<Level>) {
let bundle = (Foo, ...);
level.spawn.push(Box::new(move |commands: &mut Commands| {
commands.spawn(bundle.clone());
}));
}
fn add_bars_to_level(level: ResMut<Level>) {
let bundle = (Bar, ...);
level.spawn.push(Box::new(move |commands: &mut Commands| {
commands.spawn(bundle.clone());
}));
}
fn spawn_level(mut commands: Commands, level: ResMut<Level>) {
for spawn in level.spawn.iter() {
spawn(&mut commands);
}
}