An applicaiton and simulator for a bike lighting system #245

Merged
savanni merged 16 commits from bike-lights into main 2024-08-01 01:32:29 +00:00
3 changed files with 714 additions and 447 deletions
Showing only changes of commit 22f0f9061c - Show all commits

View File

@ -132,7 +132,12 @@ pub enum FadeDirection {
FadeOut, FadeOut,
} }
pub struct LeftBlinker { pub enum BlinkerDirection {
Left,
Right,
}
pub struct Blinker {
fade_in: Fade, fade_in: Fade,
fade_out: Fade, fade_out: Fade,
direction: FadeDirection, direction: FadeDirection,
@ -141,31 +146,53 @@ pub struct LeftBlinker {
frames: u8, frames: u8,
} }
impl LeftBlinker { impl Blinker {
fn new( fn new(
starting_dashboard: DashboardPattern, starting_dashboard: DashboardPattern,
starting_body: Pattern, starting_body: Pattern,
direction: BlinkerDirection,
time: std::time::Instant, time: std::time::Instant,
) -> Self { ) -> Self {
let mut ending_dashboard = starting_dashboard.clone(); let mut ending_dashboard = starting_dashboard.clone();
ending_dashboard[0].r = LEFT_DASHBOARD[0].r;
ending_dashboard[0].g = LEFT_DASHBOARD[0].g;
ending_dashboard[0].b = LEFT_DASHBOARD[0].b;
let mut ending_body = starting_body.clone(); match direction {
for i in 0..30 { BlinkerDirection::Left => {
ending_body[i].r = LEFT[i].r; ending_dashboard[0].r = LEFT_DASHBOARD[0].r;
ending_body[i].g = LEFT[i].g; ending_dashboard[0].g = LEFT_DASHBOARD[0].g;
ending_body[i].b = LEFT[i].b; ending_dashboard[0].b = LEFT_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;
}
} }
LeftBlinker { let mut ending_body = starting_body.clone();
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;
}
}
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;
}
}
}
Blinker {
fade_in: Fade::new( fade_in: Fade::new(
starting_dashboard.clone(), starting_dashboard.clone(),
starting_body.clone(), starting_body.clone(),
ending_dashboard.clone(), ending_dashboard.clone(),
ending_body.clone(), ending_body.clone(),
LEFT_FRAMES, BLINKER_FRAMES,
time, time,
), ),
fade_out: Fade::new( fade_out: Fade::new(
@ -173,17 +200,17 @@ impl LeftBlinker {
ending_body.clone(), ending_body.clone(),
starting_dashboard.clone(), starting_dashboard.clone(),
starting_body.clone(), starting_body.clone(),
LEFT_FRAMES, BLINKER_FRAMES,
time, time,
), ),
direction: FadeDirection::FadeIn, direction: FadeDirection::FadeIn,
start_time: time, start_time: time,
frames: LEFT_FRAMES, frames: BLINKER_FRAMES,
} }
} }
} }
impl Animation for LeftBlinker { impl Animation for Blinker {
fn tick(&mut self, time: std::time::Instant) -> (DashboardPattern, Pattern) { fn tick(&mut self, time: std::time::Instant) -> (DashboardPattern, Pattern) {
let frames: u8 = ((time - self.start_time).as_millis() as f64 / FPS as f64) as u8; let frames: u8 = ((time - self.start_time).as_millis() as f64 / FPS as f64) as u8;
if frames > self.frames { if frames > self.frames {
@ -249,7 +276,7 @@ impl App {
} }
} }
fn update_state(&mut self, time: std::time::Instant) { fn update_animation(&mut self, time: std::time::Instant) {
match self.state { match self.state {
State::Pattern(0) => { State::Pattern(0) => {
self.current_animation = Box::new(Fade::new( self.current_animation = Box::new(Fade::new(
@ -283,58 +310,75 @@ impl App {
)); ));
} }
State::LeftBlinker => { State::LeftBlinker => {
self.current_animation = Box::new(LeftBlinker::new( self.current_animation = Box::new(Blinker::new(
self.dashboard_lights.clone(), self.dashboard_lights.clone(),
self.lights.clone(), self.lights.clone(),
BlinkerDirection::Left,
time,
));
}
State::RightBlinker => {
self.current_animation = Box::new(Blinker::new(
self.dashboard_lights.clone(),
self.lights.clone(),
BlinkerDirection::Right,
time, time,
)); ));
} }
State::RightBlinker => (),
State::BrakeLeftBlinker => (), State::BrakeLeftBlinker => (),
State::BrakeRightBlinker => (), State::BrakeRightBlinker => (),
} }
} }
fn update_state(&mut self, event: Event) {
match event {
Event::Brake => {
if self.state == State::Brake {
self.state = self.home_state.clone();
} else {
self.state = State::Brake;
}
}
Event::BrakeRelease => self.state = self.home_state.clone(),
Event::LeftBlinker => match self.state {
State::Brake => self.state = State::BrakeLeftBlinker,
State::BrakeLeftBlinker => self.state = State::Brake,
State::LeftBlinker => self.state = self.home_state.clone(),
_ => self.state = State::LeftBlinker,
},
Event::NextPattern => match self.state {
State::Pattern(i) => {
let next = i + 1;
self.state = State::Pattern(if next > 1 { 0 } else { next });
self.home_state = self.state.clone();
}
_ => (),
},
Event::PreviousPattern => match self.state {
State::Pattern(i) => {
if i == 0 {
self.state = State::Pattern(1);
} else {
self.state = State::Pattern(i - 1);
}
self.home_state = self.state.clone();
}
_ => (),
},
Event::RightBlinker => match self.state {
State::Brake => self.state = State::BrakeRightBlinker,
State::BrakeRightBlinker => self.state = State::Brake,
State::RightBlinker => self.state = self.home_state.clone(),
_ => self.state = State::RightBlinker,
},
}
}
pub fn tick(&mut self, time: std::time::Instant) { pub fn tick(&mut self, time: std::time::Instant) {
match self.ui.check_event() { match self.ui.check_event() {
Some(event) => { Some(event) => {
match event { self.update_state(event);
Event::Brake => { self.update_animation(time);
if self.state == State::Brake {
self.state = self.home_state.clone();
} else {
self.state = State::Brake;
}
}
Event::BrakeRelease => self.state = State::Pattern(0),
Event::LeftBlinker => match self.state {
State::Brake => self.state = State::BrakeLeftBlinker,
State::BrakeLeftBlinker => self.state = State::Brake,
State::LeftBlinker => self.state = self.home_state.clone(),
_ => self.state = State::LeftBlinker,
},
Event::NextPattern => match self.state {
State::Pattern(i) => {
let next = i + 1;
self.state = State::Pattern(if next > 1 { 0 } else { next });
self.home_state = self.state.clone();
}
_ => (),
},
Event::PreviousPattern => match self.state {
State::Pattern(i) => {
if i == 0 {
self.state = State::Pattern(1);
} else {
self.state = State::Pattern(i - 1);
}
self.home_state = self.state.clone();
}
_ => (),
},
Event::RightBlinker => {}
}
self.update_state(time);
} }
None => {} None => {}
}; };

File diff suppressed because it is too large Load Diff

View File

@ -170,7 +170,9 @@ impl BikeLights {
let s: Self = Object::builder().build(); let s: Self = Object::builder().build();
s.set_width_request(WIDTH); s.set_width_request(WIDTH);
s.set_height_request(200); s.set_height_request(640);
let center = WIDTH as f64 / 2.;
s.set_draw_func({ s.set_draw_func({
let s = s.clone(); let s = s.clone();
@ -182,7 +184,7 @@ impl BikeLights {
lights[i].g as f64 / 256., lights[i].g as f64 / 256.,
lights[i].b as f64 / 256., lights[i].b as f64 / 256.,
); );
context.rectangle(5. + 20. * i as f64, 5., 15., 15.); context.rectangle(center - 45., 5. + 20. * i as f64, 15., 15.);
let _ = context.fill(); let _ = context.fill();
} }
for i in 0..30 { for i in 0..30 {
@ -191,7 +193,7 @@ impl BikeLights {
lights[i + 30].g as f64 / 256., lights[i + 30].g as f64 / 256.,
lights[i + 30].b as f64 / 256., lights[i + 30].b as f64 / 256.,
); );
context.rectangle(5. + 20. * i as f64, 30., 15., 15.); context.rectangle(center + 15., 5. + 20. * (30. - (i + 1) as f64), 15., 15.);
let _ = context.fill(); let _ = context.fill();
} }
} }