use super::filled_seven_segment;
use super::led_matrix;
#[derive(PartialEq, Eq)]
pub enum AnimationState {
Running,
End
}
pub trait Animation {
fn step(&mut self, seven_segment: &mut filled_seven_segment::FilledSevenSegment, led_matrix: &mut led_matrix::LEDMatrix) -> AnimationState;
fn cleanup(&mut self, seven_segment: &mut filled_seven_segment::FilledSevenSegment, led_matrix: &mut led_matrix::LEDMatrix);
fn running(&self) -> bool;
}
pub struct HelloAnimation {
pub inner_step: u16,
pub outer_step: u16,
pub hidden: bool
}
pub struct WinAnimation {
pub number: u16,
pub led_step: u8,
pub led_quarter: u8,
pub led_inner: u16,
pub hidden: bool
}
const WIN_ANIMATION_MAX_LED_OUTER_STEP: u8 = 5; // max led_step
const WIN_ANIMATION_MAX_LED_STEP: u8 = 4; // add led_step
const WIN_ANIMATION_MAX_LED_INNER_STEP: u16 = 2500; // 10000; // add led_quarter
const HELO_ANIMATION_MAX_INNER_STEP: u16 = 5000; // 20000;
const HELO_ANIMATION_MAX_OUTER_STEP: u16 = 5;
impl WinAnimation {
pub fn create(number: u16) -> WinAnimation {
WinAnimation {
number,
led_inner: 0,
led_quarter: 0,
led_step: 0,
hidden: true
}
}
pub fn reset(&mut self, number: u16) {
self.number = number;
self.led_step = 0;
self.led_quarter = 0;
self.led_inner = 0;
self.hidden = true;
}
}
impl Animation for WinAnimation {
fn step(&mut self, seven_segment: &mut filled_seven_segment::FilledSevenSegment, led_matrix: &mut led_matrix::LEDMatrix) -> AnimationState {
if self.led_inner == 0 && self.led_quarter == 0 && self.led_step == 0 {
seven_segment.set_number(self.number);
led_matrix.clear();
}
if self.led_inner > WIN_ANIMATION_MAX_LED_INNER_STEP {
self.led_inner = 0;
self.led_quarter += 1;
}
if self.led_quarter >= WIN_ANIMATION_MAX_LED_STEP {
self.led_quarter = 0;
self.led_step += 1;
}
if self.led_step > WIN_ANIMATION_MAX_LED_OUTER_STEP {
return AnimationState::End;
}
led_matrix.clear();
if self.led_step < 2 {
led_matrix.set(self.led_quarter, self.led_step, true);
} else if self.led_step == 2 {
led_matrix.set(self.led_quarter, 0, true);
led_matrix.set(self.led_quarter, 1, true);
} else if self.led_step == 3 {
led_matrix.set(3 - self.led_quarter, 0, true);
led_matrix.set(3 - self.led_quarter, 1, true);
} else {
for i in 0..=self.led_quarter {
led_matrix.set(i, 0, true);
led_matrix.set(i, 1, true);
}
}
if (self.led_quarter == 2 || self.led_quarter == 0) && self.led_inner == 0 {
if self.hidden {
seven_segment.show_all_digits();
} else {
seven_segment.hide_all_digits();
}
self.hidden = !self.hidden;
}
self.led_inner += 1;
AnimationState::Running
}
fn cleanup(&mut self, seven_segment: &mut filled_seven_segment::FilledSevenSegment, led_matrix: &mut led_matrix::LEDMatrix) {
led_matrix.set_data(0xFF);
seven_segment.show_all_digits();
}
#[inline]
fn running(&self) -> bool {
self.led_step < WIN_ANIMATION_MAX_LED_OUTER_STEP
}
}
impl HelloAnimation {
pub fn create() -> HelloAnimation {
HelloAnimation {
inner_step: 0,
outer_step: 0,
hidden: false
}
}
}
impl Animation for HelloAnimation {
fn step(&mut self, seven_segment: &mut filled_seven_segment::FilledSevenSegment, led_matrix: &mut led_matrix::LEDMatrix) -> AnimationState {
// Helo text
if self.inner_step == 0 && self.outer_step == 0 {
seven_segment.set_digit(3, Some(72)); // H
seven_segment.set_digit(2, Some(69)); // E
seven_segment.set_digit(1, Some(76)); // L
seven_segment.set_digit(0, Some(79)); // O
led_matrix.set_data(0xFF);
}
if self.inner_step >= HELO_ANIMATION_MAX_INNER_STEP {
self.inner_step = 0;
self.outer_step += 1;
let matrix_data = led_matrix.data();
led_matrix.set_data(!matrix_data);
if self.hidden {
seven_segment.show_all_digits();
} else {
seven_segment.hide_all_digits();
}
self.hidden = !self.hidden;
}
if self.outer_step == HELO_ANIMATION_MAX_OUTER_STEP {
return AnimationState::End
}
self.inner_step += 1;
AnimationState::Running
}
fn cleanup(&mut self, seven_segment: &mut filled_seven_segment::FilledSevenSegment, led_matrix: &mut led_matrix::LEDMatrix) {
led_matrix.clear();
seven_segment.show_all_digits();
}
#[inline]
fn running(&self) -> bool {
self.outer_step < HELO_ANIMATION_MAX_OUTER_STEP
}
}