use bevy::prelude::*;
#[derive(Debug, Component)]
pub enum AutoDespawn {
Timer(Timer),
Frames(u32),
}
impl AutoDespawn {
#[deprecated]
pub fn new(duration: f32) -> Self {
Self::with_duration(duration)
}
pub fn with_duration(duration: f32) -> Self {
AutoDespawn::Timer(Timer::from_seconds(duration, TimerMode::Once))
}
pub fn with_frames(frames: u32) -> Self {
AutoDespawn::Frames(frames)
}
}
pub fn auto_despawn_system(
mut commands: Commands,
mut query: Query<(Entity, &mut AutoDespawn)>,
time: Res<Time>,
) {
for (entity, mut auto_despawn) in query.iter_mut() {
match auto_despawn.as_mut() {
AutoDespawn::Timer(timer) => {
if timer.tick(time.delta()).just_finished() {
commands.entity(entity).despawn_recursive();
}
}
AutoDespawn::Frames(frames) => {
if *frames == 0 {
commands.entity(entity).despawn_recursive();
} else {
*frames -= 1;
}
}
}
}
}
pub struct AutoDespawnPlugin;
impl Plugin for AutoDespawnPlugin {
fn build(&self, app: &mut App) {
app.add_systems(Update, auto_despawn_system);
}
}
#[derive(Debug, Component)]
pub struct Cleanup<S>(pub S);
pub fn cleanup_system<S: States + Eq>(state: S) -> impl Fn(Commands, Query<(Entity, &Cleanup<S>)>) {
move |mut commands: Commands, query: Query<(Entity, &Cleanup<S>)>| {
for (entity, cleanup) in query.iter() {
if cleanup.0 == state {
commands.entity(entity).despawn_recursive();
}
}
}
}
pub struct CleanupPlugin<S>(pub S);
impl<S: Clone + States + Send + Sync + 'static> Plugin for CleanupPlugin<S> {
fn build(&self, app: &mut App) {
app.add_systems(OnExit(self.0.clone()), cleanup_system(self.0.clone()));
}
}