2023-11-27 23:51:36 +00:00
|
|
|
#![no_std]
|
|
|
|
|
|
|
|
extern crate alloc;
|
|
|
|
use alloc::boxed::Box;
|
2023-11-28 01:35:45 +00:00
|
|
|
use az::*;
|
2023-12-14 23:00:45 +00:00
|
|
|
use core::{
|
|
|
|
clone::Clone,
|
|
|
|
cmp::PartialEq,
|
|
|
|
default::Default,
|
|
|
|
ops::{Add, Sub},
|
|
|
|
option::Option,
|
|
|
|
};
|
2023-12-14 17:41:13 +00:00
|
|
|
use fixed::types::{I48F16, I8F8, U128F0, U16F0};
|
2023-11-27 23:51:36 +00:00
|
|
|
|
2023-11-27 01:57:28 +00:00
|
|
|
mod patterns;
|
|
|
|
pub use patterns::*;
|
|
|
|
|
|
|
|
mod types;
|
2023-11-28 01:35:45 +00:00
|
|
|
pub use types::{BodyPattern, DashboardPattern, RGB};
|
|
|
|
|
|
|
|
fn calculate_frames(starting_time: U128F0, now: U128F0) -> U16F0 {
|
|
|
|
let frames_128 = (now - starting_time) / U128F0::from(FPS);
|
|
|
|
(frames_128 % U128F0::from(U16F0::MAX)).cast()
|
|
|
|
}
|
|
|
|
|
|
|
|
fn calculate_slope(start: I8F8, end: I8F8, frames: U16F0) -> I8F8 {
|
|
|
|
let slope_i16f16 = (I48F16::from(end) - I48F16::from(start)) / I48F16::from(frames);
|
|
|
|
slope_i16f16.saturating_as()
|
|
|
|
}
|
|
|
|
|
|
|
|
fn linear_ease(value: I8F8, frames: U16F0, slope: I8F8) -> I8F8 {
|
|
|
|
let value_i16f16 = I48F16::from(value) + I48F16::from(frames) * I48F16::from(slope);
|
|
|
|
value_i16f16.saturating_as()
|
|
|
|
}
|
2023-11-27 01:57:28 +00:00
|
|
|
|
2023-12-29 21:15:25 +00:00
|
|
|
#[derive(Clone, Copy, PartialOrd, Ord, PartialEq, Eq)]
|
2023-11-28 01:35:45 +00:00
|
|
|
pub struct Instant(pub U128F0);
|
2023-11-27 23:51:36 +00:00
|
|
|
|
2023-12-14 23:00:45 +00:00
|
|
|
impl Default for Instant {
|
|
|
|
fn default() -> Self {
|
|
|
|
Self(U128F0::from(0 as u8))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Add for Instant {
|
|
|
|
type Output = Self;
|
|
|
|
|
|
|
|
fn add(self, r: Self) -> Self::Output {
|
|
|
|
Self(self.0 + r.0)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-27 23:51:36 +00:00
|
|
|
impl Sub for Instant {
|
|
|
|
type Output = Self;
|
|
|
|
|
|
|
|
fn sub(self, r: Self) -> Self::Output {
|
|
|
|
Self(self.0 - r.0)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-27 04:30:45 +00:00
|
|
|
pub const FPS: u8 = 30;
|
|
|
|
|
2023-11-27 01:57:28 +00:00
|
|
|
pub trait UI {
|
2023-12-29 21:15:25 +00:00
|
|
|
fn check_event(&mut self, current_time: Instant) -> Option<Event>;
|
2023-11-28 01:35:45 +00:00
|
|
|
fn update_lights(&self, dashboard_lights: DashboardPattern, body_lights: BodyPattern);
|
2023-11-27 01:57:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub trait Animation {
|
2023-11-28 01:35:45 +00:00
|
|
|
fn tick(&mut self, time: Instant) -> (DashboardPattern, BodyPattern);
|
2023-11-27 01:57:28 +00:00
|
|
|
}
|
|
|
|
|
2023-12-29 22:51:15 +00:00
|
|
|
/*
|
2023-11-27 01:57:28 +00:00
|
|
|
pub struct DefaultAnimation {}
|
|
|
|
|
|
|
|
impl Animation for DefaultAnimation {
|
2023-11-28 01:35:45 +00:00
|
|
|
fn tick(&mut self, _: Instant) -> (DashboardPattern, BodyPattern) {
|
2023-12-29 22:51:15 +00:00
|
|
|
(WATER_DASHBOARD, WATER_BODY)
|
2023-11-27 01:57:28 +00:00
|
|
|
}
|
|
|
|
}
|
2023-12-29 22:51:15 +00:00
|
|
|
*/
|
2023-11-27 01:57:28 +00:00
|
|
|
|
2023-11-27 04:30:45 +00:00
|
|
|
pub struct Fade {
|
|
|
|
starting_dashboard: DashboardPattern,
|
2023-11-28 01:35:45 +00:00
|
|
|
starting_lights: BodyPattern,
|
2023-11-27 04:30:45 +00:00
|
|
|
|
2023-11-27 23:51:36 +00:00
|
|
|
start_time: Instant,
|
2023-11-28 01:35:45 +00:00
|
|
|
dashboard_slope: [RGB<I8F8>; 3],
|
|
|
|
body_slope: [RGB<I8F8>; 60],
|
|
|
|
frames: U16F0,
|
2023-11-27 04:30:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Fade {
|
|
|
|
fn new(
|
|
|
|
dashboard: DashboardPattern,
|
2023-11-28 01:35:45 +00:00
|
|
|
lights: BodyPattern,
|
2023-11-27 04:30:45 +00:00
|
|
|
ending_dashboard: DashboardPattern,
|
2023-11-28 01:35:45 +00:00
|
|
|
ending_lights: BodyPattern,
|
|
|
|
frames: U16F0,
|
2023-11-27 23:51:36 +00:00
|
|
|
time: Instant,
|
2023-11-27 04:30:45 +00:00
|
|
|
) -> Self {
|
2023-11-27 23:51:36 +00:00
|
|
|
let mut dashboard_slope = [Default::default(); 3];
|
|
|
|
let mut body_slope = [Default::default(); 60];
|
2023-11-27 04:30:45 +00:00
|
|
|
for i in 0..3 {
|
|
|
|
let slope = RGB {
|
2023-11-28 01:35:45 +00:00
|
|
|
r: calculate_slope(dashboard[i].r, ending_dashboard[i].r, frames),
|
|
|
|
g: calculate_slope(dashboard[i].g, ending_dashboard[i].g, frames),
|
|
|
|
b: calculate_slope(dashboard[i].b, ending_dashboard[i].b, frames),
|
2023-11-27 04:30:45 +00:00
|
|
|
};
|
2023-11-27 23:51:36 +00:00
|
|
|
dashboard_slope[i] = slope;
|
2023-11-27 04:30:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
for i in 0..60 {
|
|
|
|
let slope = RGB {
|
2023-11-28 01:35:45 +00:00
|
|
|
r: calculate_slope(lights[i].r, ending_lights[i].r, frames),
|
|
|
|
g: calculate_slope(lights[i].g, ending_lights[i].g, frames),
|
|
|
|
b: calculate_slope(lights[i].b, ending_lights[i].b, frames),
|
2023-11-27 04:30:45 +00:00
|
|
|
};
|
2023-11-27 23:51:36 +00:00
|
|
|
body_slope[i] = slope;
|
2023-11-27 04:30:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Self {
|
|
|
|
starting_dashboard: dashboard,
|
|
|
|
starting_lights: lights,
|
|
|
|
start_time: time,
|
|
|
|
dashboard_slope,
|
|
|
|
body_slope,
|
|
|
|
frames,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Animation for Fade {
|
2023-11-28 01:35:45 +00:00
|
|
|
fn tick(&mut self, time: Instant) -> (DashboardPattern, BodyPattern) {
|
|
|
|
let mut frames = calculate_frames(self.start_time.0, time.0);
|
2023-11-27 04:30:45 +00:00
|
|
|
if frames > self.frames {
|
|
|
|
frames = self.frames
|
|
|
|
}
|
|
|
|
let mut dashboard_pattern: DashboardPattern = OFF_DASHBOARD;
|
2023-11-28 01:35:45 +00:00
|
|
|
let mut body_pattern: BodyPattern = OFF_BODY;
|
2023-11-27 04:30:45 +00:00
|
|
|
|
|
|
|
for i in 0..3 {
|
2023-11-28 01:35:45 +00:00
|
|
|
dashboard_pattern[i].r = linear_ease(
|
|
|
|
self.starting_dashboard[i].r,
|
|
|
|
frames,
|
|
|
|
self.dashboard_slope[i].r,
|
|
|
|
);
|
|
|
|
dashboard_pattern[i].g = linear_ease(
|
|
|
|
self.starting_dashboard[i].g,
|
|
|
|
frames,
|
|
|
|
self.dashboard_slope[i].g,
|
|
|
|
);
|
|
|
|
dashboard_pattern[i].b = linear_ease(
|
|
|
|
self.starting_dashboard[i].b,
|
|
|
|
frames,
|
|
|
|
self.dashboard_slope[i].b,
|
|
|
|
);
|
2023-11-27 04:30:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
for i in 0..60 {
|
2023-11-28 01:35:45 +00:00
|
|
|
body_pattern[i].r =
|
|
|
|
linear_ease(self.starting_lights[i].r, frames, self.body_slope[i].r);
|
|
|
|
body_pattern[i].g =
|
|
|
|
linear_ease(self.starting_lights[i].g, frames, self.body_slope[i].g);
|
|
|
|
body_pattern[i].b =
|
|
|
|
linear_ease(self.starting_lights[i].b, frames, self.body_slope[i].b);
|
2023-11-27 04:30:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
(dashboard_pattern, body_pattern)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub enum FadeDirection {
|
2023-12-15 03:03:51 +00:00
|
|
|
Transition,
|
2023-11-27 04:30:45 +00:00
|
|
|
FadeIn,
|
|
|
|
FadeOut,
|
|
|
|
}
|
|
|
|
|
2023-11-27 14:37:36 +00:00
|
|
|
pub enum BlinkerDirection {
|
|
|
|
Left,
|
|
|
|
Right,
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct Blinker {
|
2023-12-15 03:03:51 +00:00
|
|
|
transition: Fade,
|
2023-11-27 04:30:45 +00:00
|
|
|
fade_in: Fade,
|
|
|
|
fade_out: Fade,
|
|
|
|
direction: FadeDirection,
|
|
|
|
|
2023-11-27 23:51:36 +00:00
|
|
|
start_time: Instant,
|
2023-11-28 01:35:45 +00:00
|
|
|
frames: U16F0,
|
2023-11-27 04:30:45 +00:00
|
|
|
}
|
|
|
|
|
2023-11-27 14:37:36 +00:00
|
|
|
impl Blinker {
|
2023-11-27 04:30:45 +00:00
|
|
|
fn new(
|
|
|
|
starting_dashboard: DashboardPattern,
|
2023-11-28 01:35:45 +00:00
|
|
|
starting_body: BodyPattern,
|
2023-11-27 14:37:36 +00:00
|
|
|
direction: BlinkerDirection,
|
2023-11-27 23:51:36 +00:00
|
|
|
time: Instant,
|
2023-11-27 04:30:45 +00:00
|
|
|
) -> Self {
|
2023-12-29 21:15:25 +00:00
|
|
|
let mut ending_dashboard = OFF_DASHBOARD.clone();
|
2023-11-27 14:37:36 +00:00
|
|
|
|
|
|
|
match direction {
|
|
|
|
BlinkerDirection::Left => {
|
2023-11-28 01:35:45 +00:00
|
|
|
ending_dashboard[0].r = LEFT_BLINKER_DASHBOARD[0].r;
|
|
|
|
ending_dashboard[0].g = LEFT_BLINKER_DASHBOARD[0].g;
|
|
|
|
ending_dashboard[0].b = LEFT_BLINKER_DASHBOARD[0].b;
|
2023-11-27 14:37:36 +00:00
|
|
|
}
|
|
|
|
BlinkerDirection::Right => {
|
2023-11-28 01:35:45 +00:00
|
|
|
ending_dashboard[2].r = RIGHT_BLINKER_DASHBOARD[2].r;
|
|
|
|
ending_dashboard[2].g = RIGHT_BLINKER_DASHBOARD[2].g;
|
|
|
|
ending_dashboard[2].b = RIGHT_BLINKER_DASHBOARD[2].b;
|
2023-11-27 14:37:36 +00:00
|
|
|
}
|
|
|
|
}
|
2023-11-27 04:30:45 +00:00
|
|
|
|
2023-12-29 21:15:25 +00:00
|
|
|
let mut ending_body = OFF_BODY.clone();
|
2023-11-27 14:37:36 +00:00
|
|
|
match direction {
|
|
|
|
BlinkerDirection::Left => {
|
|
|
|
for i in 0..30 {
|
2023-11-28 01:35:45 +00:00
|
|
|
ending_body[i].r = LEFT_BLINKER_BODY[i].r;
|
|
|
|
ending_body[i].g = LEFT_BLINKER_BODY[i].g;
|
|
|
|
ending_body[i].b = LEFT_BLINKER_BODY[i].b;
|
2023-11-27 14:37:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
BlinkerDirection::Right => {
|
|
|
|
for i in 30..60 {
|
2023-11-28 01:35:45 +00:00
|
|
|
ending_body[i].r = RIGHT_BLINKER_BODY[i].r;
|
|
|
|
ending_body[i].g = RIGHT_BLINKER_BODY[i].g;
|
|
|
|
ending_body[i].b = RIGHT_BLINKER_BODY[i].b;
|
2023-11-27 14:37:36 +00:00
|
|
|
}
|
|
|
|
}
|
2023-11-27 04:30:45 +00:00
|
|
|
}
|
|
|
|
|
2023-11-27 14:37:36 +00:00
|
|
|
Blinker {
|
2023-12-15 03:03:51 +00:00
|
|
|
transition: Fade::new(
|
2023-11-27 04:30:45 +00:00
|
|
|
starting_dashboard.clone(),
|
|
|
|
starting_body.clone(),
|
|
|
|
ending_dashboard.clone(),
|
|
|
|
ending_body.clone(),
|
2023-11-27 14:37:36 +00:00
|
|
|
BLINKER_FRAMES,
|
2023-11-27 04:30:45 +00:00
|
|
|
time,
|
|
|
|
),
|
2023-12-15 03:03:51 +00:00
|
|
|
fade_in: Fade::new(
|
2023-12-29 21:15:25 +00:00
|
|
|
OFF_DASHBOARD.clone(),
|
|
|
|
OFF_BODY.clone(),
|
2023-12-15 03:03:51 +00:00
|
|
|
ending_dashboard.clone(),
|
|
|
|
ending_body.clone(),
|
|
|
|
BLINKER_FRAMES,
|
|
|
|
time,
|
|
|
|
),
|
2023-11-27 04:30:45 +00:00
|
|
|
fade_out: Fade::new(
|
|
|
|
ending_dashboard.clone(),
|
|
|
|
ending_body.clone(),
|
2023-12-29 21:15:25 +00:00
|
|
|
OFF_DASHBOARD.clone(),
|
|
|
|
OFF_BODY.clone(),
|
2023-11-27 14:37:36 +00:00
|
|
|
BLINKER_FRAMES,
|
2023-11-27 04:30:45 +00:00
|
|
|
time,
|
|
|
|
),
|
2023-12-15 03:03:51 +00:00
|
|
|
direction: FadeDirection::Transition,
|
2023-11-27 04:30:45 +00:00
|
|
|
start_time: time,
|
2023-11-27 14:37:36 +00:00
|
|
|
frames: BLINKER_FRAMES,
|
2023-11-27 04:30:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-27 14:37:36 +00:00
|
|
|
impl Animation for Blinker {
|
2023-11-28 01:35:45 +00:00
|
|
|
fn tick(&mut self, time: Instant) -> (DashboardPattern, BodyPattern) {
|
|
|
|
let frames = calculate_frames(self.start_time.0, time.0);
|
2023-11-27 04:30:45 +00:00
|
|
|
if frames > self.frames {
|
|
|
|
match self.direction {
|
2023-12-15 03:03:51 +00:00
|
|
|
FadeDirection::Transition => {
|
|
|
|
self.direction = FadeDirection::FadeOut;
|
|
|
|
self.fade_out.start_time = time;
|
|
|
|
}
|
2023-11-27 04:30:45 +00:00
|
|
|
FadeDirection::FadeIn => {
|
|
|
|
self.direction = FadeDirection::FadeOut;
|
|
|
|
self.fade_out.start_time = time;
|
|
|
|
}
|
|
|
|
FadeDirection::FadeOut => {
|
|
|
|
self.direction = FadeDirection::FadeIn;
|
|
|
|
self.fade_in.start_time = time;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
self.start_time = time;
|
|
|
|
}
|
|
|
|
|
|
|
|
match self.direction {
|
2023-12-15 03:03:51 +00:00
|
|
|
FadeDirection::Transition => self.transition.tick(time),
|
2023-11-27 04:30:45 +00:00
|
|
|
FadeDirection::FadeIn => self.fade_in.tick(time),
|
|
|
|
FadeDirection::FadeOut => self.fade_out.tick(time),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-27 02:19:09 +00:00
|
|
|
#[derive(Clone, Debug)]
|
2023-11-27 01:57:28 +00:00
|
|
|
pub enum Event {
|
|
|
|
Brake,
|
|
|
|
BrakeRelease,
|
|
|
|
LeftBlinker,
|
|
|
|
NextPattern,
|
|
|
|
PreviousPattern,
|
|
|
|
RightBlinker,
|
|
|
|
}
|
|
|
|
|
2023-12-29 22:51:15 +00:00
|
|
|
#[derive(Clone, Copy, Debug, PartialEq)]
|
2023-12-15 03:03:51 +00:00
|
|
|
pub enum Pattern {
|
2023-12-29 22:51:15 +00:00
|
|
|
Water,
|
2023-12-15 03:03:51 +00:00
|
|
|
GayPride,
|
|
|
|
TransPride,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Pattern {
|
|
|
|
fn previous(&self) -> Pattern {
|
|
|
|
match self {
|
2023-12-29 22:51:15 +00:00
|
|
|
Pattern::Water => Pattern::TransPride,
|
|
|
|
Pattern::GayPride => Pattern::Water,
|
2023-12-15 03:03:51 +00:00
|
|
|
Pattern::TransPride => Pattern::GayPride,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn next(&self) -> Pattern {
|
|
|
|
match self {
|
2023-12-29 22:51:15 +00:00
|
|
|
Pattern::Water => Pattern::GayPride,
|
2023-12-15 03:03:51 +00:00
|
|
|
Pattern::GayPride => Pattern::TransPride,
|
2023-12-29 22:51:15 +00:00
|
|
|
Pattern::TransPride => Pattern::Water,
|
2023-12-15 03:03:51 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn dashboard(&self) -> DashboardPattern {
|
|
|
|
match self {
|
2023-12-29 22:51:15 +00:00
|
|
|
Pattern::Water => WATER_DASHBOARD,
|
2023-12-15 03:03:51 +00:00
|
|
|
Pattern::GayPride => PRIDE_DASHBOARD,
|
|
|
|
Pattern::TransPride => TRANS_PRIDE_DASHBOARD,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn body(&self) -> BodyPattern {
|
|
|
|
match self {
|
2024-11-08 14:44:13 +00:00
|
|
|
Pattern::Water => WATER_BODY,
|
2023-12-15 03:03:51 +00:00
|
|
|
Pattern::GayPride => PRIDE_BODY,
|
|
|
|
Pattern::TransPride => TRANS_PRIDE_BODY,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-12-29 22:51:15 +00:00
|
|
|
#[derive(Clone, Debug, PartialEq)]
|
2023-11-27 01:57:28 +00:00
|
|
|
pub enum State {
|
2023-12-15 03:03:51 +00:00
|
|
|
Pattern(Pattern),
|
2023-11-27 01:57:28 +00:00
|
|
|
Brake,
|
|
|
|
LeftBlinker,
|
|
|
|
RightBlinker,
|
|
|
|
BrakeLeftBlinker,
|
|
|
|
BrakeRightBlinker,
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct App {
|
|
|
|
ui: Box<dyn UI>,
|
|
|
|
state: State,
|
2023-12-15 03:03:51 +00:00
|
|
|
home_pattern: Pattern,
|
2023-11-27 01:57:28 +00:00
|
|
|
current_animation: Box<dyn Animation>,
|
|
|
|
dashboard_lights: DashboardPattern,
|
2023-11-28 01:35:45 +00:00
|
|
|
lights: BodyPattern,
|
2023-11-26 18:03:19 +00:00
|
|
|
}
|
|
|
|
|
2023-11-27 01:57:28 +00:00
|
|
|
impl App {
|
|
|
|
pub fn new(ui: Box<dyn UI>) -> Self {
|
2023-12-29 22:51:15 +00:00
|
|
|
let pattern = Pattern::Water;
|
2023-11-27 01:57:28 +00:00
|
|
|
Self {
|
|
|
|
ui,
|
2023-12-29 22:51:15 +00:00
|
|
|
state: State::Pattern(pattern),
|
|
|
|
home_pattern: pattern,
|
|
|
|
current_animation: Box::new(Fade::new(
|
|
|
|
OFF_DASHBOARD,
|
|
|
|
OFF_BODY,
|
|
|
|
pattern.dashboard(),
|
|
|
|
pattern.body(),
|
|
|
|
DEFAULT_FRAMES,
|
|
|
|
Instant((0 as u32).into()),
|
|
|
|
)),
|
2023-11-27 01:57:28 +00:00
|
|
|
dashboard_lights: OFF_DASHBOARD,
|
2023-11-28 01:35:45 +00:00
|
|
|
lights: OFF_BODY,
|
2023-11-27 01:57:28 +00:00
|
|
|
}
|
|
|
|
}
|
2023-11-26 18:03:19 +00:00
|
|
|
|
2023-11-27 23:51:36 +00:00
|
|
|
fn update_animation(&mut self, time: Instant) {
|
2023-11-27 04:30:45 +00:00
|
|
|
match self.state {
|
2023-12-15 03:03:51 +00:00
|
|
|
State::Pattern(ref pattern) => {
|
2023-11-27 04:30:45 +00:00
|
|
|
self.current_animation = Box::new(Fade::new(
|
|
|
|
self.dashboard_lights.clone(),
|
|
|
|
self.lights.clone(),
|
2023-12-15 03:03:51 +00:00
|
|
|
pattern.dashboard(),
|
|
|
|
pattern.body(),
|
2023-11-27 04:30:45 +00:00
|
|
|
DEFAULT_FRAMES,
|
|
|
|
time,
|
|
|
|
))
|
|
|
|
}
|
|
|
|
State::Brake => {
|
|
|
|
self.current_animation = Box::new(Fade::new(
|
|
|
|
self.dashboard_lights.clone(),
|
|
|
|
self.lights.clone(),
|
2023-11-28 01:35:45 +00:00
|
|
|
BRAKES_DASHBOARD,
|
|
|
|
BRAKES_BODY,
|
|
|
|
BRAKES_FRAMES,
|
2023-11-27 04:30:45 +00:00
|
|
|
time,
|
|
|
|
));
|
|
|
|
}
|
|
|
|
State::LeftBlinker => {
|
2023-11-27 14:37:36 +00:00
|
|
|
self.current_animation = Box::new(Blinker::new(
|
2023-11-27 04:30:45 +00:00
|
|
|
self.dashboard_lights.clone(),
|
|
|
|
self.lights.clone(),
|
2023-11-27 14:37:36 +00:00
|
|
|
BlinkerDirection::Left,
|
|
|
|
time,
|
|
|
|
));
|
|
|
|
}
|
|
|
|
State::RightBlinker => {
|
|
|
|
self.current_animation = Box::new(Blinker::new(
|
|
|
|
self.dashboard_lights.clone(),
|
|
|
|
self.lights.clone(),
|
|
|
|
BlinkerDirection::Right,
|
2023-11-27 04:30:45 +00:00
|
|
|
time,
|
|
|
|
));
|
|
|
|
}
|
|
|
|
State::BrakeLeftBlinker => (),
|
|
|
|
State::BrakeRightBlinker => (),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-27 14:37:36 +00:00
|
|
|
fn update_state(&mut self, event: Event) {
|
|
|
|
match event {
|
|
|
|
Event::Brake => {
|
|
|
|
if self.state == State::Brake {
|
2023-12-15 03:03:51 +00:00
|
|
|
self.state = State::Pattern(self.home_pattern);
|
2023-11-27 14:37:36 +00:00
|
|
|
} else {
|
|
|
|
self.state = State::Brake;
|
|
|
|
}
|
|
|
|
}
|
2023-12-15 03:03:51 +00:00
|
|
|
Event::BrakeRelease => self.state = State::Pattern(self.home_pattern),
|
2023-11-27 14:37:36 +00:00
|
|
|
Event::LeftBlinker => match self.state {
|
|
|
|
State::Brake => self.state = State::BrakeLeftBlinker,
|
|
|
|
State::BrakeLeftBlinker => self.state = State::Brake,
|
2023-12-15 03:03:51 +00:00
|
|
|
State::LeftBlinker => self.state = State::Pattern(self.home_pattern),
|
2023-11-27 14:37:36 +00:00
|
|
|
_ => self.state = State::LeftBlinker,
|
|
|
|
},
|
|
|
|
Event::NextPattern => match self.state {
|
2023-12-15 03:03:51 +00:00
|
|
|
State::Pattern(ref pattern) => {
|
|
|
|
self.home_pattern = pattern.next();
|
|
|
|
self.state = State::Pattern(self.home_pattern);
|
2023-11-27 14:37:36 +00:00
|
|
|
}
|
|
|
|
_ => (),
|
|
|
|
},
|
|
|
|
Event::PreviousPattern => match self.state {
|
2023-12-15 03:03:51 +00:00
|
|
|
State::Pattern(ref pattern) => {
|
|
|
|
self.home_pattern = pattern.previous();
|
|
|
|
self.state = State::Pattern(self.home_pattern);
|
2023-11-27 14:37:36 +00:00
|
|
|
}
|
|
|
|
_ => (),
|
|
|
|
},
|
|
|
|
Event::RightBlinker => match self.state {
|
|
|
|
State::Brake => self.state = State::BrakeRightBlinker,
|
|
|
|
State::BrakeRightBlinker => self.state = State::Brake,
|
2023-12-15 03:03:51 +00:00
|
|
|
State::RightBlinker => self.state = State::Pattern(self.home_pattern),
|
2023-11-27 14:37:36 +00:00
|
|
|
_ => self.state = State::RightBlinker,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-27 23:51:36 +00:00
|
|
|
pub fn tick(&mut self, time: Instant) {
|
2023-12-29 21:15:25 +00:00
|
|
|
match self.ui.check_event(time) {
|
2023-11-27 04:30:45 +00:00
|
|
|
Some(event) => {
|
2023-11-27 14:37:36 +00:00
|
|
|
self.update_state(event);
|
|
|
|
self.update_animation(time);
|
2023-11-27 04:30:45 +00:00
|
|
|
}
|
|
|
|
None => {}
|
2023-11-27 02:19:09 +00:00
|
|
|
};
|
2023-11-27 04:30:45 +00:00
|
|
|
|
2023-11-27 02:19:09 +00:00
|
|
|
let (dashboard, lights) = self.current_animation.tick(time);
|
2023-11-27 01:57:28 +00:00
|
|
|
self.dashboard_lights = dashboard.clone();
|
|
|
|
self.lights = lights.clone();
|
|
|
|
self.ui.update_lights(dashboard, lights);
|
2023-11-26 18:03:19 +00:00
|
|
|
}
|
|
|
|
}
|