use beet_core::prelude::*;
#[derive(Debug, Component, EntityEvent)]
pub struct GetReady(pub Entity);
#[derive(Debug, Component, EntityEvent)]
#[entity_event(auto_propagate)]
pub struct Ready(pub Entity);
#[derive(Debug, Component)]
pub struct ReadyAction {
sealed: PhantomData<()>,
}
impl ReadyAction {
pub fn run<Fut, Out>(
func: impl 'static + Send + Sync + Clone + FnOnce(AsyncEntity) -> Fut,
) -> (Self, OnSpawn)
where
Fut: 'static + Send + Sync + Future<Output = Out> + Send,
Out: AsyncTaskOut,
{
(
Self { sealed: default() },
OnSpawn::observe(
move |ev: On<GetReady>, mut commands: AsyncCommands| {
let entity = ev.event_target();
let observer = func.clone();
commands.run(async move |world| {
let out = observer(world.entity(entity)).await;
world.entity(entity).trigger(Ready).await;
out
});
},
),
)
}
pub fn run_local<Fut, Out>(
func: impl 'static + Send + Sync + Clone + FnOnce(AsyncEntity) -> Fut,
) -> (Self, OnSpawn)
where
Fut: 'static + Future<Output = Out> + Send,
Out: AsyncTaskOut,
{
(
Self { sealed: default() },
OnSpawn::observe(
move |ev: On<GetReady>, mut commands: AsyncCommands| {
let entity = ev.event_target();
let observer = func.clone();
commands.run_local(async move |world| {
let out = observer(world.entity(entity)).await;
world.entity(entity).trigger(Ready).await;
out
});
},
),
)
}
}