diff --git a/src/main.rs b/src/main.rs index e070df4..4ddd746 100644 --- a/src/main.rs +++ b/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, + number_input: &mut NumberInput, + calc: &mut Calc, + ) -> Option { + 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 { + ) -> Result { 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 = 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(); } } - 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(); - } - } + } + + match &state { + State::Trans(_) => display.error(), + State::Calc(_) => number_input.show(&mut display), } arduino_hal::delay_ms(1);