1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-01-08 22:40:59 +00:00

refactor(core/rust): streamline FlowState handling

* use the freed-up FlowState name for an alias to &'static dyn
FlowController
* replace StateChange with raw Decision
* move FlowState into Decision::Transition (the other Decisions should
not have the ability to change state
* also rename `transit` to `goto` which is a much better name
This commit is contained in:
matejcik 2024-09-05 14:51:54 +02:00 committed by matejcik
parent 9cc03c91d1
commit 48edb483a0
18 changed files with 163 additions and 171 deletions

View File

@ -16,7 +16,7 @@ pub enum Decision {
/// Initiate transition to another state, end event processing.
/// NOTE: it might make sense to include Option<ButtonRequest> here
Transition(AttachType),
Transition(FlowState, AttachType),
/// Yield a message to the caller of the flow (i.e. micropython), end event
/// processing.
@ -32,11 +32,14 @@ impl Decision {
}
}
/// State transition type.
/// Flow state type
///
/// Contains a new state (by convention it must be of the same concrete type as
/// the current one) and a Decision object that tells the flow what to do next.
pub type StateChange = (&'static dyn FlowController, Decision);
/// It is a static dyn reference to a FlowController, which, due to this, is required to
/// be a plain enum type. Its concrete values then are individual states.
///
/// By convention, a Decision emitted by a controller must embed a reference to the same
/// type of controller.
pub type FlowState = &'static dyn FlowController;
/// Encodes the flow logic as a set of states, and transitions between them
/// triggered by events and swipes.
@ -47,7 +50,7 @@ pub trait FlowController {
/// By convention, the type of the new state inside the state change must be
/// Self. This can't be enforced by the type system unfortunately, because
/// this trait must remain object-safe and so can't refer to Self.
fn handle_swipe(&'static self, direction: SwipeDirection) -> StateChange;
fn handle_swipe(&'static self, direction: SwipeDirection) -> Decision;
/// What to do when the current component emits a message in response to an
/// event.
@ -55,7 +58,7 @@ pub trait FlowController {
/// By convention, the type of the new state inside the state change must be
/// Self. This can't be enforced by the type system unfortunately, because
/// this trait must remain object-safe and so can't refer to Self.
fn handle_event(&'static self, msg: FlowMsg) -> StateChange;
fn handle_event(&'static self, msg: FlowMsg) -> Decision;
/// Page index of the current state.
fn index(&'static self) -> usize;
@ -64,43 +67,43 @@ pub trait FlowController {
/// Helper trait for writing nicer flow logic.
pub trait DecisionBuilder: FlowController + Sized {
#[inline]
fn swipe(&'static self, direction: SwipeDirection) -> StateChange {
(self, Decision::Transition(AttachType::Swipe(direction)))
fn swipe(&'static self, direction: SwipeDirection) -> Decision {
Decision::Transition(self, AttachType::Swipe(direction))
}
#[inline]
fn swipe_left(&'static self) -> StateChange {
fn swipe_left(&'static self) -> Decision {
self.swipe(SwipeDirection::Left)
}
#[inline]
fn swipe_right(&'static self) -> StateChange {
fn swipe_right(&'static self) -> Decision {
self.swipe(SwipeDirection::Right)
}
#[inline]
fn swipe_up(&'static self) -> StateChange {
fn swipe_up(&'static self) -> Decision {
self.swipe(SwipeDirection::Up)
}
#[inline]
fn swipe_down(&'static self) -> StateChange {
fn swipe_down(&'static self) -> Decision {
self.swipe(SwipeDirection::Down)
}
#[inline]
fn transit(&'static self) -> StateChange {
(self, Decision::Transition(AttachType::Initial))
fn goto(&'static self) -> Decision {
Decision::Transition(self, AttachType::Initial)
}
#[inline]
fn do_nothing(&'static self) -> StateChange {
(self, Decision::Nothing)
fn do_nothing(&'static self) -> Decision {
Decision::Nothing
}
#[inline]
fn return_msg(&'static self, msg: FlowMsg) -> StateChange {
(self, Decision::Return(msg))
fn return_msg(&'static self, msg: FlowMsg) -> Decision {
Decision::Return(msg)
}
}

View File

@ -20,7 +20,7 @@ use crate::{
},
};
use super::{base::StateChange, Swipable};
use super::{base::FlowState, Swipable};
use heapless::Vec;
@ -95,7 +95,7 @@ impl<T> FlowComponentDynTrait for T where
/// - if it can't then FlowState::handle_swipe is consulted.
pub struct SwipeFlow {
/// Current state of the flow.
state: &'static dyn FlowController,
state: FlowState,
/// Store of all screens which are part of the flow.
store: Vec<GcBox<dyn FlowComponentDynTrait>, 12>,
/// Swipe detector.
@ -108,7 +108,7 @@ pub struct SwipeFlow {
internal_pages: u16,
/// If triggering swipe by event, make this decision instead of default
/// after the swipe.
decision_override: Option<StateChange>,
decision_override: Option<Decision>,
}
impl SwipeFlow {
@ -173,30 +173,22 @@ impl SwipeFlow {
self.store[state].render(target);
}
fn handle_swipe_child(
&mut self,
_ctx: &mut EventCtx,
direction: SwipeDirection,
) -> StateChange {
fn handle_swipe_child(&mut self, _ctx: &mut EventCtx, direction: SwipeDirection) -> Decision {
self.state.handle_swipe(direction)
}
fn handle_event_child(&mut self, ctx: &mut EventCtx, event: Event) -> StateChange {
fn handle_event_child(&mut self, ctx: &mut EventCtx, event: Event) -> Decision {
let msg = self.current_page_mut().event(ctx, event);
if let Some(msg) = msg {
self.state.handle_event(msg)
} else {
(self.state, Decision::Nothing)
Decision::Nothing
}
}
fn state_unchanged(&self) -> StateChange {
(self.state, Decision::Nothing)
}
fn event(&mut self, ctx: &mut EventCtx, event: Event) -> Option<FlowMsg> {
let mut state_change = self.state_unchanged();
let mut decision = Decision::Nothing;
let mut return_transition: AttachType = AttachType::Initial;
let mut attach = false;
@ -212,9 +204,9 @@ impl SwipeFlow {
match self.swipe.event(ctx, event, config) {
Some(SwipeDetectMsg::Trigger(dir)) => {
if let Some(override_decision) = self.decision_override.take() {
state_change = override_decision;
decision = override_decision;
} else {
state_change = self.handle_swipe_child(ctx, dir);
decision = self.handle_swipe_child(ctx, dir);
}
return_transition = AttachType::Swipe(dir);
@ -223,7 +215,7 @@ impl SwipeFlow {
config.paging_event(dir, self.internal_state, self.internal_pages);
if new_internal_state != self.internal_state {
self.internal_state = new_internal_state;
state_change = self.state_unchanged();
decision = Decision::Nothing;
attach = true;
}
Event::Swipe(SwipeEvent::End(dir))
@ -238,9 +230,9 @@ impl SwipeFlow {
event
};
match state_change {
(_, Decision::Nothing) => {
state_change = self.handle_event_child(ctx, e);
match decision {
Decision::Nothing => {
decision = self.handle_event_child(ctx, e);
// when doing internal transition, pass attach event to the child after sending
// swipe end.
@ -262,12 +254,12 @@ impl SwipeFlow {
let config = self.current_page().get_swipe_config();
if let (_, Decision::Transition(Swipe(direction))) = state_change {
if let Decision::Transition(_, Swipe(direction)) = decision {
if config.is_allowed(direction) {
if !animation_disabled() {
self.swipe.trigger(ctx, direction, config);
self.decision_override = Some(state_change);
state_change = self.state_unchanged();
self.decision_override = Some(decision);
decision = Decision::Nothing;
}
self.allow_swipe = true;
}
@ -279,10 +271,8 @@ impl SwipeFlow {
}
}
let (new_state, decision) = state_change;
self.state = new_state;
match decision {
Decision::Transition(attach) => {
Decision::Transition(new_state, attach) => {
self.state = new_state;
self.goto(ctx, attach);
None

View File

@ -1,6 +1,5 @@
use crate::{
error,
error::Error,
error::{self, Error},
maybe_trace::MaybeTrace,
micropython::{map::Map, obj::Obj, qstr::Qstr, util},
strutil::TString,
@ -12,8 +11,8 @@ use crate::{
Component, ComponentExt, Paginate, SwipeDirection,
},
flow::{
base::{DecisionBuilder as _, StateChange},
FlowMsg, FlowController, SwipeFlow, SwipePage,
base::{Decision, DecisionBuilder as _},
FlowController, FlowMsg, SwipeFlow, SwipePage,
},
layout::obj::LayoutObj,
},
@ -38,7 +37,7 @@ impl FlowController for ConfirmAction {
*self as usize
}
fn handle_swipe(&'static self, direction: SwipeDirection) -> StateChange {
fn handle_swipe(&'static self, direction: SwipeDirection) -> Decision {
match (self, direction) {
(Self::Intro, SwipeDirection::Left) => Self::Menu.swipe(direction),
(Self::Menu, SwipeDirection::Right) => Self::Intro.swipe(direction),
@ -49,14 +48,14 @@ impl FlowController for ConfirmAction {
}
}
fn handle_event(&'static self, msg: FlowMsg) -> StateChange {
fn handle_event(&'static self, msg: FlowMsg) -> Decision {
match (self, msg) {
(Self::Intro, FlowMsg::Info) => Self::Menu.transit(),
(Self::Intro, FlowMsg::Info) => Self::Menu.goto(),
(Self::Menu, FlowMsg::Cancelled) => Self::Intro.swipe_right(),
(Self::Menu, FlowMsg::Choice(0)) => self.return_msg(FlowMsg::Cancelled),
(Self::Menu, FlowMsg::Choice(1)) => self.return_msg(FlowMsg::Info),
(Self::Confirm, FlowMsg::Confirmed) => self.return_msg(FlowMsg::Confirmed),
(Self::Confirm, FlowMsg::Info) => Self::Menu.transit(),
(Self::Confirm, FlowMsg::Info) => Self::Menu.goto(),
_ => self.do_nothing(),
}
}
@ -76,7 +75,7 @@ impl FlowController for ConfirmActionSimple {
*self as usize
}
fn handle_swipe(&'static self, direction: SwipeDirection) -> StateChange {
fn handle_swipe(&'static self, direction: SwipeDirection) -> Decision {
match (self, direction) {
(Self::Intro, SwipeDirection::Left) => Self::Menu.swipe(direction),
(Self::Menu, SwipeDirection::Right) => Self::Intro.swipe(direction),
@ -85,9 +84,9 @@ impl FlowController for ConfirmActionSimple {
}
}
fn handle_event(&'static self, msg: FlowMsg) -> StateChange {
fn handle_event(&'static self, msg: FlowMsg) -> Decision {
match (self, msg) {
(Self::Intro, FlowMsg::Info) => Self::Menu.transit(),
(Self::Intro, FlowMsg::Info) => Self::Menu.goto(),
(Self::Menu, FlowMsg::Cancelled) => Self::Intro.swipe_right(),
(Self::Menu, FlowMsg::Choice(0)) => self.return_msg(FlowMsg::Cancelled),
(Self::Menu, FlowMsg::Choice(1)) => self.return_msg(FlowMsg::Info),

View File

@ -10,7 +10,7 @@ use crate::{
ComponentExt, EventCtx, SwipeDirection,
},
flow::{
base::{DecisionBuilder as _, StateChange},
base::{Decision, DecisionBuilder as _},
FlowController, FlowMsg, SwipeFlow, SwipePage,
},
layout::obj::LayoutObj,
@ -45,7 +45,7 @@ impl FlowController for ConfirmFido {
*self as usize
}
fn handle_swipe(&'static self, direction: SwipeDirection) -> StateChange {
fn handle_swipe(&'static self, direction: SwipeDirection) -> Decision {
match (self, direction) {
(Self::Intro, SwipeDirection::Left) => Self::Menu.swipe(direction),
(Self::Intro, SwipeDirection::Up) => Self::ChooseCredential.swipe(direction),
@ -56,9 +56,9 @@ impl FlowController for ConfirmFido {
}
}
fn handle_event(&'static self, msg: FlowMsg) -> StateChange {
fn handle_event(&'static self, msg: FlowMsg) -> Decision {
match (self, msg) {
(_, FlowMsg::Info) => Self::Menu.transit(),
(_, FlowMsg::Info) => Self::Menu.goto(),
(Self::Menu, FlowMsg::Choice(0)) => self.return_msg(FlowMsg::Cancelled),
(Self::Menu, FlowMsg::Cancelled) => {
if Self::single_cred() {

View File

@ -10,8 +10,8 @@ use crate::{
ComponentExt, SwipeDirection,
},
flow::{
base::{DecisionBuilder as _, StateChange},
FlowMsg, FlowController, SwipeFlow,
base::{Decision, DecisionBuilder as _},
FlowController, FlowMsg, SwipeFlow,
},
layout::obj::LayoutObj,
},
@ -38,7 +38,7 @@ impl FlowController for ConfirmFirmwareUpdate {
*self as usize
}
fn handle_swipe(&'static self, direction: SwipeDirection) -> StateChange {
fn handle_swipe(&'static self, direction: SwipeDirection) -> Decision {
match (self, direction) {
(Self::Intro, SwipeDirection::Left) => Self::Menu.swipe(direction),
(Self::Intro, SwipeDirection::Up) => Self::Confirm.swipe(direction),
@ -50,15 +50,15 @@ impl FlowController for ConfirmFirmwareUpdate {
}
}
fn handle_event(&'static self, msg: FlowMsg) -> StateChange {
fn handle_event(&'static self, msg: FlowMsg) -> Decision {
match (self, msg) {
(Self::Intro, FlowMsg::Info) => Self::Menu.transit(),
(Self::Intro, FlowMsg::Info) => Self::Menu.goto(),
(Self::Menu, FlowMsg::Cancelled) => Self::Intro.swipe_right(),
(Self::Menu, FlowMsg::Choice(0)) => Self::Fingerprint.transit(),
(Self::Menu, FlowMsg::Choice(0)) => Self::Fingerprint.goto(),
(Self::Menu, FlowMsg::Choice(1)) => self.return_msg(FlowMsg::Cancelled),
(Self::Fingerprint, FlowMsg::Cancelled) => Self::Menu.transit(),
(Self::Fingerprint, FlowMsg::Cancelled) => Self::Menu.goto(),
(Self::Confirm, FlowMsg::Confirmed) => self.return_msg(FlowMsg::Confirmed),
(Self::Confirm, FlowMsg::Info) => Self::Menu.transit(),
(Self::Confirm, FlowMsg::Info) => Self::Menu.goto(),
_ => self.do_nothing(),
}
}

View File

@ -11,8 +11,8 @@ use crate::{
swipe_detect::SwipeSettings, ButtonRequestExt, ComponentExt, MsgMap, SwipeDirection,
},
flow::{
base::{DecisionBuilder as _, StateChange},
FlowMsg, FlowController, SwipeFlow,
base::{Decision, DecisionBuilder as _},
FlowController, FlowMsg, SwipeFlow,
},
layout::obj::LayoutObj,
},
@ -48,7 +48,7 @@ impl FlowController for ConfirmOutput {
*self as usize
}
fn handle_swipe(&'static self, direction: SwipeDirection) -> StateChange {
fn handle_swipe(&'static self, direction: SwipeDirection) -> Decision {
match (self, direction) {
(Self::Address, SwipeDirection::Left) => Self::Menu.swipe(direction),
(Self::Address, SwipeDirection::Up) => self.return_msg(FlowMsg::Confirmed),
@ -61,14 +61,14 @@ impl FlowController for ConfirmOutput {
}
}
fn handle_event(&'static self, msg: FlowMsg) -> StateChange {
fn handle_event(&'static self, msg: FlowMsg) -> Decision {
match (self, msg) {
(_, FlowMsg::Info) => Self::Menu.transit(),
(_, FlowMsg::Info) => Self::Menu.goto(),
(Self::Menu, FlowMsg::Choice(MENU_ITEM_CANCEL)) => Self::CancelTap.swipe_left(),
(Self::Menu, FlowMsg::Choice(MENU_ITEM_ACCOUNT_INFO)) => Self::AccountInfo.transit(),
(Self::Menu, FlowMsg::Choice(MENU_ITEM_ACCOUNT_INFO)) => Self::AccountInfo.goto(),
(Self::Menu, FlowMsg::Cancelled) => Self::Address.swipe_right(),
(Self::CancelTap, FlowMsg::Confirmed) => self.return_msg(FlowMsg::Cancelled),
(_, FlowMsg::Cancelled) => Self::Menu.transit(),
(_, FlowMsg::Cancelled) => Self::Menu.goto(),
_ => self.do_nothing(),
}
}
@ -89,7 +89,7 @@ impl FlowController for ConfirmOutputWithAmount {
*self as usize
}
fn handle_swipe(&'static self, direction: SwipeDirection) -> StateChange {
fn handle_swipe(&'static self, direction: SwipeDirection) -> Decision {
match (self, direction) {
(Self::Address | Self::Amount, SwipeDirection::Left) => Self::Menu.swipe(direction),
(Self::Address, SwipeDirection::Up) => Self::Amount.swipe(direction),
@ -103,14 +103,14 @@ impl FlowController for ConfirmOutputWithAmount {
}
}
fn handle_event(&'static self, msg: FlowMsg) -> StateChange {
fn handle_event(&'static self, msg: FlowMsg) -> Decision {
match (self, msg) {
(_, FlowMsg::Info) => Self::Menu.transit(),
(_, FlowMsg::Info) => Self::Menu.goto(),
(Self::Menu, FlowMsg::Choice(MENU_ITEM_CANCEL)) => Self::CancelTap.swipe_left(),
(Self::Menu, FlowMsg::Choice(MENU_ITEM_ACCOUNT_INFO)) => Self::AccountInfo.transit(),
(Self::Menu, FlowMsg::Choice(MENU_ITEM_ACCOUNT_INFO)) => Self::AccountInfo.goto(),
(Self::Menu, FlowMsg::Cancelled) => Self::Address.swipe_right(),
(Self::CancelTap, FlowMsg::Confirmed) => self.return_msg(FlowMsg::Cancelled),
(_, FlowMsg::Cancelled) => Self::Menu.transit(),
(_, FlowMsg::Cancelled) => Self::Menu.goto(),
_ => self.do_nothing(),
}
}
@ -138,7 +138,7 @@ impl FlowController for ConfirmOutputWithSummary {
*self as usize
}
fn handle_swipe(&'static self, direction: SwipeDirection) -> StateChange {
fn handle_swipe(&'static self, direction: SwipeDirection) -> Decision {
match (self, direction) {
(Self::Main, SwipeDirection::Left) => Self::MainMenu.swipe(direction),
(Self::Main, SwipeDirection::Up) => Self::Summary.swipe(direction),
@ -157,21 +157,21 @@ impl FlowController for ConfirmOutputWithSummary {
}
}
fn handle_event(&'static self, msg: FlowMsg) -> StateChange {
fn handle_event(&'static self, msg: FlowMsg) -> Decision {
match (self, msg) {
(Self::Main, FlowMsg::Info) => Self::MainMenu.transit(),
(Self::Main, FlowMsg::Info) => Self::MainMenu.goto(),
(Self::MainMenu, FlowMsg::Choice(MENU_ITEM_CANCEL)) => {
Self::MainMenuCancel.swipe_left()
}
(Self::AccountInfo, FlowMsg::Cancelled) => Self::MainMenu.swipe_right(),
(Self::MainMenuCancel, FlowMsg::Cancelled) => Self::MainMenu.swipe_right(),
(Self::AddressInfo, FlowMsg::Info) => Self::MainMenu.transit(),
(Self::Summary, FlowMsg::Info) => Self::SummaryMenu.transit(),
(Self::AddressInfo, FlowMsg::Info) => Self::MainMenu.goto(),
(Self::Summary, FlowMsg::Info) => Self::SummaryMenu.goto(),
(Self::SummaryMenu, FlowMsg::Choice(MENU_ITEM_CANCEL)) => {
Self::SummaryMenuCancel.swipe_left()
}
(Self::SummaryMenuCancel, FlowMsg::Cancelled) => Self::SummaryMenu.swipe_right(),
(Self::Hold, FlowMsg::Info) => Self::HoldMenu.transit(),
(Self::Hold, FlowMsg::Info) => Self::HoldMenu.goto(),
(Self::HoldMenu, FlowMsg::Choice(MENU_ITEM_CANCEL)) => {
Self::HoldMenuCancel.swipe_left()
}
@ -191,9 +191,9 @@ impl FlowController for ConfirmOutputWithSummary {
Self::MainMenuCancel | Self::SummaryMenuCancel | Self::HoldMenuCancel,
FlowMsg::Confirmed,
) => self.return_msg(FlowMsg::Cancelled),
(Self::Main, FlowMsg::Cancelled) => Self::MainMenu.transit(),
(Self::Summary, FlowMsg::Cancelled) => Self::SummaryMenu.transit(),
(Self::Hold, FlowMsg::Cancelled) => Self::HoldMenu.transit(),
(Self::Main, FlowMsg::Cancelled) => Self::MainMenu.goto(),
(Self::Summary, FlowMsg::Cancelled) => Self::SummaryMenu.goto(),
(Self::Hold, FlowMsg::Cancelled) => Self::HoldMenu.goto(),
(Self::Hold, FlowMsg::Confirmed) => self.return_msg(FlowMsg::Confirmed),
_ => self.do_nothing(),
}

View File

@ -11,8 +11,8 @@ use crate::{
ButtonRequestExt, ComponentExt, SwipeDirection,
},
flow::{
base::{DecisionBuilder as _, StateChange},
FlowMsg, FlowController, SwipeFlow,
base::{Decision, DecisionBuilder as _},
FlowController, FlowMsg, SwipeFlow,
},
layout::obj::LayoutObj,
},
@ -38,7 +38,7 @@ impl FlowController for ConfirmResetCreate {
*self as usize
}
fn handle_swipe(&'static self, direction: SwipeDirection) -> StateChange {
fn handle_swipe(&'static self, direction: SwipeDirection) -> Decision {
match (self, direction) {
(Self::Intro, SwipeDirection::Left) => Self::Menu.swipe(direction),
(Self::Intro, SwipeDirection::Up) => Self::Confirm.swipe(direction),
@ -49,13 +49,13 @@ impl FlowController for ConfirmResetCreate {
}
}
fn handle_event(&'static self, msg: FlowMsg) -> StateChange {
fn handle_event(&'static self, msg: FlowMsg) -> Decision {
match (self, msg) {
(Self::Intro, FlowMsg::Info) => Self::Menu.transit(),
(Self::Intro, FlowMsg::Info) => Self::Menu.goto(),
(Self::Menu, FlowMsg::Cancelled) => Self::Intro.swipe_right(),
(Self::Menu, FlowMsg::Choice(0)) => self.return_msg(FlowMsg::Cancelled),
(Self::Confirm, FlowMsg::Confirmed) => self.return_msg(FlowMsg::Confirmed),
(Self::Confirm, FlowMsg::Info) => Self::Menu.transit(),
(Self::Confirm, FlowMsg::Info) => Self::Menu.goto(),
_ => self.do_nothing(),
}
}
@ -73,7 +73,7 @@ impl FlowController for ConfirmResetRecover {
*self as usize
}
fn handle_swipe(&'static self, direction: SwipeDirection) -> StateChange {
fn handle_swipe(&'static self, direction: SwipeDirection) -> Decision {
match (self, direction) {
(Self::Intro, SwipeDirection::Left) => Self::Menu.swipe(direction),
(Self::Menu, SwipeDirection::Right) => Self::Intro.swipe(direction),
@ -82,9 +82,9 @@ impl FlowController for ConfirmResetRecover {
}
}
fn handle_event(&'static self, msg: FlowMsg) -> StateChange {
fn handle_event(&'static self, msg: FlowMsg) -> Decision {
match (self, msg) {
(Self::Intro, FlowMsg::Info) => Self::Menu.transit(),
(Self::Intro, FlowMsg::Info) => Self::Menu.goto(),
(Self::Menu, FlowMsg::Cancelled) => Self::Intro.swipe_right(),
(Self::Menu, FlowMsg::Choice(0)) => self.return_msg(FlowMsg::Cancelled),
_ => self.do_nothing(),

View File

@ -10,8 +10,8 @@ use crate::{
ComponentExt, SwipeDirection,
},
flow::{
base::{DecisionBuilder as _, StateChange},
FlowMsg, FlowController, SwipeFlow,
base::{Decision, DecisionBuilder as _},
FlowController, FlowMsg, SwipeFlow,
},
layout::obj::LayoutObj,
model_mercury::component::SwipeContent,
@ -37,7 +37,7 @@ impl FlowController for SetNewPin {
*self as usize
}
fn handle_swipe(&'static self, direction: SwipeDirection) -> StateChange {
fn handle_swipe(&'static self, direction: SwipeDirection) -> Decision {
match (self, direction) {
(Self::Intro, SwipeDirection::Left) => Self::Menu.swipe(direction),
(Self::Intro, SwipeDirection::Up) => self.return_msg(FlowMsg::Confirmed),
@ -50,9 +50,9 @@ impl FlowController for SetNewPin {
}
}
fn handle_event(&'static self, msg: FlowMsg) -> StateChange {
fn handle_event(&'static self, msg: FlowMsg) -> Decision {
match (self, msg) {
(Self::Intro, FlowMsg::Info) => Self::Menu.transit(),
(Self::Intro, FlowMsg::Info) => Self::Menu.goto(),
(Self::Menu, FlowMsg::Choice(0)) => Self::CancelPinIntro.swipe_left(),
(Self::Menu, FlowMsg::Cancelled) => Self::Intro.swipe_right(),
(Self::CancelPinIntro, FlowMsg::Cancelled) => Self::Intro.swipe_right(),

View File

@ -9,8 +9,8 @@ use crate::{
button_request::ButtonRequest,
component::{swipe_detect::SwipeSettings, ButtonRequestExt, ComponentExt, SwipeDirection},
flow::{
base::{DecisionBuilder as _, StateChange},
FlowMsg, FlowController, SwipeFlow,
base::{Decision, DecisionBuilder as _},
FlowController, FlowMsg, SwipeFlow,
},
layout::obj::LayoutObj,
model_mercury::component::SwipeContent,
@ -47,7 +47,7 @@ impl FlowController for ConfirmSummary {
*self as usize
}
fn handle_swipe(&'static self, direction: SwipeDirection) -> StateChange {
fn handle_swipe(&'static self, direction: SwipeDirection) -> Decision {
match (self, direction) {
(Self::Summary | Self::Hold, SwipeDirection::Left) => Self::Menu.swipe(direction),
(Self::Summary, SwipeDirection::Up) => Self::Hold.swipe(direction),
@ -60,16 +60,16 @@ impl FlowController for ConfirmSummary {
}
}
fn handle_event(&'static self, msg: FlowMsg) -> StateChange {
fn handle_event(&'static self, msg: FlowMsg) -> Decision {
match (self, msg) {
(_, FlowMsg::Info) => Self::Menu.transit(),
(_, FlowMsg::Info) => Self::Menu.goto(),
(Self::Hold, FlowMsg::Confirmed) => self.return_msg(FlowMsg::Confirmed),
(Self::Menu, FlowMsg::Choice(MENU_ITEM_CANCEL)) => Self::CancelTap.swipe_left(),
(Self::Menu, FlowMsg::Choice(MENU_ITEM_FEE_INFO)) => Self::FeeInfo.swipe_left(),
(Self::Menu, FlowMsg::Choice(MENU_ITEM_ACCOUNT_INFO)) => Self::AccountInfo.swipe_left(),
(Self::Menu, FlowMsg::Cancelled) => Self::Summary.swipe_right(),
(Self::CancelTap, FlowMsg::Confirmed) => self.return_msg(FlowMsg::Cancelled),
(_, FlowMsg::Cancelled) => Self::Menu.transit(),
(_, FlowMsg::Cancelled) => Self::Menu.goto(),
_ => self.do_nothing(),
}
}

View File

@ -14,8 +14,8 @@ use crate::{
ComponentExt, EventCtx, SwipeDirection,
},
flow::{
base::{DecisionBuilder as _, StateChange},
FlowMsg, FlowController, SwipeFlow, SwipePage,
base::{Decision, DecisionBuilder as _},
FlowController, FlowMsg, SwipeFlow, SwipePage,
},
layout::{obj::LayoutObj, util::RecoveryType},
},
@ -58,7 +58,7 @@ impl FlowController for ContinueRecoveryBeforeShares {
*self as usize
}
fn handle_swipe(&'static self, direction: SwipeDirection) -> StateChange {
fn handle_swipe(&'static self, direction: SwipeDirection) -> Decision {
match (self, direction) {
(Self::Main, SwipeDirection::Left) => Self::Menu.swipe(direction),
(Self::Menu, SwipeDirection::Right) => Self::Main.swipe(direction),
@ -67,9 +67,9 @@ impl FlowController for ContinueRecoveryBeforeShares {
}
}
fn handle_event(&'static self, msg: FlowMsg) -> StateChange {
fn handle_event(&'static self, msg: FlowMsg) -> Decision {
match (self, msg) {
(Self::Main, FlowMsg::Info) => Self::Menu.transit(),
(Self::Main, FlowMsg::Info) => Self::Menu.goto(),
(Self::Menu, FlowMsg::Cancelled) => Self::Main.swipe_right(),
(Self::Menu, FlowMsg::Choice(0)) => self.return_msg(FlowMsg::Cancelled),
_ => self.do_nothing(),
@ -83,7 +83,7 @@ impl FlowController for ContinueRecoveryBetweenShares {
*self as usize
}
fn handle_swipe(&'static self, direction: SwipeDirection) -> StateChange {
fn handle_swipe(&'static self, direction: SwipeDirection) -> Decision {
match (self, direction) {
(Self::Main, SwipeDirection::Left) => Self::Menu.swipe(direction),
(Self::Menu, SwipeDirection::Right) => Self::Main.swipe(direction),
@ -95,12 +95,12 @@ impl FlowController for ContinueRecoveryBetweenShares {
}
}
fn handle_event(&'static self, msg: FlowMsg) -> StateChange {
fn handle_event(&'static self, msg: FlowMsg) -> Decision {
match (self, msg) {
(Self::Main, FlowMsg::Info) => Self::Menu.transit(),
(Self::Main, FlowMsg::Info) => Self::Menu.goto(),
(Self::Menu, FlowMsg::Choice(0)) => Self::CancelIntro.swipe_left(),
(Self::Menu, FlowMsg::Cancelled) => Self::Main.swipe_right(),
(Self::CancelIntro, FlowMsg::Cancelled) => Self::Menu.transit(),
(Self::CancelIntro, FlowMsg::Cancelled) => Self::Menu.goto(),
(Self::CancelConfirm, FlowMsg::Cancelled) => Self::CancelIntro.swipe_right(),
(Self::CancelConfirm, FlowMsg::Confirmed) => self.return_msg(FlowMsg::Cancelled),
_ => self.do_nothing(),
@ -108,13 +108,13 @@ impl FlowController for ContinueRecoveryBetweenShares {
}
}
impl FlowState for ContinueRecoveryBetweenSharesAdvanced {
impl FlowController for ContinueRecoveryBetweenSharesAdvanced {
#[inline]
fn index(&'static self) -> usize {
*self as usize
}
fn handle_swipe(&'static self, direction: SwipeDirection) -> StateChange {
fn handle_swipe(&'static self, direction: SwipeDirection) -> Decision {
match (self, direction) {
(Self::Main, SwipeDirection::Left) => Self::Menu.swipe(direction),
(Self::Menu, SwipeDirection::Right) => Self::Main.swipe(direction),
@ -127,16 +127,16 @@ impl FlowState for ContinueRecoveryBetweenSharesAdvanced {
}
}
fn handle_event(&'static self, msg: FlowMsg) -> StateChange {
fn handle_event(&'static self, msg: FlowMsg) -> Decision {
match (self, msg) {
(Self::Main, FlowMsg::Info) => Self::Menu.transit(),
(Self::Menu, FlowMsg::Choice(0)) => Self::RemainingShares.transit(),
(Self::Main, FlowMsg::Info) => Self::Menu.goto(),
(Self::Menu, FlowMsg::Choice(0)) => Self::RemainingShares.goto(),
(Self::Menu, FlowMsg::Choice(1)) => Self::CancelIntro.swipe_left(),
(Self::Menu, FlowMsg::Cancelled) => Self::Main.swipe_right(),
(Self::CancelIntro, FlowMsg::Cancelled) => Self::Menu.transit(),
(Self::CancelIntro, FlowMsg::Cancelled) => Self::Menu.goto(),
(Self::CancelConfirm, FlowMsg::Cancelled) => Self::CancelIntro.swipe_right(),
(Self::CancelConfirm, FlowMsg::Confirmed) => self.return_msg(FlowMsg::Cancelled),
(Self::RemainingShares, FlowMsg::Cancelled) => Self::Menu.transit(),
(Self::RemainingShares, FlowMsg::Cancelled) => Self::Menu.goto(),
_ => self.do_nothing(),
}
}

View File

@ -11,8 +11,8 @@ use crate::{
ButtonRequestExt, ComponentExt, Qr, SwipeDirection,
},
flow::{
base::{DecisionBuilder as _, StateChange},
FlowMsg, FlowController, SwipeFlow, SwipePage,
base::{Decision, DecisionBuilder as _},
FlowController, FlowMsg, SwipeFlow, SwipePage,
},
layout::{obj::LayoutObj, util::ConfirmBlob},
},
@ -46,7 +46,7 @@ impl FlowController for GetAddress {
*self as usize
}
fn handle_swipe(&'static self, direction: SwipeDirection) -> StateChange {
fn handle_swipe(&'static self, direction: SwipeDirection) -> Decision {
match (self, direction) {
(Self::Address, SwipeDirection::Left) => Self::Menu.swipe(direction),
(Self::Address, SwipeDirection::Up) => Self::Tap.swipe(direction),
@ -63,9 +63,9 @@ impl FlowController for GetAddress {
}
}
fn handle_event(&'static self, msg: FlowMsg) -> StateChange {
fn handle_event(&'static self, msg: FlowMsg) -> Decision {
match (self, msg) {
(Self::Address, FlowMsg::Info) => Self::Menu.transit(),
(Self::Address, FlowMsg::Info) => Self::Menu.goto(),
(Self::Tap, FlowMsg::Confirmed) => Self::Confirmed.swipe_up(),
(Self::Tap, FlowMsg::Info) => Self::Menu.swipe_left(),
(Self::Confirmed, _) => self.return_msg(FlowMsg::Confirmed),
@ -73,11 +73,11 @@ impl FlowController for GetAddress {
(Self::Menu, FlowMsg::Choice(1)) => Self::AccountInfo.swipe_left(),
(Self::Menu, FlowMsg::Choice(2)) => Self::Cancel.swipe_left(),
(Self::Menu, FlowMsg::Cancelled) => Self::Address.swipe_right(),
(Self::QrCode, FlowMsg::Cancelled) => Self::Menu.transit(),
(Self::AccountInfo, FlowMsg::Cancelled) => Self::Menu.transit(),
(Self::Cancel, FlowMsg::Cancelled) => Self::Menu.transit(),
(Self::QrCode, FlowMsg::Cancelled) => Self::Menu.goto(),
(Self::AccountInfo, FlowMsg::Cancelled) => Self::Menu.goto(),
(Self::Cancel, FlowMsg::Cancelled) => Self::Menu.goto(),
(Self::CancelTap, FlowMsg::Confirmed) => self.return_msg(FlowMsg::Cancelled),
(Self::CancelTap, FlowMsg::Cancelled) => Self::Menu.transit(),
(Self::CancelTap, FlowMsg::Cancelled) => Self::Menu.goto(),
_ => self.do_nothing(),
}
}

View File

@ -10,8 +10,8 @@ use crate::{
ComponentExt, SwipeDirection,
},
flow::{
base::{DecisionBuilder as _, StateChange},
FlowMsg, FlowController, SwipeFlow,
base::{Decision, DecisionBuilder as _},
FlowController, FlowMsg, SwipeFlow,
},
layout::obj::LayoutObj,
},
@ -38,7 +38,7 @@ impl FlowController for PromptBackup {
*self as usize
}
fn handle_swipe(&'static self, direction: SwipeDirection) -> StateChange {
fn handle_swipe(&'static self, direction: SwipeDirection) -> Decision {
match (self, direction) {
(Self::Intro, SwipeDirection::Left) => Self::Menu.swipe(direction),
(Self::Intro, SwipeDirection::Up) => self.return_msg(FlowMsg::Confirmed),
@ -53,12 +53,12 @@ impl FlowController for PromptBackup {
}
}
fn handle_event(&'static self, msg: FlowMsg) -> StateChange {
fn handle_event(&'static self, msg: FlowMsg) -> Decision {
match (self, msg) {
(Self::Intro, FlowMsg::Info) => Self::Menu.transit(),
(Self::Intro, FlowMsg::Info) => Self::Menu.goto(),
(Self::Menu, FlowMsg::Choice(0)) => Self::SkipBackupIntro.swipe_left(),
(Self::Menu, FlowMsg::Cancelled) => Self::Intro.swipe_right(),
(Self::SkipBackupIntro, FlowMsg::Cancelled) => Self::Menu.transit(),
(Self::SkipBackupIntro, FlowMsg::Cancelled) => Self::Menu.goto(),
(Self::SkipBackupConfirm, FlowMsg::Cancelled) => Self::SkipBackupIntro.swipe_right(),
(Self::SkipBackupConfirm, FlowMsg::Confirmed) => self.return_msg(FlowMsg::Cancelled),
_ => self.do_nothing(),

View File

@ -7,8 +7,8 @@ use crate::{
button_request::ButtonRequest,
component::{swipe_detect::SwipeSettings, ButtonRequestExt, ComponentExt, SwipeDirection},
flow::{
base::{DecisionBuilder as _, StateChange},
FlowMsg, FlowController, SwipeFlow,
base::{Decision, DecisionBuilder as _},
FlowController, FlowMsg, SwipeFlow,
},
layout::obj::LayoutObj,
},
@ -37,7 +37,7 @@ impl FlowController for RequestNumber {
*self as usize
}
fn handle_swipe(&'static self, direction: SwipeDirection) -> StateChange {
fn handle_swipe(&'static self, direction: SwipeDirection) -> Decision {
match (self, direction) {
(Self::Number, SwipeDirection::Left) => Self::Menu.swipe(direction),
(Self::Menu, SwipeDirection::Right) => Self::Number.swipe(direction),
@ -46,12 +46,12 @@ impl FlowController for RequestNumber {
}
}
fn handle_event(&'static self, msg: FlowMsg) -> StateChange {
fn handle_event(&'static self, msg: FlowMsg) -> Decision {
match (self, msg) {
(Self::Number, FlowMsg::Info) => Self::Menu.transit(),
(Self::Number, FlowMsg::Info) => Self::Menu.goto(),
(Self::Menu, FlowMsg::Choice(0)) => Self::Info.swipe_left(),
(Self::Menu, FlowMsg::Cancelled) => Self::Number.swipe_right(),
(Self::Info, FlowMsg::Cancelled) => Self::Menu.transit(),
(Self::Info, FlowMsg::Cancelled) => Self::Menu.goto(),
(Self::Number, FlowMsg::Choice(n)) => self.return_msg(FlowMsg::Choice(n)),
_ => self.do_nothing(),
}

View File

@ -6,8 +6,8 @@ use crate::{
ui::{
component::{ComponentExt, SwipeDirection},
flow::{
base::{DecisionBuilder as _, StateChange},
FlowMsg, FlowController, SwipeFlow,
base::{Decision, DecisionBuilder as _},
FlowController, FlowMsg, SwipeFlow,
},
layout::obj::LayoutObj,
},
@ -29,21 +29,21 @@ impl FlowController for RequestPassphrase {
*self as usize
}
fn handle_swipe(&'static self, _direction: SwipeDirection) -> StateChange {
fn handle_swipe(&'static self, _direction: SwipeDirection) -> Decision {
self.do_nothing()
}
fn handle_event(&'static self, msg: FlowMsg) -> StateChange {
fn handle_event(&'static self, msg: FlowMsg) -> Decision {
match (self, msg) {
(Self::Keypad, FlowMsg::Text(s)) => {
if s.is_empty() {
Self::ConfirmEmpty.transit()
Self::ConfirmEmpty.goto()
} else {
self.return_msg(FlowMsg::Text(s))
}
}
(Self::Keypad, FlowMsg::Cancelled) => self.return_msg(FlowMsg::Cancelled),
(Self::ConfirmEmpty, FlowMsg::Cancelled) => Self::Keypad.transit(),
(Self::ConfirmEmpty, FlowMsg::Cancelled) => Self::Keypad.goto(),
(Self::ConfirmEmpty, FlowMsg::Confirmed) => {
self.return_msg(FlowMsg::Text(ShortString::new()))
}

View File

@ -9,7 +9,7 @@ use crate::{
ui::{
component::{base::ComponentExt, swipe_detect::SwipeSettings, FlowMsg, SwipeDirection},
flow::{
base::{DecisionBuilder as _, StateChange},
base::{Decision, DecisionBuilder as _},
FlowController, SwipeFlow,
},
layout::obj::LayoutObj,
@ -39,7 +39,7 @@ impl FlowController for SetBrightness {
*self as usize
}
fn handle_swipe(&'static self, direction: SwipeDirection) -> StateChange {
fn handle_swipe(&'static self, direction: SwipeDirection) -> Decision {
match (self, direction) {
(Self::Menu, SwipeDirection::Right) => Self::Slider.swipe(direction),
(Self::Slider, SwipeDirection::Up) => Self::Confirm.swipe(direction),
@ -50,7 +50,7 @@ impl FlowController for SetBrightness {
}
}
fn handle_event(&'static self, msg: FlowMsg) -> StateChange {
fn handle_event(&'static self, msg: FlowMsg) -> Decision {
match (self, msg) {
(Self::Slider, FlowMsg::Info) => Self::Menu.swipe_left(),
(Self::Menu, FlowMsg::Cancelled) => Self::Slider.swipe_right(),

View File

@ -11,8 +11,8 @@ use crate::{
ButtonRequestExt, ComponentExt, EventCtx, SwipeDirection,
},
flow::{
base::{DecisionBuilder as _, StateChange},
FlowMsg, FlowController, SwipeFlow,
base::{Decision, DecisionBuilder as _},
FlowController, FlowMsg, SwipeFlow,
},
layout::obj::LayoutObj,
model_mercury::component::{InternallySwipable, InternallySwipableContent, SwipeContent},
@ -39,7 +39,7 @@ impl FlowController for ShowShareWords {
*self as usize
}
fn handle_swipe(&'static self, direction: SwipeDirection) -> StateChange {
fn handle_swipe(&'static self, direction: SwipeDirection) -> Decision {
match (self, direction) {
(Self::Instruction, SwipeDirection::Up) => Self::Words.swipe(direction),
(Self::Confirm, SwipeDirection::Down) => Self::Words.swipe(direction),
@ -50,7 +50,7 @@ impl FlowController for ShowShareWords {
}
}
fn handle_event(&'static self, msg: FlowMsg) -> StateChange {
fn handle_event(&'static self, msg: FlowMsg) -> Decision {
match (self, msg) {
(Self::Words, FlowMsg::Cancelled) => Self::Instruction.swipe_down(),
(Self::Words, FlowMsg::Confirmed) => Self::Confirm.swipe_up(),

View File

@ -9,8 +9,8 @@ use crate::{
ComponentExt, SwipeDirection,
},
flow::{
base::{DecisionBuilder as _, StateChange},
FlowMsg, FlowController, SwipeFlow,
base::{Decision, DecisionBuilder as _},
FlowController, FlowMsg, SwipeFlow,
},
layout::obj::LayoutObj,
},
@ -42,7 +42,7 @@ impl FlowController for ShowTutorial {
*self as usize
}
fn handle_swipe(&'static self, direction: SwipeDirection) -> StateChange {
fn handle_swipe(&'static self, direction: SwipeDirection) -> Decision {
match (self, direction) {
(Self::StepBegin, SwipeDirection::Up) => Self::StepNavigation.swipe(direction),
(Self::StepNavigation, SwipeDirection::Up) => Self::StepMenu.swipe(direction),
@ -58,15 +58,15 @@ impl FlowController for ShowTutorial {
}
}
fn handle_event(&'static self, msg: FlowMsg) -> StateChange {
fn handle_event(&'static self, msg: FlowMsg) -> Decision {
match (self, msg) {
(Self::StepWelcome, FlowMsg::Confirmed) => Self::StepBegin.swipe_up(),
(Self::StepMenu, FlowMsg::Info) => Self::Menu.transit(),
(Self::StepMenu, FlowMsg::Info) => Self::Menu.goto(),
(Self::Menu, FlowMsg::Choice(0)) => Self::DidYouKnow.swipe_left(),
(Self::Menu, FlowMsg::Choice(1)) => Self::StepBegin.swipe_right(),
(Self::Menu, FlowMsg::Choice(2)) => Self::HoldToExit.swipe_up(),
(Self::Menu, FlowMsg::Cancelled) => Self::StepMenu.swipe_right(),
(Self::DidYouKnow, FlowMsg::Cancelled) => Self::Menu.transit(),
(Self::DidYouKnow, FlowMsg::Cancelled) => Self::Menu.goto(),
(Self::StepHold, FlowMsg::Confirmed) => Self::StepDone.swipe_up(),
(Self::HoldToExit, FlowMsg::Confirmed) => Self::StepDone.swipe_up(),
_ => self.do_nothing(),

View File

@ -10,8 +10,8 @@ use crate::{
ComponentExt, SwipeDirection,
},
flow::{
base::{DecisionBuilder as _, StateChange},
FlowMsg, FlowController, SwipeFlow,
base::{Decision, DecisionBuilder as _},
FlowController, FlowMsg, SwipeFlow,
},
layout::obj::LayoutObj,
model_mercury::component::SwipeContent,
@ -36,7 +36,7 @@ impl FlowController for WarningHiPrio {
*self as usize
}
fn handle_swipe(&'static self, direction: SwipeDirection) -> StateChange {
fn handle_swipe(&'static self, direction: SwipeDirection) -> Decision {
match (self, direction) {
(Self::Message, SwipeDirection::Left) => Self::Menu.swipe(direction),
(Self::Message, SwipeDirection::Up) => Self::Cancelled.swipe(direction),
@ -45,9 +45,9 @@ impl FlowController for WarningHiPrio {
}
}
fn handle_event(&'static self, msg: FlowMsg) -> StateChange {
fn handle_event(&'static self, msg: FlowMsg) -> Decision {
match (self, msg) {
(Self::Message, FlowMsg::Info) => Self::Menu.transit(),
(Self::Message, FlowMsg::Info) => Self::Menu.goto(),
(Self::Menu, FlowMsg::Choice(1)) => self.return_msg(FlowMsg::Confirmed),
(Self::Menu, FlowMsg::Choice(_)) => Self::Cancelled.swipe_up(),
(Self::Menu, FlowMsg::Cancelled) => Self::Message.swipe_right(),