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 } }