use std::io::{stdout, Write};
use std::time::{Instant, Duration};
use crossterm::{
self,
event::{self, Event},
QueueableCommand,
style::{Print, PrintStyledContent},
terminal,
cursor
};
use crate::raindrop::{Raindrop, color_algorithms::ColorAlgorithm};
fn create_raindrops<T>(charset: &Vec<char>, color_algorithm: T,
advance_chance:f64, terminal_width: u16, terminal_height: u16)
-> Vec<Raindrop<T>>
where T: ColorAlgorithm
{
let mut raindrop_vec: Vec<Raindrop<T>> = Vec::with_capacity(terminal_width.into());
for _ in 0..terminal_width {
let new_raindrop = Raindrop::new(
charset, color_algorithm, advance_chance, terminal_height);
raindrop_vec.push(new_raindrop);
}
raindrop_vec
}
pub fn anim_loop<T: ColorAlgorithm>(charset: Vec<char>, color_algorithm: T,
advance_chance:f64, target_framerate: usize) -> crossterm::Result<()>
{
assert!(charset.len() > 0, "cannot run anim_loop with empty character set");
assert!(target_framerate > 0,
"cannot run anim_loop at target framerate of zero");
let mut out = stdout();
let (mut term_cols, mut term_rows) = terminal::size()?;
terminal::enable_raw_mode()?;
out.queue(terminal::EnterAlternateScreen)?
.queue(cursor::Hide)?;
let target_frame_duration = Duration::from_secs_f64(1.0/(target_framerate as f64));
let mut raindrop_vector =
create_raindrops(&charset, color_algorithm, advance_chance,
term_cols, term_rows);
let mut start_instant: Instant;
loop {
start_instant = Instant::now();
out.queue(cursor::MoveTo(0,0))?;
for row_index in 0..term_rows {
out.queue(cursor::MoveToRow(row_index + 1))?
.queue(cursor::MoveToColumn(1))?;
for raindrop in raindrop_vector.iter_mut() {
match raindrop.get_styled_char_at_row(row_index) {
None => out.queue(Print(" "))?,
Some(styled_char) => out.queue(PrintStyledContent(styled_char))?
};
}
}
out.flush()?;
for raindrop in raindrop_vector.iter_mut() {
raindrop.advance_animation(term_rows);
}
if event::poll(target_frame_duration.saturating_sub(Instant::now() - start_instant))? {
match event::read()? {
Event::Resize(new_cols, new_rows) => {
term_cols = new_cols;
term_rows = new_rows;
raindrop_vector =
create_raindrops(&charset, color_algorithm,
advance_chance, term_cols, term_rows);
},
_ => break
}
}
}
terminal::disable_raw_mode()?;
out.queue(terminal::LeaveAlternateScreen)?
.queue(cursor::Show)?;
out.flush()?;
Ok(())
}