~ruther/simple-clock

ref: 6fbd046c5cdec2a46aa06ef9753192095ad33555 simple-clock/source/src/clock_app.rs -rw-r--r-- 3.8 KiB
6fbd046c — Rutherther Merge pull request #1 from Rutherther/add-docs 1 year, 9 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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
use core::marker::PhantomData;

use alloc::boxed::Box;
use stm32f1xx_hal::rtc::Rtc;

use crate::{
    brightness_manager::BrightnessManager, button::ButtonState,
    clock_display_viewer::ClockDisplayViewer, clock_state::ClockState, display_view::DisplayViews,
};

pub struct ClockApp {
    rtc: Rtc,
    display: ClockDisplayViewer,
    state: ClockState,
    buttons: [Box<dyn ClockButton + Send>; 4],
    brightness: BrightnessManager,
}

struct AppState<'a> {
    rtc: &'a mut Rtc,
    display: &'a mut ClockDisplayViewer,
    state: &'a mut ClockState,
    brightness: &'a mut BrightnessManager,
}

trait ClockButton {
    fn handle(&self, state: ButtonState, state: AppState);
}

struct ButtonSwitchView;
struct ButtonChangeTime;

struct Up;
struct Down;
struct ButtonBrightness<Direction> {
    direction: PhantomData<Direction>,
}

pub enum ClockInterrupt {
    Rtc,
    DisplayTimer,
}

impl ClockApp {
    pub fn new(rtc: Rtc, display: ClockDisplayViewer, state: ClockState) -> Self {
        Self {
            rtc,
            display,
            state,
            buttons: [
                Box::new(ButtonSwitchView),
                Box::new(ButtonChangeTime),
                Box::new(ButtonBrightness::<Down> {
                    direction: PhantomData::<Down>,
                }),
                Box::new(ButtonBrightness::<Up> {
                    direction: PhantomData::<Up>,
                }),
            ],
            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.update(&self.state);
                self.brightness.apply_brightness(&mut self.display);
            }
        }
    }

    pub fn handle_button(&mut self, index: usize, state: ButtonState) {
        self.buttons[index].handle(
            state,
            AppState {
                rtc: &mut self.rtc,
                display: &mut self.display,
                state: &mut self.state,
                brightness: &mut self.brightness,
            },
        );
    }

    pub fn display(&mut self) -> &mut ClockDisplayViewer {
        &mut self.display
    }
}

impl ClockButton for ButtonSwitchView {
    fn handle(&self, state: ButtonState, app: AppState) {
        match state {
            ButtonState::JustPressed => {
                let display = app.display;
                let current_view =
                    display.current_view().unwrap_or(DisplayViews::ClockView) as usize;
                display.set_current_view(((current_view + 1) % DisplayViews::count()).into());
            }
            _ => (),
        }
    }
}

impl ClockButton for ButtonBrightness<Down> {
    fn handle(&self, state: ButtonState, app: AppState) {
        match state {
            ButtonState::JustPressed => {
                app.brightness
                    .set_brightness(app.brightness.brightness() as i8 - 10);
            }
            _ => (),
        }
    }
}

impl ClockButton for ButtonBrightness<Up> {
    fn handle(&self, state: ButtonState, app: AppState) {
        match state {
            ButtonState::JustPressed => {
                app.brightness
                    .set_brightness(app.brightness.brightness() as i8 + 10);
            }
            _ => (),
        }
    }
}

impl ClockButton for ButtonChangeTime {
    fn handle(&self, state: ButtonState, app: AppState) {
        match state {
            ButtonState::JustPressed => {
                app.rtc.set_time(app.rtc.current_time() + 2);
            }
            _ => (),
        }
    }
}
Do not follow this link