use firework::{types::Drawables, Firework};
use rand::{rngs::StdRng, Rng, SeedableRng};
use crate::firework;
pub struct StateMachine {
rng: StdRng,
fireworks: Vec<Firework>,
}
impl StateMachine {
pub fn new(seed: u64, term_height: u16) -> Self {
let rng = StdRng::seed_from_u64(seed);
StateMachine {
fireworks: vec![Firework::new(rng.clone(), term_height)], rng,
}
}
pub fn tick(&mut self, term_height: u16) -> Drawables {
self.gc_old_fireworks();
self.maybe_add_firework(term_height);
self.update_fireworks();
self.collect_drawables()
}
fn update_fireworks(&mut self) {
for firework in self.fireworks.iter_mut() {
firework.advance();
}
}
fn collect_drawables(&self) -> Drawables {
self
.fireworks
.iter()
.map(|firework| firework.drawables())
.flatten()
.collect::<Drawables>()
}
fn maybe_add_firework(&mut self, term_height: u16) {
if self.should_gen_firework() {
self
.fireworks
.push(Firework::new(self.rng.clone(), term_height));
}
}
fn should_gen_firework(&mut self) -> bool {
self.rng.gen_range(0, 100) <= 10
}
fn gc_old_fireworks(&mut self) {
let gcable_fireworks = self.gcable_firework_idx();
if gcable_fireworks > 0 {
self.fireworks.drain(..gcable_fireworks);
}
}
fn gcable_firework_idx(&self) -> usize {
let mut gcable_count = 0;
for firework in self.fireworks.iter() {
if firework.extinguished() {
gcable_count += 1;
} else {
break;
}
}
gcable_count
}
}