From 0b949111d20f68331dbecb47d1e69580b9495105 Mon Sep 17 00:00:00 2001 From: Savanni D'Gerinel Date: Mon, 27 Nov 2023 20:35:45 -0500 Subject: [PATCH] Switch to a fixed point arithmatic library --- Cargo.lock | 4 + bike-lights/core/Cargo.toml | 2 + bike-lights/core/src/lib.rs | 160 ++-- bike-lights/core/src/patterns.rs | 1413 ++++++----------------------- bike-lights/core/src/types.rs | 34 +- bike-lights/simulator/src/main.rs | 112 +-- 6 files changed, 401 insertions(+), 1324 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c3142d1..2d6a554 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2337,6 +2337,10 @@ dependencies = [ [[package]] name = "lights-core" version = "0.1.0" +dependencies = [ + "az", + "fixed", +] [[package]] name = "linux-raw-sys" diff --git a/bike-lights/core/Cargo.toml b/bike-lights/core/Cargo.toml index 4c709a8..be3f09e 100644 --- a/bike-lights/core/Cargo.toml +++ b/bike-lights/core/Cargo.toml @@ -6,3 +6,5 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +az = { version = "1" } +fixed = { version = "1" } diff --git a/bike-lights/core/src/lib.rs b/bike-lights/core/src/lib.rs index ab87421..c8523eb 100644 --- a/bike-lights/core/src/lib.rs +++ b/bike-lights/core/src/lib.rs @@ -2,16 +2,33 @@ extern crate alloc; use alloc::boxed::Box; +use az::*; use core::{clone::Clone, cmp::PartialEq, ops::Sub, option::Option}; +use fixed::types::{I16F0, I16F16, I48F16, I8F8, U128F0, U16F0}; mod patterns; pub use patterns::*; mod types; -pub use types::{DashboardPattern, Pattern, RGB}; +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() +} #[derive(Clone, Copy)] -pub struct Instant(pub u128); +pub struct Instant(pub U128F0); impl Sub for Instant { type Output = Self; @@ -25,56 +42,56 @@ pub const FPS: u8 = 30; pub trait UI { fn check_event(&self) -> Option; - fn update_lights(&self, dashboard_lights: DashboardPattern, lights: Pattern); + fn update_lights(&self, dashboard_lights: DashboardPattern, body_lights: BodyPattern); } pub trait Animation { - fn tick(&mut self, time: Instant) -> (DashboardPattern, Pattern); + fn tick(&mut self, time: Instant) -> (DashboardPattern, BodyPattern); } pub struct DefaultAnimation {} impl Animation for DefaultAnimation { - fn tick(&mut self, _: Instant) -> (DashboardPattern, Pattern) { - (PRIDE_DASHBOARD, PRIDE) + fn tick(&mut self, _: Instant) -> (DashboardPattern, BodyPattern) { + (PRIDE_DASHBOARD, PRIDE_BODY) } } pub struct Fade { starting_dashboard: DashboardPattern, - starting_lights: Pattern, + starting_lights: BodyPattern, start_time: Instant, - dashboard_slope: [RGB; 3], - body_slope: [RGB; 60], - frames: u8, + dashboard_slope: [RGB; 3], + body_slope: [RGB; 60], + frames: U16F0, } impl Fade { fn new( dashboard: DashboardPattern, - lights: Pattern, + lights: BodyPattern, ending_dashboard: DashboardPattern, - ending_lights: Pattern, - frames: u8, + ending_lights: BodyPattern, + frames: U16F0, time: Instant, ) -> Self { let mut dashboard_slope = [Default::default(); 3]; let mut body_slope = [Default::default(); 60]; for i in 0..3 { let slope = RGB { - r: (ending_dashboard[i].r as f64 - dashboard[i].r as f64) / frames as f64, - g: (ending_dashboard[i].g as f64 - dashboard[i].g as f64) / frames as f64, - b: (ending_dashboard[i].b as f64 - dashboard[i].b as f64) / frames as f64, + 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), }; dashboard_slope[i] = slope; } for i in 0..60 { let slope = RGB { - r: (ending_lights[i].r as f64 - lights[i].r as f64) / frames as f64, - g: (ending_lights[i].g as f64 - lights[i].g as f64) / frames as f64, - b: (ending_lights[i].b as f64 - lights[i].b as f64) / frames as f64, + 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), }; body_slope[i] = slope; } @@ -91,50 +108,39 @@ impl Fade { } impl Animation for Fade { - fn tick(&mut self, time: Instant) -> (DashboardPattern, Pattern) { - let mut frames: u8 = ((time - self.start_time).0 as f64 / FPS as f64) as u8; + fn tick(&mut self, time: Instant) -> (DashboardPattern, BodyPattern) { + let mut frames = calculate_frames(self.start_time.0, time.0); if frames > self.frames { frames = self.frames } let mut dashboard_pattern: DashboardPattern = OFF_DASHBOARD; - let mut body_pattern: Pattern = OFF; - - let apply = |value: f64, frames: f64, slope: f64| -> f64 { value + frames * slope }; + let mut body_pattern: BodyPattern = OFF_BODY; for i in 0..3 { - dashboard_pattern[i].r = apply( - self.starting_dashboard[i].r as f64, - frames as f64, - self.dashboard_slope[i].r as f64, - ) as u8; - dashboard_pattern[i].g = apply( - self.starting_dashboard[i].g as f64, - frames as f64, - self.dashboard_slope[i].g as f64, - ) as u8; - dashboard_pattern[i].b = apply( - self.starting_dashboard[i].b as f64, - frames as f64, - self.dashboard_slope[i].b as f64, - ) as u8; + 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, + ); } for i in 0..60 { - body_pattern[i].r = apply( - self.starting_lights[i].r as f64, - frames as f64, - self.body_slope[i].r as f64, - ) as u8; - body_pattern[i].g = apply( - self.starting_lights[i].g as f64, - frames as f64, - self.body_slope[i].g as f64, - ) as u8; - body_pattern[i].b = apply( - self.starting_lights[i].b as f64, - frames as f64, - self.body_slope[i].b as f64, - ) as u8; + 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); } (dashboard_pattern, body_pattern) @@ -158,13 +164,13 @@ pub struct Blinker { direction: FadeDirection, start_time: Instant, - frames: u8, + frames: U16F0, } impl Blinker { fn new( starting_dashboard: DashboardPattern, - starting_body: Pattern, + starting_body: BodyPattern, direction: BlinkerDirection, time: Instant, ) -> Self { @@ -172,14 +178,14 @@ impl Blinker { match direction { BlinkerDirection::Left => { - ending_dashboard[0].r = LEFT_DASHBOARD[0].r; - ending_dashboard[0].g = LEFT_DASHBOARD[0].g; - ending_dashboard[0].b = LEFT_DASHBOARD[0].b; + 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; } BlinkerDirection::Right => { - ending_dashboard[2].r = RIGHT_DASHBOARD[2].r; - ending_dashboard[2].g = RIGHT_DASHBOARD[2].g; - ending_dashboard[2].b = RIGHT_DASHBOARD[2].b; + 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; } } @@ -187,16 +193,16 @@ impl Blinker { match direction { BlinkerDirection::Left => { for i in 0..30 { - ending_body[i].r = LEFT[i].r; - ending_body[i].g = LEFT[i].g; - ending_body[i].b = LEFT[i].b; + 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; } } BlinkerDirection::Right => { for i in 30..60 { - ending_body[i].r = RIGHT[i].r; - ending_body[i].g = RIGHT[i].g; - ending_body[i].b = RIGHT[i].b; + 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; } } } @@ -226,8 +232,8 @@ impl Blinker { } impl Animation for Blinker { - fn tick(&mut self, time: Instant) -> (DashboardPattern, Pattern) { - let frames: u8 = ((time - self.start_time).0 as f64 / FPS as f64) as u8; + fn tick(&mut self, time: Instant) -> (DashboardPattern, BodyPattern) { + let frames = calculate_frames(self.start_time.0, time.0); if frames > self.frames { match self.direction { FadeDirection::FadeIn => { @@ -275,7 +281,7 @@ pub struct App { home_state: State, current_animation: Box, dashboard_lights: DashboardPattern, - lights: Pattern, + lights: BodyPattern, } impl App { @@ -286,7 +292,7 @@ impl App { home_state: State::Pattern(0), current_animation: Box::new(DefaultAnimation {}), dashboard_lights: OFF_DASHBOARD, - lights: OFF, + lights: OFF_BODY, } } @@ -297,7 +303,7 @@ impl App { self.dashboard_lights.clone(), self.lights.clone(), PRIDE_DASHBOARD, - PRIDE, + PRIDE_BODY, DEFAULT_FRAMES, time, )) @@ -307,7 +313,7 @@ impl App { self.dashboard_lights.clone(), self.lights.clone(), TRANS_PRIDE_DASHBOARD, - TRANS_PRIDE, + TRANS_PRIDE_BODY, DEFAULT_FRAMES, time, )) @@ -317,9 +323,9 @@ impl App { self.current_animation = Box::new(Fade::new( self.dashboard_lights.clone(), self.lights.clone(), - BRAKE_DASHBOARD, - BRAKES, - BRAKE_FRAMES, + BRAKES_DASHBOARD, + BRAKES_BODY, + BRAKES_FRAMES, time, )); } diff --git a/bike-lights/core/src/patterns.rs b/bike-lights/core/src/patterns.rs index 767b835..e566a5d 100644 --- a/bike-lights/core/src/patterns.rs +++ b/bike-lights/core/src/patterns.rs @@ -1,1160 +1,311 @@ -use crate::RGB; +use crate::{BodyPattern, DashboardPattern, RGB}; +use fixed::types::{I8F8, U16F0}; -pub type DashboardPattern = [RGB; 3]; -pub type Pattern = [RGB; 60]; +pub const RGB_OFF: RGB = RGB { + r: I8F8::lit("0"), + g: I8F8::lit("0"), + b: I8F8::lit("0"), +}; -pub const OFF_DASHBOARD: DashboardPattern = [ - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, -]; +pub const RGB_WHITE: RGB = RGB { + r: I8F8::lit("1"), + g: I8F8::lit("1"), + b: I8F8::lit("1"), +}; -pub const OFF: Pattern = [ - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, -]; +pub const BRAKES_RED: RGB = RGB { + r: I8F8::lit("1"), + g: I8F8::lit("0"), + b: I8F8::lit("0"), +}; -pub const DEFAULT_FRAMES: u8 = 30; +pub const BLINKER_AMBER: RGB = RGB { + r: I8F8::lit("1"), + g: I8F8::lit("0.74"), + b: I8F8::lit("0"), +}; -pub const PRIDE_DASHBOARD: DashboardPattern = [ - RGB { r: 228, g: 3, b: 3 }, - RGB { - r: 0, - g: 128, - b: 38, - }, - RGB { - r: 36, - g: 64, - b: 142, - }, -]; +pub const PRIDE_RED: RGB = RGB { + r: I8F8::lit("0.89"), + g: I8F8::lit("0.01"), + b: I8F8::lit("0.01"), +}; -pub const PRIDE: Pattern = [ +pub const PRIDE_ORANGE: RGB = RGB { + r: I8F8::lit("1.0"), + g: I8F8::lit("0.54"), + b: I8F8::lit("0"), +}; + +pub const PRIDE_YELLOW: RGB = RGB { + r: I8F8::lit("1.0"), + g: I8F8::lit("0.92"), + b: I8F8::lit("0"), +}; + +pub const PRIDE_GREEN: RGB = RGB { + r: I8F8::lit("0"), + g: I8F8::lit("0.5"), + b: I8F8::lit("0.14"), +}; + +pub const PRIDE_INDIGO: RGB = RGB { + r: I8F8::lit("0.14"), + g: I8F8::lit("0.25"), + b: I8F8::lit("0.55"), +}; + +pub const PRIDE_VIOLET: RGB = RGB { + r: I8F8::lit("0.45"), + g: I8F8::lit("0.16"), + b: I8F8::lit("0.50"), +}; + +pub const TRANS_BLUE: RGB = RGB { + r: I8F8::lit("0.36"), + g: I8F8::lit("0.81"), + b: I8F8::lit("0.98"), +}; + +pub const TRANS_PINK: RGB = RGB { + r: I8F8::lit("0.96"), + g: I8F8::lit("0.66"), + b: I8F8::lit("0.72"), +}; + +pub const OFF_DASHBOARD: DashboardPattern = [RGB_OFF; 3]; +pub const OFF_BODY: BodyPattern = [RGB_OFF; 60]; + +pub const DEFAULT_FRAMES: U16F0 = U16F0::lit("30"); + +pub const PRIDE_DASHBOARD: DashboardPattern = [PRIDE_RED, PRIDE_GREEN, PRIDE_INDIGO]; + +pub const PRIDE_BODY: BodyPattern = [ // Left Side // Red - RGB { r: 228, g: 3, b: 3 }, - RGB { r: 228, g: 3, b: 3 }, - RGB { r: 228, g: 3, b: 3 }, - RGB { r: 228, g: 3, b: 3 }, - RGB { r: 228, g: 3, b: 3 }, + PRIDE_RED, + PRIDE_RED, + PRIDE_RED, + PRIDE_RED, + PRIDE_RED, // Orange - RGB { - r: 255, - g: 140, - b: 0, - }, - RGB { - r: 255, - g: 140, - b: 0, - }, - RGB { - r: 255, - g: 140, - b: 0, - }, - RGB { - r: 255, - g: 140, - b: 0, - }, - RGB { - r: 255, - g: 140, - b: 0, - }, + PRIDE_ORANGE, + PRIDE_ORANGE, + PRIDE_ORANGE, + PRIDE_ORANGE, + PRIDE_ORANGE, // Yellow - RGB { - r: 255, - g: 237, - b: 0, - }, - RGB { - r: 255, - g: 237, - b: 0, - }, - RGB { - r: 255, - g: 237, - b: 0, - }, - RGB { - r: 255, - g: 237, - b: 0, - }, - RGB { - r: 255, - g: 237, - b: 0, - }, + PRIDE_YELLOW, + PRIDE_YELLOW, + PRIDE_YELLOW, + PRIDE_YELLOW, + PRIDE_YELLOW, // Green - RGB { - r: 0, - g: 128, - b: 38, - }, - RGB { - r: 0, - g: 128, - b: 38, - }, - RGB { - r: 0, - g: 128, - b: 38, - }, - RGB { - r: 0, - g: 128, - b: 38, - }, - RGB { - r: 0, - g: 128, - b: 38, - }, + PRIDE_GREEN, + PRIDE_GREEN, + PRIDE_GREEN, + PRIDE_GREEN, + PRIDE_GREEN, // Indigo - RGB { - r: 36, - g: 64, - b: 142, - }, - RGB { - r: 36, - g: 64, - b: 142, - }, - RGB { - r: 36, - g: 64, - b: 142, - }, - RGB { - r: 36, - g: 64, - b: 142, - }, - RGB { - r: 36, - g: 64, - b: 142, - }, - // Purple - RGB { - r: 115, - g: 41, - b: 130, - }, - RGB { - r: 115, - g: 41, - b: 130, - }, - RGB { - r: 115, - g: 41, - b: 130, - }, - RGB { - r: 115, - g: 41, - b: 130, - }, - RGB { - r: 115, - g: 41, - b: 130, - }, + PRIDE_INDIGO, + PRIDE_INDIGO, + PRIDE_INDIGO, + PRIDE_INDIGO, + PRIDE_INDIGO, + // Violet + PRIDE_VIOLET, + PRIDE_VIOLET, + PRIDE_VIOLET, + PRIDE_VIOLET, + PRIDE_VIOLET, // Right Side - // Purple - RGB { - r: 115, - g: 41, - b: 130, - }, - RGB { - r: 115, - g: 41, - b: 130, - }, - RGB { - r: 115, - g: 41, - b: 130, - }, - RGB { - r: 115, - g: 41, - b: 130, - }, - RGB { - r: 115, - g: 41, - b: 130, - }, + // Violet + PRIDE_VIOLET, + PRIDE_VIOLET, + PRIDE_VIOLET, + PRIDE_VIOLET, + PRIDE_VIOLET, // Indigo - RGB { - r: 36, - g: 64, - b: 142, - }, - RGB { - r: 36, - g: 64, - b: 142, - }, - RGB { - r: 36, - g: 64, - b: 142, - }, - RGB { - r: 36, - g: 64, - b: 142, - }, - RGB { - r: 36, - g: 64, - b: 142, - }, + PRIDE_INDIGO, + PRIDE_INDIGO, + PRIDE_INDIGO, + PRIDE_INDIGO, + PRIDE_INDIGO, // Green - RGB { - r: 0, - g: 128, - b: 38, - }, - RGB { - r: 0, - g: 128, - b: 38, - }, - RGB { - r: 0, - g: 128, - b: 38, - }, - RGB { - r: 0, - g: 128, - b: 38, - }, - RGB { - r: 0, - g: 128, - b: 38, - }, + PRIDE_GREEN, + PRIDE_GREEN, + PRIDE_GREEN, + PRIDE_GREEN, + PRIDE_GREEN, // Yellow - RGB { - r: 255, - g: 237, - b: 0, - }, - RGB { - r: 255, - g: 237, - b: 0, - }, - RGB { - r: 255, - g: 237, - b: 0, - }, - RGB { - r: 255, - g: 237, - b: 0, - }, - RGB { - r: 255, - g: 237, - b: 0, - }, + PRIDE_YELLOW, + PRIDE_YELLOW, + PRIDE_YELLOW, + PRIDE_YELLOW, + PRIDE_YELLOW, // Orange - RGB { - r: 255, - g: 140, - b: 0, - }, - RGB { - r: 255, - g: 140, - b: 0, - }, - RGB { - r: 255, - g: 140, - b: 0, - }, - RGB { - r: 255, - g: 140, - b: 0, - }, - RGB { - r: 255, - g: 140, - b: 0, - }, + PRIDE_ORANGE, + PRIDE_ORANGE, + PRIDE_ORANGE, + PRIDE_ORANGE, + PRIDE_ORANGE, // Red - RGB { r: 228, g: 3, b: 3 }, - RGB { r: 228, g: 3, b: 3 }, - RGB { r: 228, g: 3, b: 3 }, - RGB { r: 228, g: 3, b: 3 }, - RGB { r: 228, g: 3, b: 3 }, + PRIDE_RED, + PRIDE_RED, + PRIDE_RED, + PRIDE_RED, + PRIDE_RED, ]; -pub const TRANS_PRIDE_DASHBOARD: DashboardPattern = [ - RGB { - r: 91, - g: 206, - b: 250, - }, - RGB { - r: 255, - g: 255, - b: 255, - }, - RGB { - r: 245, - g: 169, - b: 184, - }, -]; +pub const TRANS_PRIDE_DASHBOARD: DashboardPattern = [TRANS_BLUE, RGB_WHITE, TRANS_PINK]; -pub const TRANS_PRIDE: Pattern = [ +pub const TRANS_PRIDE_BODY: BodyPattern = [ // Left Side - // Light Blue - RGB { - r: 91, - g: 206, - b: 250, - }, - RGB { - r: 91, - g: 206, - b: 250, - }, - RGB { - r: 91, - g: 206, - b: 250, - }, - RGB { - r: 91, - g: 206, - b: 250, - }, - RGB { - r: 91, - g: 206, - b: 250, - }, - RGB { - r: 91, - g: 206, - b: 250, - }, - // Light Pink - RGB { - r: 245, - g: 169, - b: 184, - }, - RGB { - r: 245, - g: 169, - b: 184, - }, - RGB { - r: 245, - g: 169, - b: 184, - }, - RGB { - r: 245, - g: 169, - b: 184, - }, - RGB { - r: 245, - g: 169, - b: 184, - }, - RGB { - r: 245, - g: 169, - b: 184, - }, - // White - RGB { - r: 255, - g: 255, - b: 255, - }, - RGB { - r: 255, - g: 255, - b: 255, - }, - RGB { - r: 255, - g: 255, - b: 255, - }, - RGB { - r: 255, - g: 255, - b: 255, - }, - RGB { - r: 255, - g: 255, - b: 255, - }, - RGB { - r: 255, - g: 255, - b: 255, - }, - // Light Pink - RGB { - r: 245, - g: 169, - b: 184, - }, - RGB { - r: 245, - g: 169, - b: 184, - }, - RGB { - r: 245, - g: 169, - b: 184, - }, - RGB { - r: 245, - g: 169, - b: 184, - }, - RGB { - r: 245, - g: 169, - b: 184, - }, - RGB { - r: 245, - g: 169, - b: 184, - }, - // Light Blue - RGB { - r: 91, - g: 206, - b: 250, - }, - RGB { - r: 91, - g: 206, - b: 250, - }, - RGB { - r: 91, - g: 206, - b: 250, - }, - RGB { - r: 91, - g: 206, - b: 250, - }, - RGB { - r: 91, - g: 206, - b: 250, - }, - RGB { - r: 91, - g: 206, - b: 250, - }, + TRANS_BLUE, TRANS_BLUE, TRANS_BLUE, TRANS_BLUE, TRANS_BLUE, TRANS_BLUE, TRANS_PINK, TRANS_PINK, + TRANS_PINK, TRANS_PINK, TRANS_PINK, TRANS_PINK, RGB_WHITE, RGB_WHITE, RGB_WHITE, RGB_WHITE, + RGB_WHITE, RGB_WHITE, TRANS_PINK, TRANS_PINK, TRANS_PINK, TRANS_PINK, TRANS_PINK, TRANS_PINK, + TRANS_BLUE, TRANS_BLUE, TRANS_BLUE, TRANS_BLUE, TRANS_BLUE, TRANS_BLUE, // Right side - // Light Blue - RGB { - r: 91, - g: 206, - b: 250, - }, - RGB { - r: 91, - g: 206, - b: 250, - }, - RGB { - r: 91, - g: 206, - b: 250, - }, - RGB { - r: 91, - g: 206, - b: 250, - }, - RGB { - r: 91, - g: 206, - b: 250, - }, - RGB { - r: 91, - g: 206, - b: 250, - }, - // Light Pink - RGB { - r: 245, - g: 169, - b: 184, - }, - RGB { - r: 245, - g: 169, - b: 184, - }, - RGB { - r: 245, - g: 169, - b: 184, - }, - RGB { - r: 245, - g: 169, - b: 184, - }, - RGB { - r: 245, - g: 169, - b: 184, - }, - RGB { - r: 245, - g: 169, - b: 184, - }, - // White - RGB { - r: 255, - g: 255, - b: 255, - }, - RGB { - r: 255, - g: 255, - b: 255, - }, - RGB { - r: 255, - g: 255, - b: 255, - }, - RGB { - r: 255, - g: 255, - b: 255, - }, - RGB { - r: 255, - g: 255, - b: 255, - }, - RGB { - r: 255, - g: 255, - b: 255, - }, - // Light Pink - RGB { - r: 245, - g: 169, - b: 184, - }, - RGB { - r: 245, - g: 169, - b: 184, - }, - RGB { - r: 245, - g: 169, - b: 184, - }, - RGB { - r: 245, - g: 169, - b: 184, - }, - RGB { - r: 245, - g: 169, - b: 184, - }, - RGB { - r: 245, - g: 169, - b: 184, - }, - // Light Blue - RGB { - r: 91, - g: 206, - b: 250, - }, - RGB { - r: 91, - g: 206, - b: 250, - }, - RGB { - r: 91, - g: 206, - b: 250, - }, - RGB { - r: 91, - g: 206, - b: 250, - }, - RGB { - r: 91, - g: 206, - b: 250, - }, - RGB { - r: 91, - g: 206, - b: 250, - }, + TRANS_BLUE, TRANS_BLUE, TRANS_BLUE, TRANS_BLUE, TRANS_BLUE, TRANS_BLUE, TRANS_PINK, TRANS_PINK, + TRANS_PINK, TRANS_PINK, TRANS_PINK, TRANS_PINK, RGB_WHITE, RGB_WHITE, RGB_WHITE, RGB_WHITE, + RGB_WHITE, RGB_WHITE, TRANS_PINK, TRANS_PINK, TRANS_PINK, TRANS_PINK, TRANS_PINK, TRANS_PINK, + TRANS_BLUE, TRANS_BLUE, TRANS_BLUE, TRANS_BLUE, TRANS_BLUE, TRANS_BLUE, ]; -pub const BRAKE_FRAMES: u8 = 15; +pub const BRAKES_FRAMES: U16F0 = U16F0::lit("15"); -pub const BRAKE_DASHBOARD: DashboardPattern = [ - RGB { r: 255, g: 0, b: 0 }, - RGB { r: 255, g: 0, b: 0 }, - RGB { r: 255, g: 0, b: 0 }, +pub const BRAKES_DASHBOARD: DashboardPattern = [BRAKES_RED; 3]; + +pub const BRAKES_BODY: BodyPattern = [BRAKES_RED; 60]; + +pub const BLINKER_FRAMES: U16F0 = U16F0::lit("15"); + +pub const LEFT_BLINKER_DASHBOARD: DashboardPattern = [BLINKER_AMBER, RGB_OFF, RGB_OFF]; + +pub const LEFT_BLINKER_BODY: BodyPattern = [ + BLINKER_AMBER, + BLINKER_AMBER, + BLINKER_AMBER, + BLINKER_AMBER, + BLINKER_AMBER, + BLINKER_AMBER, + BLINKER_AMBER, + BLINKER_AMBER, + BLINKER_AMBER, + BLINKER_AMBER, + BLINKER_AMBER, + BLINKER_AMBER, + BLINKER_AMBER, + BLINKER_AMBER, + BLINKER_AMBER, + BLINKER_AMBER, + BLINKER_AMBER, + BLINKER_AMBER, + BLINKER_AMBER, + BLINKER_AMBER, + BLINKER_AMBER, + BLINKER_AMBER, + BLINKER_AMBER, + BLINKER_AMBER, + BLINKER_AMBER, + BLINKER_AMBER, + BLINKER_AMBER, + BLINKER_AMBER, + BLINKER_AMBER, + BLINKER_AMBER, + RGB_OFF, + RGB_OFF, + RGB_OFF, + RGB_OFF, + RGB_OFF, + RGB_OFF, + RGB_OFF, + RGB_OFF, + RGB_OFF, + RGB_OFF, + RGB_OFF, + RGB_OFF, + RGB_OFF, + RGB_OFF, + RGB_OFF, + RGB_OFF, + RGB_OFF, + RGB_OFF, + RGB_OFF, + RGB_OFF, + RGB_OFF, + RGB_OFF, + RGB_OFF, + RGB_OFF, + RGB_OFF, + RGB_OFF, + RGB_OFF, + RGB_OFF, + RGB_OFF, + RGB_OFF, ]; -pub const BRAKES: Pattern = [ - RGB { r: 255, g: 0, b: 0 }, - RGB { r: 255, g: 0, b: 0 }, - RGB { r: 255, g: 0, b: 0 }, - RGB { r: 255, g: 0, b: 0 }, - RGB { r: 255, g: 0, b: 0 }, - RGB { r: 255, g: 0, b: 0 }, - RGB { r: 255, g: 0, b: 0 }, - RGB { r: 255, g: 0, b: 0 }, - RGB { r: 255, g: 0, b: 0 }, - RGB { r: 255, g: 0, b: 0 }, - RGB { r: 255, g: 0, b: 0 }, - RGB { r: 255, g: 0, b: 0 }, - RGB { r: 255, g: 0, b: 0 }, - RGB { r: 255, g: 0, b: 0 }, - RGB { r: 255, g: 0, b: 0 }, - RGB { r: 255, g: 0, b: 0 }, - RGB { r: 255, g: 0, b: 0 }, - RGB { r: 255, g: 0, b: 0 }, - RGB { r: 255, g: 0, b: 0 }, - RGB { r: 255, g: 0, b: 0 }, - RGB { r: 255, g: 0, b: 0 }, - RGB { r: 255, g: 0, b: 0 }, - RGB { r: 255, g: 0, b: 0 }, - RGB { r: 255, g: 0, b: 0 }, - RGB { r: 255, g: 0, b: 0 }, - RGB { r: 255, g: 0, b: 0 }, - RGB { r: 255, g: 0, b: 0 }, - RGB { r: 255, g: 0, b: 0 }, - RGB { r: 255, g: 0, b: 0 }, - RGB { r: 255, g: 0, b: 0 }, - RGB { r: 255, g: 0, b: 0 }, - RGB { r: 255, g: 0, b: 0 }, - RGB { r: 255, g: 0, b: 0 }, - RGB { r: 255, g: 0, b: 0 }, - RGB { r: 255, g: 0, b: 0 }, - RGB { r: 255, g: 0, b: 0 }, - RGB { r: 255, g: 0, b: 0 }, - RGB { r: 255, g: 0, b: 0 }, - RGB { r: 255, g: 0, b: 0 }, - RGB { r: 255, g: 0, b: 0 }, - RGB { r: 255, g: 0, b: 0 }, - RGB { r: 255, g: 0, b: 0 }, - RGB { r: 255, g: 0, b: 0 }, - RGB { r: 255, g: 0, b: 0 }, - RGB { r: 255, g: 0, b: 0 }, - RGB { r: 255, g: 0, b: 0 }, - RGB { r: 255, g: 0, b: 0 }, - RGB { r: 255, g: 0, b: 0 }, - RGB { r: 255, g: 0, b: 0 }, - RGB { r: 255, g: 0, b: 0 }, - RGB { r: 255, g: 0, b: 0 }, - RGB { r: 255, g: 0, b: 0 }, - RGB { r: 255, g: 0, b: 0 }, - RGB { r: 255, g: 0, b: 0 }, - RGB { r: 255, g: 0, b: 0 }, - RGB { r: 255, g: 0, b: 0 }, - RGB { r: 255, g: 0, b: 0 }, - RGB { r: 255, g: 0, b: 0 }, - RGB { r: 255, g: 0, b: 0 }, - RGB { r: 255, g: 0, b: 0 }, -]; - -pub const BLINKER_FRAMES: u8 = 15; - -pub const LEFT_DASHBOARD: DashboardPattern = [ - RGB { - r: 255, - g: 191, - b: 0, - }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, -]; - -pub const LEFT: Pattern = [ - RGB { - r: 255, - g: 191, - b: 0, - }, - RGB { - r: 255, - g: 191, - b: 0, - }, - RGB { - r: 255, - g: 191, - b: 0, - }, - RGB { - r: 255, - g: 191, - b: 0, - }, - RGB { - r: 255, - g: 191, - b: 0, - }, - RGB { - r: 255, - g: 191, - b: 0, - }, - RGB { - r: 255, - g: 191, - b: 0, - }, - RGB { - r: 255, - g: 191, - b: 0, - }, - RGB { - r: 255, - g: 191, - b: 0, - }, - RGB { - r: 255, - g: 191, - b: 0, - }, - RGB { - r: 255, - g: 191, - b: 0, - }, - RGB { - r: 255, - g: 191, - b: 0, - }, - RGB { - r: 255, - g: 191, - b: 0, - }, - RGB { - r: 255, - g: 191, - b: 0, - }, - RGB { - r: 255, - g: 191, - b: 0, - }, - RGB { - r: 255, - g: 191, - b: 0, - }, - RGB { - r: 255, - g: 191, - b: 0, - }, - RGB { - r: 255, - g: 191, - b: 0, - }, - RGB { - r: 255, - g: 191, - b: 0, - }, - RGB { - r: 255, - g: 191, - b: 0, - }, - RGB { - r: 255, - g: 191, - b: 0, - }, - RGB { - r: 255, - g: 191, - b: 0, - }, - RGB { - r: 255, - g: 191, - b: 0, - }, - RGB { - r: 255, - g: 191, - b: 0, - }, - RGB { - r: 255, - g: 191, - b: 0, - }, - RGB { - r: 255, - g: 191, - b: 0, - }, - RGB { - r: 255, - g: 191, - b: 0, - }, - RGB { - r: 255, - g: 191, - b: 0, - }, - RGB { - r: 255, - g: 191, - b: 0, - }, - RGB { - r: 255, - g: 191, - b: 0, - }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, -]; - -pub const RIGHT_FRAMES: u8 = 15; - -pub const RIGHT_DASHBOARD: DashboardPattern = [ - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { - r: 255, - g: 191, - b: 0, - }, -]; - -pub const RIGHT: Pattern = [ - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { - r: 255, - g: 191, - b: 0, - }, - RGB { - r: 255, - g: 191, - b: 0, - }, - RGB { - r: 255, - g: 191, - b: 0, - }, - RGB { - r: 255, - g: 191, - b: 0, - }, - RGB { - r: 255, - g: 191, - b: 0, - }, - RGB { - r: 255, - g: 191, - b: 0, - }, - RGB { - r: 255, - g: 191, - b: 0, - }, - RGB { - r: 255, - g: 191, - b: 0, - }, - RGB { - r: 255, - g: 191, - b: 0, - }, - RGB { - r: 255, - g: 191, - b: 0, - }, - RGB { - r: 255, - g: 191, - b: 0, - }, - RGB { - r: 255, - g: 191, - b: 0, - }, - RGB { - r: 255, - g: 191, - b: 0, - }, - RGB { - r: 255, - g: 191, - b: 0, - }, - RGB { - r: 255, - g: 191, - b: 0, - }, - RGB { - r: 255, - g: 191, - b: 0, - }, - RGB { - r: 255, - g: 191, - b: 0, - }, - RGB { - r: 255, - g: 191, - b: 0, - }, - RGB { - r: 255, - g: 191, - b: 0, - }, - RGB { - r: 255, - g: 191, - b: 0, - }, - RGB { - r: 255, - g: 191, - b: 0, - }, - RGB { - r: 255, - g: 191, - b: 0, - }, - RGB { - r: 255, - g: 191, - b: 0, - }, - RGB { - r: 255, - g: 191, - b: 0, - }, - RGB { - r: 255, - g: 191, - b: 0, - }, - RGB { - r: 255, - g: 191, - b: 0, - }, - RGB { - r: 255, - g: 191, - b: 0, - }, - RGB { - r: 255, - g: 191, - b: 0, - }, - RGB { - r: 255, - g: 191, - b: 0, - }, - RGB { - r: 255, - g: 191, - b: 0, - }, +pub const RIGHT_BLINKER_DASHBOARD: DashboardPattern = [RGB_OFF, RGB_OFF, BLINKER_AMBER]; + +pub const RIGHT_BLINKER_BODY: BodyPattern = [ + RGB_OFF, + RGB_OFF, + RGB_OFF, + RGB_OFF, + RGB_OFF, + RGB_OFF, + RGB_OFF, + RGB_OFF, + RGB_OFF, + RGB_OFF, + RGB_OFF, + RGB_OFF, + RGB_OFF, + RGB_OFF, + RGB_OFF, + RGB_OFF, + RGB_OFF, + RGB_OFF, + RGB_OFF, + RGB_OFF, + RGB_OFF, + RGB_OFF, + RGB_OFF, + RGB_OFF, + RGB_OFF, + RGB_OFF, + RGB_OFF, + RGB_OFF, + RGB_OFF, + RGB_OFF, + BLINKER_AMBER, + BLINKER_AMBER, + BLINKER_AMBER, + BLINKER_AMBER, + BLINKER_AMBER, + BLINKER_AMBER, + BLINKER_AMBER, + BLINKER_AMBER, + BLINKER_AMBER, + BLINKER_AMBER, + BLINKER_AMBER, + BLINKER_AMBER, + BLINKER_AMBER, + BLINKER_AMBER, + BLINKER_AMBER, + BLINKER_AMBER, + BLINKER_AMBER, + BLINKER_AMBER, + BLINKER_AMBER, + BLINKER_AMBER, + BLINKER_AMBER, + BLINKER_AMBER, + BLINKER_AMBER, + BLINKER_AMBER, + BLINKER_AMBER, + BLINKER_AMBER, + BLINKER_AMBER, + BLINKER_AMBER, + BLINKER_AMBER, + BLINKER_AMBER, ]; diff --git a/bike-lights/core/src/types.rs b/bike-lights/core/src/types.rs index 145b515..c7acf2a 100644 --- a/bike-lights/core/src/types.rs +++ b/bike-lights/core/src/types.rs @@ -1,4 +1,5 @@ use core::default::Default; +use fixed::types::I8F8; #[derive(Clone, Copy, Default, Debug)] pub struct RGB { @@ -7,35 +8,10 @@ pub struct RGB { pub b: T, } -pub type DashboardPattern = [RGB; 3]; -/* -#[derive(Clone)] -pub struct DashboardPattern(pub [RGB; 3]); -*/ +const DASHBOARD_LIGHT_COUNT: usize = 3; -/* -impl Clone for DashboardPattern { - fn clone(&self) -> Self { - let mut v: [RGB; 3] = Default::default(); - for i in 0..3 { - v[i] = self.0[i] - } - Self(v) - } -} -*/ +pub type DashboardPattern = [RGB; DASHBOARD_LIGHT_COUNT]; -pub type Pattern = [RGB; 60]; -/* -pub struct Pattern(pub [RGB; 60]); +const BODY_LIGHT_COUNT: usize = 60; -impl Pattern { - pub fn clone(&self) -> Self { - let mut v: [RGB; 60] = [Default::default(); 60]; - for i in 0..60 { - v[i] = self.0[i] - } - Self(v) - } -} -*/ +pub type BodyPattern = [RGB; BODY_LIGHT_COUNT]; diff --git a/bike-lights/simulator/src/main.rs b/bike-lights/simulator/src/main.rs index 64d5222..407a11d 100644 --- a/bike-lights/simulator/src/main.rs +++ b/bike-lights/simulator/src/main.rs @@ -1,7 +1,10 @@ use adw::prelude::*; +use fixed::types::{I8F8, U128F0}; use glib::{Object, Sender}; use gtk::subclass::prelude::*; -use lights_core::{App, DashboardPattern, Event, Instant, Pattern, FPS, RGB, UI}; +use lights_core::{ + App, BodyPattern, DashboardPattern, Event, Instant, FPS, OFF_BODY, OFF_DASHBOARD, RGB, UI, +}; use std::{ cell::RefCell, env, @@ -14,7 +17,7 @@ const HEIGHT: i32 = 480; pub struct Update { dashboard: DashboardPattern, - lights: Pattern, + lights: BodyPattern, } pub struct DashboardLightsPrivate { @@ -29,11 +32,7 @@ impl ObjectSubclass for DashboardLightsPrivate { fn new() -> Self { Self { - lights: Rc::new(RefCell::new([ - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - ])), + lights: Rc::new(RefCell::new(OFF_DASHBOARD)), } } } @@ -60,9 +59,9 @@ impl DashboardLights { let lights = s.imp().lights.borrow(); for i in 0..3 { context.set_source_rgb( - lights[i].r as f64 / 256., - lights[i].g as f64 / 256., - lights[i].b as f64 / 256., + lights[i].r.into(), + lights[i].g.into(), + lights[i].b.into(), ); context.rectangle(start + 100. * i as f64, 10., 80., 80.); let _ = context.fill(); @@ -73,14 +72,14 @@ impl DashboardLights { s } - pub fn set_lights(&self, lights: [RGB; 3]) { + pub fn set_lights(&self, lights: DashboardPattern) { *self.imp().lights.borrow_mut() = lights; self.queue_draw(); } } pub struct BikeLightsPrivate { - lights: Rc>, + lights: Rc>, } #[glib::object_subclass] @@ -91,68 +90,7 @@ impl ObjectSubclass for BikeLightsPrivate { fn new() -> Self { Self { - lights: Rc::new(RefCell::new([ - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - RGB { r: 0, g: 0, b: 0 }, - ])), + lights: Rc::new(RefCell::new(OFF_BODY)), } } } @@ -180,18 +118,18 @@ impl BikeLights { let lights = s.imp().lights.borrow(); for i in 0..30 { context.set_source_rgb( - lights[i].r as f64 / 256., - lights[i].g as f64 / 256., - lights[i].b as f64 / 256., + lights[i].r.into(), + lights[i].g.into(), + lights[i].b.into(), ); context.rectangle(center - 45., 5. + 20. * i as f64, 15., 15.); let _ = context.fill(); } for i in 0..30 { context.set_source_rgb( - lights[i + 30].r as f64 / 256., - lights[i + 30].g as f64 / 256., - lights[i + 30].b as f64 / 256., + lights[i + 30].r.into(), + lights[i + 30].g.into(), + lights[i + 30].b.into(), ); context.rectangle(center + 15., 5. + 20. * (30. - (i + 1) as f64), 15., 15.); let _ = context.fill(); @@ -202,7 +140,7 @@ impl BikeLights { s } - pub fn set_lights(&self, lights: [RGB; 60]) { + pub fn set_lights(&self, lights: [RGB; 60]) { *self.imp().lights.borrow_mut() = lights; self.queue_draw(); } @@ -222,7 +160,7 @@ impl UI for GTKUI { } } - fn update_lights(&self, dashboard_lights: DashboardPattern, lights: Pattern) { + fn update_lights(&self, dashboard_lights: DashboardPattern, lights: BodyPattern) { self.tx .send(Update { dashboard: dashboard_lights, @@ -248,12 +186,12 @@ fn main() { rx: event_rx, })); loop { - bike_app.tick(Instant( - (std::time::SystemTime::now() + bike_app.tick(Instant(U128F0::from( + std::time::SystemTime::now() .duration_since(std::time::UNIX_EPOCH) - .unwrap()) - .as_millis(), - )); + .unwrap() + .as_millis(), + ))); std::thread::sleep(std::time::Duration::from_millis(1000 / (FPS as u64))); } });