~ruther/simple-clock

ref: 0248a3d23e58c50caa5085204db3d0211664da8e simple-clock/source/src/clock_app.rs -rw-r--r-- 3.3 KiB
0248a3d2 — František Boháček docs: document new changes 1 year, 10 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
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<dyn ClockAppMode + Send>; core::mem::variant_count::<ClockAppModes>()],
    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
    }
}
Do not follow this link