fw: comment pass
parent
0ccbf37bed
commit
5d200bad08
|
@ -1,4 +1,5 @@
|
|||
#[derive(Clone)]
|
||||
/// A stateful button debouncer.
|
||||
pub struct Buttons {
|
||||
state: [Option<u32>; 4],
|
||||
}
|
||||
|
@ -10,6 +11,8 @@ impl Buttons {
|
|||
}
|
||||
}
|
||||
|
||||
/// Update internal state from raw input state, with given millisecond timestamp. The input
|
||||
/// state is proccessed/debounced into the internal state.
|
||||
pub fn update(&mut self, ts: u32, state: [bool; 4]) {
|
||||
for (&s, v) in state.iter().zip(self.state.iter_mut()) {
|
||||
if let Some(pressed) = v {
|
||||
|
@ -29,6 +32,8 @@ impl Buttons {
|
|||
}
|
||||
}
|
||||
|
||||
/// Return a watcher, which is used to detect edge-triggered button events. Multiple
|
||||
/// independent watchers can exist, eg. for different downstream code.
|
||||
pub fn watch(&self) -> ButtonWatcher {
|
||||
let mut pending = [false; 4];
|
||||
for (i, v) in self.state.iter().enumerate() {
|
||||
|
@ -43,12 +48,17 @@ impl Buttons {
|
|||
}
|
||||
}
|
||||
|
||||
/// A edge-triggered button event watcher. Updates events from a Buttons struct and yields button
|
||||
/// press events once per button press.
|
||||
pub struct ButtonWatcher {
|
||||
state: [Option<u32>; 4],
|
||||
pending: [bool; 4],
|
||||
}
|
||||
|
||||
impl ButtonWatcher {
|
||||
/// Update internal state from Buttons. If any events are missed, a best effort is made to
|
||||
/// reconstruct missing presses - but for all presses to be available, they should be processed
|
||||
/// as early as possible via the events function.
|
||||
pub fn update(&mut self, buttons: &Buttons) {
|
||||
for (i, (v, o)) in self.state.iter_mut().zip(buttons.state.iter()).enumerate() {
|
||||
|
||||
|
@ -79,6 +89,8 @@ impl ButtonWatcher {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns an iterator over pending button presses. Button presses are registered as processed
|
||||
/// one-by-one as the returned iterator is consumed.
|
||||
pub fn events<'a>(&'a mut self) -> ButtonWatcherPending<'a> {
|
||||
ButtonWatcherPending {
|
||||
w: self,
|
||||
|
@ -86,6 +98,7 @@ impl ButtonWatcher {
|
|||
}
|
||||
}
|
||||
|
||||
/// Button press iterator, yielding a button number for each pending button press (edge-triggered).
|
||||
pub struct ButtonWatcherPending<'a> {
|
||||
w: &'a mut ButtonWatcher,
|
||||
}
|
||||
|
|
|
@ -17,31 +17,47 @@ use profont::{
|
|||
|
||||
use crate::input;
|
||||
|
||||
/// Color space that we expect to support: some form of RGB.
|
||||
pub trait ColorSpace = RgbColor + PixelColor;
|
||||
|
||||
/// Context passed to state tick functions.
|
||||
pub struct Context {
|
||||
pub buttons: input::Buttons,
|
||||
pub ticks: u32,
|
||||
}
|
||||
|
||||
/// Transitions (ie. FSM edges) returned by state tick functions.
|
||||
pub enum Transition {
|
||||
/// Do nothing (keep current state).
|
||||
Keep,
|
||||
/// Start the 'Running' state.
|
||||
Running {
|
||||
/// Tickcount at which the timer started running.
|
||||
start: u32,
|
||||
/// Number of milliseconds that the timer should run.
|
||||
msec: u32,
|
||||
},
|
||||
/// Start the 'Time Select' state.
|
||||
TimeSelect,
|
||||
}
|
||||
|
||||
/// State combining state logic, transition logic and drawing logic.
|
||||
pub trait State<D: DrawTarget<Color: ColorSpace>> {
|
||||
/// Called when the state becomes active, before tick is called.
|
||||
fn enter(&mut self, tr: Transition);
|
||||
/// Called on each tick of the application when the state is active.
|
||||
fn tick(&mut self, ctx: &Context) -> Transition;
|
||||
/// Called whenever the application can/should draw. Called after tick.
|
||||
fn draw(&mut self, target: &mut D) -> Result<(), <D as DrawTarget>::Error>;
|
||||
|
||||
/// Return the size of the target display. Helper function for draw().
|
||||
fn size(&mut self, target: &mut D) -> (u32, u32)
|
||||
{
|
||||
let bb = target.bounding_box();
|
||||
(bb.size.width, bb.size.height)
|
||||
}
|
||||
|
||||
/// Fully clear the target display with a given color. Helper function for draw().
|
||||
fn clear(&mut self, target: &mut D, color: D::Color) -> Result<(), <D as DrawTarget>::Error>
|
||||
{
|
||||
let (width, height) = self.size(target);
|
||||
|
@ -49,6 +65,8 @@ pub trait State<D: DrawTarget<Color: ColorSpace>> {
|
|||
.into_styled(PrimitiveStyle::with_fill(color))
|
||||
.draw(target)
|
||||
}
|
||||
|
||||
/// Draw bottom soft buttons. Each button should be one-character string. Helper for draw().
|
||||
fn draw_softbuttons(&mut self, target: &mut D, labels: [&str; 4]) ->
|
||||
Result<(), <D as DrawTarget>::Error>
|
||||
{
|
||||
|
@ -80,6 +98,8 @@ pub trait State<D: DrawTarget<Color: ColorSpace>> {
|
|||
}
|
||||
}
|
||||
|
||||
/// State used to select the time for the timer. Has +/- buttons and a start button (which
|
||||
/// transitions to Running).
|
||||
pub struct TimeSelect {
|
||||
cleared: bool,
|
||||
bw: Option<input::ButtonWatcher>,
|
||||
|
@ -195,6 +215,7 @@ impl<D: DrawTarget<Color: ColorSpace>> State<D> for TimeSelect {
|
|||
}
|
||||
}
|
||||
|
||||
/// State when the timer is counting down.
|
||||
pub struct Running {
|
||||
cleared: bool,
|
||||
msec: u32,
|
||||
|
|
Loading…
Reference in New Issue