use tiny_led_matrix::Render;
pub trait Animate {
fn is_finished(&self) -> bool;
fn reset(&mut self);
fn tick(&mut self);
}
#[derive(Default)]
#[derive(Copy, Clone, Debug)]
pub struct ScrollingState {
index: usize,
pixel: usize,
}
impl ScrollingState {
pub fn reset(&mut self) {
self.index = 0;
self.pixel = 0;
}
pub fn tick(&mut self) {
self.pixel += 1;
if self.pixel == 5 {
self.pixel = 0;
self.index += 1;
}
}
}
pub trait Scrollable {
type Subimage: Render;
fn length(&self) -> usize;
fn state(&self) -> &ScrollingState;
fn state_mut(&mut self) -> &mut ScrollingState;
fn subimage(&self, index: usize) -> &Self::Subimage;
fn current_brightness_at(&self, x: usize, y: usize) -> u8 {
if self.state().index > self.length() {return 0}
let state = self.state();
let (index, x) = if x + state.pixel < 5 {
if state.index == 0 {return 0}
(state.index - 1, x + state.pixel)
} else {
if state.index == self.length() {return 0}
(state.index, x + state.pixel - 5)
};
self.subimage(index).brightness_at(x, y)
}
}
impl<T : Scrollable> Animate for T {
fn is_finished(&self) -> bool {
self.state().index > self.length()
}
fn reset(&mut self) {
self.state_mut().reset();
}
fn tick(&mut self) {
if !self.is_finished() {
self.state_mut().tick();
}
}
}