use bevy_app::{App, Plugin, Update};
use bevy_ecs::component::Component;
use bevy_ecs::message::{Message, MessageWriter};
use bevy_ecs::prelude::*;
use bevy_time::Time;
use crate::spring::Spring;
use crate::traits::Animatable;
use crate::traits::Update as SpandaUpdate;
use crate::tween::Tween;
#[derive(Debug, Message)]
pub struct TweenCompleted {
pub entity: Entity,
}
#[derive(Debug, Message)]
pub struct SpringSettled {
pub entity: Entity,
}
#[derive(Component, Clone, Debug)]
pub struct AnimationLabel {
pub label: &'static str,
}
impl AnimationLabel {
pub fn new(label: &'static str) -> Self {
Self { label }
}
}
#[derive(Debug)]
pub struct SpandaPlugin;
impl Plugin for SpandaPlugin {
fn build(&self, app: &mut App) {
app.add_message::<TweenCompleted>()
.add_message::<SpringSettled>()
.add_systems(
Update,
(
spanda_tick_tween::<f32>,
spanda_tick_tween::<[f32; 2]>,
spanda_tick_tween::<[f32; 3]>,
spanda_tick_tween::<[f32; 4]>,
spanda_tick_spring,
),
);
}
}
fn spanda_tick_tween<T: Animatable + Send + Sync>(
time: Res<Time>,
mut query: Query<(Entity, &mut Tween<T>)>,
mut events: MessageWriter<TweenCompleted>,
) {
let dt = time.delta_secs();
for (entity, mut tween) in query.iter_mut() {
let was_complete = tween.is_complete();
tween.update(dt);
if !was_complete && tween.is_complete() {
events.write(TweenCompleted { entity });
}
}
}
fn spanda_tick_spring(
time: Res<Time>,
mut query: Query<(Entity, &mut Spring)>,
mut events: MessageWriter<SpringSettled>,
) {
let dt = time.delta_secs();
for (entity, mut spring) in query.iter_mut() {
let was_settled = spring.is_settled();
spring.update(dt);
if !was_settled && spring.is_settled() {
events.write(SpringSettled { entity });
}
}
}