use std::collections::HashMap;
use std::time::Duration;
use super::{AnimationGroup, KeyframeAnimation, Stagger};
pub struct Choreographer {
groups: HashMap<String, AnimationGroup>,
staggered: HashMap<String, Vec<KeyframeAnimation>>,
}
impl Default for Choreographer {
fn default() -> Self {
Self::new()
}
}
impl Choreographer {
pub fn new() -> Self {
Self {
groups: HashMap::new(),
staggered: HashMap::new(),
}
}
pub fn add_group(&mut self, name: impl Into<String>, group: AnimationGroup) {
self.groups.insert(name.into(), group);
}
pub fn add_staggered<F>(
&mut self,
name: impl Into<String>,
count: usize,
delay: Duration,
create: F,
) where
F: FnMut(usize) -> KeyframeAnimation,
{
let stagger = Stagger::new(count, delay);
let animations = stagger.apply(create);
self.staggered.insert(name.into(), animations);
}
pub fn start(&mut self, name: &str) {
if let Some(group) = self.groups.get_mut(name) {
group.start();
}
if let Some(anims) = self.staggered.get_mut(name) {
for anim in anims {
anim.start();
}
}
}
pub fn update(&mut self) {
for group in self.groups.values_mut() {
group.update();
}
}
pub fn get_staggered(&mut self, name: &str, index: usize, property: &str) -> f32 {
self.staggered
.get_mut(name)
.and_then(|anims| anims.get_mut(index))
.map(|anim| anim.get(property))
.unwrap_or(0.0)
}
pub fn is_completed(&self, name: &str) -> bool {
if let Some(group) = self.groups.get(name) {
return group.is_completed();
}
if let Some(anims) = self.staggered.get(name) {
return anims.iter().all(|a| a.is_completed());
}
true
}
}