use alloc::boxed::Box; use stm32f1xx_hal::rtc::Rtc; use crate::{ brightness_manager::BrightnessManager, button::ButtonState, clock_display_viewer::ClockDisplayViewer, clock_state::ClockState, app_mode::{ClockAppMode, ClockAppModes, default_app_mode::DefaultAppMode, edit_app_mode::EditAppMode}, }; pub struct ClockApp { rtc: Rtc, display: ClockDisplayViewer, state: ClockState, modes: [Box; core::mem::variant_count::()], brightness: BrightnessManager, current_mode: ClockAppModes, } pub struct AppState<'a> { pub rtc: &'a mut Rtc, pub display: &'a mut ClockDisplayViewer, pub state: &'a mut ClockState, pub brightness: &'a mut BrightnessManager, pub current_mode: &'a mut ClockAppModes, } pub enum ClockInterrupt { Rtc, DisplayTimer, } impl ClockApp { pub fn new(rtc: Rtc, display: ClockDisplayViewer, state: ClockState) -> Self { Self { rtc, display, state, current_mode: ClockAppModes::NormalMode, modes: [ Box::new(DefaultAppMode::new()), Box::new(EditAppMode::new()) ], brightness: BrightnessManager::new(), } } pub fn interrupt(&mut self, interrupt: ClockInterrupt) { match interrupt { ClockInterrupt::Rtc => { self.state.second_elapsed(); self.rtc.clear_second_flag(); } ClockInterrupt::DisplayTimer => { let _ = self.display.update(&self.state); self.brightness.apply_brightness(&mut self.display); let mut mode = self.current_mode; let app_state = AppState { rtc: &mut self.rtc, display: &mut self.display, state: &mut self.state, brightness: &mut self.brightness, current_mode: &mut mode, }; self.modes[self.current_mode as usize].update(app_state); } } } pub fn handle_button(&mut self, index: usize, state: ButtonState) { let mut mode = self.current_mode; let current_mode = self.modes[self.current_mode as usize].as_mut(); { let app_state = AppState { rtc: &mut self.rtc, display: &mut self.display, state: &mut self.state, brightness: &mut self.brightness, current_mode: &mut mode, }; current_mode.handle_button(app_state, index, state); } if self.current_mode != mode { let mut temp_mode = mode; { current_mode.stop(AppState { rtc: &mut self.rtc, display: &mut self.display, state: &mut self.state, brightness: &mut self.brightness, current_mode: &mut temp_mode }); } self.current_mode = temp_mode; let current_mode = self.modes[self.current_mode as usize].as_mut(); current_mode.run(AppState { rtc: &mut self.rtc, display: &mut self.display, state: &mut self.state, brightness: &mut self.brightness, current_mode: &mut temp_mode }); } } pub fn display(&mut self) -> &mut ClockDisplayViewer { &mut self.display } }