fw: comment pass

main
q3k 2022-02-13 17:25:08 +00:00
parent 0ccbf37bed
commit 5d200bad08
2 changed files with 34 additions and 0 deletions

View File

@ -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,
}

View File

@ -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,