factored out transition state
This commit is contained in:
145
src/main.rs
145
src/main.rs
@@ -205,96 +205,134 @@ impl Show for NumberInput {
|
||||
|
||||
#[derive(uDebug)]
|
||||
enum State {
|
||||
EnterSignificant,
|
||||
EnterExponent,
|
||||
EnterOperation,
|
||||
Trans(TransState),
|
||||
Calc(CalcState),
|
||||
}
|
||||
|
||||
#[derive(uDebug)]
|
||||
enum TransState {
|
||||
Err { timeout: usize },
|
||||
}
|
||||
|
||||
impl State {
|
||||
impl TransState {
|
||||
fn on_frame(
|
||||
&mut self,
|
||||
key: Option<KeyPress>,
|
||||
number_input: &mut NumberInput,
|
||||
calc: &mut Calc,
|
||||
) -> Option<CalcState> {
|
||||
match self {
|
||||
TransState::Err { timeout: 0 } => {
|
||||
number_input.reset();
|
||||
calc.reset();
|
||||
Some(CalcState::EnterSignificant)
|
||||
}
|
||||
TransState::Err { timeout } => {
|
||||
*timeout -= 1;
|
||||
match key {
|
||||
Some(KeyPress::C) => {
|
||||
number_input.reset();
|
||||
calc.reset();
|
||||
Some(CalcState::EnterSignificant)
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(uDebug)]
|
||||
enum CalcState {
|
||||
EnterSignificant,
|
||||
EnterExponent,
|
||||
EnterOperation,
|
||||
}
|
||||
|
||||
impl CalcState {
|
||||
fn on_key(
|
||||
&self,
|
||||
key: KeyPress,
|
||||
number_input: &mut NumberInput,
|
||||
calc: &mut Calc,
|
||||
) -> Result<State, ()> {
|
||||
) -> Result<CalcState, ()> {
|
||||
match self {
|
||||
State::EnterSignificant => match key {
|
||||
CalcState::EnterSignificant => match key {
|
||||
KeyPress::C => {
|
||||
number_input.reset();
|
||||
calc.reset();
|
||||
Ok(State::EnterSignificant)
|
||||
Ok(CalcState::EnterSignificant)
|
||||
}
|
||||
KeyPress::Num(val) => {
|
||||
number_input.input(val)?;
|
||||
Ok(State::EnterSignificant)
|
||||
Ok(CalcState::EnterSignificant)
|
||||
}
|
||||
KeyPress::Minus => {
|
||||
number_input.toggle_minus();
|
||||
Ok(State::EnterSignificant)
|
||||
Ok(CalcState::EnterSignificant)
|
||||
}
|
||||
KeyPress::E => {
|
||||
number_input.enter_exponent();
|
||||
Ok(State::EnterExponent)
|
||||
Ok(CalcState::EnterExponent)
|
||||
}
|
||||
_ => Ok(State::EnterSignificant),
|
||||
_ => Ok(CalcState::EnterSignificant),
|
||||
},
|
||||
State::EnterExponent => match key {
|
||||
CalcState::EnterExponent => match key {
|
||||
KeyPress::C => {
|
||||
number_input.reset();
|
||||
calc.reset();
|
||||
Ok(State::EnterSignificant)
|
||||
Ok(CalcState::EnterSignificant)
|
||||
}
|
||||
KeyPress::Num(val) => {
|
||||
number_input.input(val)?;
|
||||
Ok(State::EnterExponent)
|
||||
Ok(CalcState::EnterExponent)
|
||||
}
|
||||
KeyPress::Minus => {
|
||||
number_input.toggle_minus();
|
||||
Ok(State::EnterExponent)
|
||||
Ok(CalcState::EnterExponent)
|
||||
}
|
||||
KeyPress::E => {
|
||||
number_input.done();
|
||||
match calc.push(number_input.to_decimal()) {
|
||||
Ok(()) => Ok(State::EnterOperation),
|
||||
Ok(()) => Ok(CalcState::EnterOperation),
|
||||
Err(_) => Err(()),
|
||||
}
|
||||
}
|
||||
_ => Ok(State::EnterExponent),
|
||||
_ => Ok(CalcState::EnterExponent),
|
||||
},
|
||||
State::EnterOperation => match key {
|
||||
CalcState::EnterOperation => match key {
|
||||
KeyPress::Up => todo!(),
|
||||
KeyPress::C => {
|
||||
number_input.reset();
|
||||
calc.reset();
|
||||
Ok(State::EnterSignificant)
|
||||
Ok(CalcState::EnterSignificant)
|
||||
}
|
||||
KeyPress::Num(_) => todo!(),
|
||||
KeyPress::Mul => match calc.mul() {
|
||||
Ok(dec) => {
|
||||
number_input.set_result(dec)?;
|
||||
Ok(State::EnterOperation)
|
||||
Ok(CalcState::EnterOperation)
|
||||
}
|
||||
Err(_) => Err(()),
|
||||
},
|
||||
KeyPress::Div => match calc.div() {
|
||||
Ok(dec) => {
|
||||
number_input.set_result(dec)?;
|
||||
Ok(State::EnterOperation)
|
||||
Ok(CalcState::EnterOperation)
|
||||
}
|
||||
Err(_) => Err(()),
|
||||
},
|
||||
KeyPress::Plus => match calc.add() {
|
||||
Ok(dec) => {
|
||||
number_input.set_result(dec)?;
|
||||
Ok(State::EnterOperation)
|
||||
Ok(CalcState::EnterOperation)
|
||||
}
|
||||
Err(_) => Err(()),
|
||||
},
|
||||
KeyPress::Minus => match calc.sub() {
|
||||
Ok(dec) => {
|
||||
number_input.set_result(dec)?;
|
||||
Ok(State::EnterOperation)
|
||||
Ok(CalcState::EnterOperation)
|
||||
}
|
||||
Err(_) => Err(()),
|
||||
},
|
||||
@@ -304,18 +342,10 @@ impl State {
|
||||
Err(())
|
||||
} else {
|
||||
number_input.reset();
|
||||
Ok(State::EnterSignificant)
|
||||
Ok(CalcState::EnterSignificant)
|
||||
}
|
||||
}
|
||||
},
|
||||
State::Err { timeout } => match key {
|
||||
KeyPress::C => {
|
||||
number_input.reset();
|
||||
calc.reset();
|
||||
Ok(State::EnterSignificant)
|
||||
}
|
||||
_ => Ok(State::Err { timeout: *timeout }),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -361,7 +391,7 @@ fn main() -> ! {
|
||||
number_input.show(&mut display);
|
||||
|
||||
let mut calc = Calc::default();
|
||||
let mut state = State::EnterSignificant;
|
||||
let mut state = State::Calc(CalcState::EnterSignificant);
|
||||
|
||||
loop {
|
||||
let mut last_key_readout: Option<KeyReadout> = None;
|
||||
@@ -378,40 +408,37 @@ fn main() -> ! {
|
||||
io_select.set_off();
|
||||
}
|
||||
|
||||
match &mut state {
|
||||
State::Err { timeout } if *timeout == 0 => {
|
||||
number_input.reset();
|
||||
calc.reset();
|
||||
state = State::EnterSignificant;
|
||||
number_input.show(&mut display);
|
||||
ufmt::uwriteln!(&mut serial, "err timout state: {:?}", state).unwrap_infallible();
|
||||
}
|
||||
State::Err { timeout } => {
|
||||
*timeout -= 1;
|
||||
}
|
||||
_ => (),
|
||||
let key = debounce.input(last_key_readout);
|
||||
|
||||
if let Some(key) = &key {
|
||||
ufmt::uwriteln!(&mut serial, "key: {:?} state: {:?}", key, state).unwrap_infallible();
|
||||
}
|
||||
|
||||
if let Some(key) = debounce.input(last_key_readout) {
|
||||
ufmt::uwriteln!(&mut serial, "key: {:?} state: {:?}", key, state).unwrap_infallible();
|
||||
match state.on_key(key, &mut number_input, &mut calc) {
|
||||
Ok(new_state) => state = new_state,
|
||||
Err(()) => {
|
||||
state = State::Err {
|
||||
timeout: ERROR_TIMEOUT,
|
||||
match &mut state {
|
||||
State::Trans(trans_state) => {
|
||||
if let Some(calc_state) = trans_state.on_frame(key, &mut number_input, &mut calc) {
|
||||
state = State::Calc(calc_state);
|
||||
}
|
||||
}
|
||||
State::Calc(calc_state) => {
|
||||
if let Some(key) = key {
|
||||
match calc_state.on_key(key, &mut number_input, &mut calc) {
|
||||
Ok(new_state) => *calc_state = new_state,
|
||||
Err(()) => {
|
||||
state = State::Trans(TransState::Err {
|
||||
timeout: ERROR_TIMEOUT,
|
||||
});
|
||||
}
|
||||
}
|
||||
ufmt::uwriteln!(&mut serial, "state: {:?} stack: {}", state, calc.len())
|
||||
.unwrap_infallible();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
match &state {
|
||||
State::EnterSignificant | State::EnterExponent | State::EnterOperation => {
|
||||
number_input.show(&mut display)
|
||||
}
|
||||
State::Err { .. } => {
|
||||
display.error();
|
||||
}
|
||||
}
|
||||
State::Trans(_) => display.error(),
|
||||
State::Calc(_) => number_input.show(&mut display),
|
||||
}
|
||||
|
||||
arduino_hal::delay_ms(1);
|
||||
|
||||
Reference in New Issue
Block a user