use crate::prelude::OnSpawn;
use beet_core_macros::BundleEffect;
use bevy::ecs::relationship::Relationship;
use std::marker::PhantomData;
pub fn spawn_siblings<R, B>(
iter: impl 'static + Send + Sync + IntoIterator<Item = B>,
) -> impl Bundle
where
R: RelationshipTarget,
B: Bundle,
{
OnSpawn::new(move |entity| {
let parent = entity
.get::<R::Relationship>()
.expect("Spawn Siblings: This entity has no parent, this can happen due to
bundle effect race conditions, try reordering the effects")
.get();
let id = entity.id();
entity.world_scope(|world| {
for bundle in iter {
world.spawn((
bundle,
<R::Relationship as Relationship>::from(parent),
));
}
world.entity_mut(id).despawn();
});
})
}
#[derive(BundleEffect)]
pub struct BundleIter<T, B>
where
T: 'static + Send + Sync + Iterator<Item = B>,
B: Bundle,
{
pub value: T,
_phantom: PhantomData<B>,
}
impl<T, B> BundleIter<T, B>
where
T: 'static + Send + Sync + Iterator<Item = B>,
B: Bundle,
{
pub fn new(iter: T) -> Self {
Self {
value: iter,
_phantom: PhantomData,
}
}
fn effect(self, entity: &mut EntityWorldMut) {
for bundle in self.value {
entity.insert(bundle);
}
}
}
#[cfg(test)]
mod test {
use crate::prelude::*;
#[test]
fn works() {
let mut world = World::new();
let entity = world
.spawn(children![spawn_siblings::<Children, Name>(vec![
Name::new("Child1"),
Name::new("Child2"),
])])
.id();
let children = world.entity(entity).get::<Children>().unwrap();
children.len().xpect_eq(2);
}
}