Skip to content

Commit f133106

Browse files
authored
Implement SpawnableList for Vec<Bundle> (#18259)
# Objective In updating examples to use the Improved Spawning API I got tripped up on being able to spawn children with a Vec. I eventually figured out that I could use `Children::spawn(SpawnIter(my_vec.into_iter()))` but thought there might be a more ergonomic way to approach it. After tinkering with it for a while I came up with the implementation here. It allows authors to use `Children::spawn(my_vec)` as an equivalent implementation. ## Solution - Implements `<R: Relationship, B: Bundle SpawnableList<R> for Vec<B>` - uses `alloc::vec::Vec` for compatibility with `no_std` (`std::Vec` also inherits implementations against the `alloc::vec::Vec` because std is a re-export of the alloc struct, thanks @bushrat011899 for the info on this!) ## Testing - Did you test these changes? If so, how? - Opened the examples before and after and verified the same behavior was observed. I did this on Ubuntu 24.04.2 LTS using `--features wayland`. - Are there any parts that need more testing? - Other OS's and features can't hurt, but this is such a small change it shouldn't be a problem. - How can other people (reviewers) test your changes? Is there anything specific they need to know? - Run the examples yourself with and without these changes. - If relevant, what platforms did you test these changes on, and are there any important ones you can't test? - see above ## Showcase n/a ## Migration Guide - Optional: you may use the new API to spawn `Vec`s of `Bundle` instead of using the `SpawnIter` approach.
1 parent 949d781 commit f133106

File tree

2 files changed

+23
-16
lines changed

2 files changed

+23
-16
lines changed

crates/bevy_ecs/src/spawn.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@
22
//! for the best entry points into these APIs and examples of how to use them.
33
44
use crate::{
5-
bundle::{Bundle, BundleEffect, DynamicBundle},
5+
bundle::{Bundle, BundleEffect, DynamicBundle, NoBundleEffect},
66
entity::Entity,
77
relationship::{RelatedSpawner, Relationship, RelationshipTarget},
88
world::{EntityWorldMut, World},
99
};
10+
use alloc::vec::Vec;
1011
use core::marker::PhantomData;
1112
use variadics_please::all_tuples;
1213

@@ -45,6 +46,17 @@ pub trait SpawnableList<R> {
4546
fn size_hint(&self) -> usize;
4647
}
4748

49+
impl<R: Relationship, B: Bundle<Effect: NoBundleEffect>> SpawnableList<R> for Vec<B> {
50+
fn spawn(self, world: &mut World, entity: Entity) {
51+
let mapped_bundles = self.into_iter().map(|b| (R::from(entity), b));
52+
world.spawn_batch(mapped_bundles);
53+
}
54+
55+
fn size_hint(&self) -> usize {
56+
self.len()
57+
}
58+
}
59+
4860
impl<R: Relationship, B: Bundle> SpawnableList<R> for Spawn<B> {
4961
fn spawn(self, world: &mut World, entity: Entity) {
5062
world.spawn((R::from(entity), self.0));

examples/tools/scene_viewer/morph_viewer_plugin.rs

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -273,21 +273,16 @@ fn detect_morphs(
273273
|(i, target): (usize, &Target)| target.text_span(AVAILABLE_KEYS[i].name, style.clone());
274274
spans.extend(detected.iter().enumerate().map(target_to_text));
275275
commands.insert_resource(WeightsControl { weights: detected });
276-
commands
277-
.spawn((
278-
Text::default(),
279-
Node {
280-
position_type: PositionType::Absolute,
281-
top: Val::Px(12.0),
282-
left: Val::Px(12.0),
283-
..default()
284-
},
285-
))
286-
.with_children(|p| {
287-
for span in spans {
288-
p.spawn(span);
289-
}
290-
});
276+
commands.spawn((
277+
Text::default(),
278+
Node {
279+
position_type: PositionType::Absolute,
280+
top: Val::Px(12.0),
281+
left: Val::Px(12.0),
282+
..default()
283+
},
284+
Children::spawn(spans),
285+
));
291286
}
292287

293288
pub struct MorphViewerPlugin;

0 commit comments

Comments
 (0)