transient state keeps calculator state
This commit is contained in:
113
src/main.rs
113
src/main.rs
@@ -204,135 +204,128 @@ impl Show for NumberInput {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(uDebug)]
|
#[derive(uDebug)]
|
||||||
enum State {
|
struct State {
|
||||||
Trans(TransState),
|
transient: TransientState,
|
||||||
Calc(CalcState),
|
calculator: CalcluclatorState,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(uDebug)]
|
#[derive(uDebug)]
|
||||||
enum TransState {
|
enum TransientState {
|
||||||
|
Done,
|
||||||
Err { timeout: usize },
|
Err { timeout: usize },
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TransState {
|
impl TransientState {
|
||||||
fn on_frame(
|
fn on_frame(&mut self, key: Option<KeyPress>) {
|
||||||
&mut self,
|
|
||||||
key: Option<KeyPress>,
|
|
||||||
number_input: &mut NumberInput,
|
|
||||||
calc: &mut Calc,
|
|
||||||
) -> Option<CalcState> {
|
|
||||||
match self {
|
match self {
|
||||||
TransState::Err { timeout: 0 } => {
|
TransientState::Err { timeout: 0 } => {
|
||||||
number_input.reset();
|
*self = TransientState::Done;
|
||||||
calc.reset();
|
|
||||||
Some(CalcState::EnterSignificant)
|
|
||||||
}
|
}
|
||||||
TransState::Err { timeout } => {
|
TransientState::Err { timeout } => {
|
||||||
*timeout -= 1;
|
*timeout -= 1;
|
||||||
match key {
|
match key {
|
||||||
Some(KeyPress::C) => {
|
Some(KeyPress::C) => {
|
||||||
number_input.reset();
|
*self = TransientState::Done;
|
||||||
calc.reset();
|
|
||||||
Some(CalcState::EnterSignificant)
|
|
||||||
}
|
}
|
||||||
_ => None,
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
TransientState::Done => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(uDebug)]
|
#[derive(uDebug)]
|
||||||
enum CalcState {
|
enum CalcluclatorState {
|
||||||
EnterSignificant,
|
EnterSignificant,
|
||||||
EnterExponent,
|
EnterExponent,
|
||||||
EnterOperation,
|
EnterOperation,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CalcState {
|
impl CalcluclatorState {
|
||||||
fn on_key(
|
fn on_key(
|
||||||
&self,
|
&self,
|
||||||
key: KeyPress,
|
key: KeyPress,
|
||||||
number_input: &mut NumberInput,
|
number_input: &mut NumberInput,
|
||||||
calc: &mut Calc,
|
calc: &mut Calc,
|
||||||
) -> Result<CalcState, ()> {
|
) -> Result<CalcluclatorState, ()> {
|
||||||
match self {
|
match self {
|
||||||
CalcState::EnterSignificant => match key {
|
CalcluclatorState::EnterSignificant => match key {
|
||||||
KeyPress::C => {
|
KeyPress::C => {
|
||||||
number_input.reset();
|
number_input.reset();
|
||||||
calc.reset();
|
calc.reset();
|
||||||
Ok(CalcState::EnterSignificant)
|
Ok(CalcluclatorState::EnterSignificant)
|
||||||
}
|
}
|
||||||
KeyPress::Num(val) => {
|
KeyPress::Num(val) => {
|
||||||
number_input.input(val)?;
|
number_input.input(val)?;
|
||||||
Ok(CalcState::EnterSignificant)
|
Ok(CalcluclatorState::EnterSignificant)
|
||||||
}
|
}
|
||||||
KeyPress::Minus => {
|
KeyPress::Minus => {
|
||||||
number_input.toggle_minus();
|
number_input.toggle_minus();
|
||||||
Ok(CalcState::EnterSignificant)
|
Ok(CalcluclatorState::EnterSignificant)
|
||||||
}
|
}
|
||||||
KeyPress::E => {
|
KeyPress::E => {
|
||||||
number_input.enter_exponent();
|
number_input.enter_exponent();
|
||||||
Ok(CalcState::EnterExponent)
|
Ok(CalcluclatorState::EnterExponent)
|
||||||
}
|
}
|
||||||
_ => Ok(CalcState::EnterSignificant),
|
_ => Ok(CalcluclatorState::EnterSignificant),
|
||||||
},
|
},
|
||||||
CalcState::EnterExponent => match key {
|
CalcluclatorState::EnterExponent => match key {
|
||||||
KeyPress::C => {
|
KeyPress::C => {
|
||||||
number_input.reset();
|
number_input.reset();
|
||||||
calc.reset();
|
calc.reset();
|
||||||
Ok(CalcState::EnterSignificant)
|
Ok(CalcluclatorState::EnterSignificant)
|
||||||
}
|
}
|
||||||
KeyPress::Num(val) => {
|
KeyPress::Num(val) => {
|
||||||
number_input.input(val)?;
|
number_input.input(val)?;
|
||||||
Ok(CalcState::EnterExponent)
|
Ok(CalcluclatorState::EnterExponent)
|
||||||
}
|
}
|
||||||
KeyPress::Minus => {
|
KeyPress::Minus => {
|
||||||
number_input.toggle_minus();
|
number_input.toggle_minus();
|
||||||
Ok(CalcState::EnterExponent)
|
Ok(CalcluclatorState::EnterExponent)
|
||||||
}
|
}
|
||||||
KeyPress::E => {
|
KeyPress::E => {
|
||||||
number_input.done();
|
number_input.done();
|
||||||
match calc.push(number_input.to_decimal()) {
|
match calc.push(number_input.to_decimal()) {
|
||||||
Ok(()) => Ok(CalcState::EnterOperation),
|
Ok(()) => Ok(CalcluclatorState::EnterOperation),
|
||||||
Err(_) => Err(()),
|
Err(_) => Err(()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => Ok(CalcState::EnterExponent),
|
_ => Ok(CalcluclatorState::EnterExponent),
|
||||||
},
|
},
|
||||||
CalcState::EnterOperation => match key {
|
CalcluclatorState::EnterOperation => match key {
|
||||||
KeyPress::Up => todo!(),
|
KeyPress::Up => todo!(),
|
||||||
KeyPress::C => {
|
KeyPress::C => {
|
||||||
number_input.reset();
|
number_input.reset();
|
||||||
calc.reset();
|
calc.reset();
|
||||||
Ok(CalcState::EnterSignificant)
|
Ok(CalcluclatorState::EnterSignificant)
|
||||||
}
|
}
|
||||||
KeyPress::Num(_) => todo!(),
|
KeyPress::Num(_) => todo!(),
|
||||||
KeyPress::Mul => match calc.mul() {
|
KeyPress::Mul => match calc.mul() {
|
||||||
Ok(dec) => {
|
Ok(dec) => {
|
||||||
number_input.set_result(dec)?;
|
number_input.set_result(dec)?;
|
||||||
Ok(CalcState::EnterOperation)
|
Ok(CalcluclatorState::EnterOperation)
|
||||||
}
|
}
|
||||||
Err(_) => Err(()),
|
Err(_) => Err(()),
|
||||||
},
|
},
|
||||||
KeyPress::Div => match calc.div() {
|
KeyPress::Div => match calc.div() {
|
||||||
Ok(dec) => {
|
Ok(dec) => {
|
||||||
number_input.set_result(dec)?;
|
number_input.set_result(dec)?;
|
||||||
Ok(CalcState::EnterOperation)
|
Ok(CalcluclatorState::EnterOperation)
|
||||||
}
|
}
|
||||||
Err(_) => Err(()),
|
Err(_) => Err(()),
|
||||||
},
|
},
|
||||||
KeyPress::Plus => match calc.add() {
|
KeyPress::Plus => match calc.add() {
|
||||||
Ok(dec) => {
|
Ok(dec) => {
|
||||||
number_input.set_result(dec)?;
|
number_input.set_result(dec)?;
|
||||||
Ok(CalcState::EnterOperation)
|
Ok(CalcluclatorState::EnterOperation)
|
||||||
}
|
}
|
||||||
Err(_) => Err(()),
|
Err(_) => Err(()),
|
||||||
},
|
},
|
||||||
KeyPress::Minus => match calc.sub() {
|
KeyPress::Minus => match calc.sub() {
|
||||||
Ok(dec) => {
|
Ok(dec) => {
|
||||||
number_input.set_result(dec)?;
|
number_input.set_result(dec)?;
|
||||||
Ok(CalcState::EnterOperation)
|
Ok(CalcluclatorState::EnterOperation)
|
||||||
}
|
}
|
||||||
Err(_) => Err(()),
|
Err(_) => Err(()),
|
||||||
},
|
},
|
||||||
@@ -342,7 +335,7 @@ impl CalcState {
|
|||||||
Err(())
|
Err(())
|
||||||
} else {
|
} else {
|
||||||
number_input.reset();
|
number_input.reset();
|
||||||
Ok(CalcState::EnterSignificant)
|
Ok(CalcluclatorState::EnterSignificant)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -391,7 +384,10 @@ fn main() -> ! {
|
|||||||
number_input.show(&mut display);
|
number_input.show(&mut display);
|
||||||
|
|
||||||
let mut calc = Calc::default();
|
let mut calc = Calc::default();
|
||||||
let mut state = State::Calc(CalcState::EnterSignificant);
|
let mut state = State {
|
||||||
|
transient: TransientState::Done,
|
||||||
|
calculator: CalcluclatorState::EnterSignificant,
|
||||||
|
};
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let mut last_key_readout: Option<KeyReadout> = None;
|
let mut last_key_readout: Option<KeyReadout> = None;
|
||||||
@@ -414,39 +410,28 @@ fn main() -> ! {
|
|||||||
ufmt::uwriteln!(&mut serial, "key: {:?} state: {:?}", key, state).unwrap_infallible();
|
ufmt::uwriteln!(&mut serial, "key: {:?} state: {:?}", key, state).unwrap_infallible();
|
||||||
}
|
}
|
||||||
|
|
||||||
match &mut state {
|
if let TransientState::Done = state.transient {
|
||||||
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 {
|
if let Some(key) = key {
|
||||||
match calc_state.on_key(key, &mut number_input, &mut calc) {
|
match state.calculator.on_key(key, &mut number_input, &mut calc) {
|
||||||
Ok(new_state) => *calc_state = new_state,
|
Ok(new_state) => state.calculator = new_state,
|
||||||
Err(()) => {
|
Err(()) => {
|
||||||
state = State::Trans(TransState::Err {
|
state.transient = TransientState::Err {
|
||||||
timeout: ERROR_TIMEOUT,
|
timeout: ERROR_TIMEOUT,
|
||||||
});
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ufmt::uwriteln!(&mut serial, "state: {:?} stack: {}", state, calc.len())
|
ufmt::uwriteln!(&mut serial, "state: {:?} stack: {}", state, calc.len())
|
||||||
.unwrap_infallible();
|
.unwrap_infallible();
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
|
state.transient.on_frame(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
match &state {
|
match &state.transient {
|
||||||
State::Trans(_) => display.error(),
|
TransientState::Done => number_input.show(&mut display),
|
||||||
State::Calc(_) => number_input.show(&mut display),
|
TransientState::Err { .. } => display.error(),
|
||||||
}
|
}
|
||||||
|
|
||||||
arduino_hal::delay_ms(1);
|
arduino_hal::delay_ms(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// loop {
|
|
||||||
// led.toggle();
|
|
||||||
// arduino_hal::delay_ms(1000);
|
|
||||||
// ufmt::uwrite!(&mut serial, ".").unwrap_infallible();
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user