use bevy::prelude::*;
use crate::prelude::*;
pub type WithPrefab<P> = With<<P as Prefab>::Marker>;
pub trait Prefab: 'static {
type Marker: Component + Default;
fn spawn(self, target: Entity, world: &mut World);
fn extract(builder: BuilderRef) -> BuilderRef {
builder.extract_entities_matching(|entity| entity.contains::<Self::Marker>())
}
}
pub struct SpawnPrefabCommand<P> {
target: Entity,
prefab: P,
}
impl<P> SpawnPrefabCommand<P> {
pub fn new(target: Entity, prefab: P) -> Self {
Self { target, prefab }
}
}
impl<P: Prefab + Send + 'static> Command for SpawnPrefabCommand<P> {
fn apply(self, world: &mut World) {
self.prefab.spawn(self.target, world);
}
}
pub trait CommandsPrefabExt {
fn spawn_prefab<P: Prefab + Send + 'static>(&mut self, prefab: P) -> EntityCommands;
}
impl CommandsPrefabExt for Commands<'_, '_> {
fn spawn_prefab<P: Prefab + Send + 'static>(&mut self, prefab: P) -> EntityCommands {
let target = self.spawn(P::Marker::default()).id();
self.queue(SpawnPrefabCommand::new(target, prefab));
self.entity(target)
}
}