pub trait StateMachine<T, U, V>{
// Required methods
fn update(&mut self);
fn top_down_update(&mut self);
fn transition(&mut self, target: T);
fn exact_transition(&mut self, target: T);
fn state(&self) -> T;
fn state_matches(&self, state: T) -> bool;
fn top_ref(&self) -> &V;
fn top_mut(&mut self) -> &mut V;
fn name(&self) -> &str;
fn set_name(&mut self, name: String);
fn handle_event(&mut self, event: &U);
fn state_list(&self) -> Vec<T>;
}Expand description
A state machine.
Required Methods§
Sourcefn update(&mut self)
fn update(&mut self)
Update the state machine.
Starting with the deepest state, calls Substate::update (or TopState::update).
If any state returns Some(state) from its update method, that transition will be
completed and the state machine will continue updating states starting from the nearest
common ancestor of the previous state and the new state after transition.
§Example
For some machine:
Top
├─ Foo
│ └─ Bar
└─ Fizz
└─ BuzzIf the Substate::update method of the Bar state returns State::Buzz.into(),
then:
assert!(matches!(machine.state(), State::Bar));
machine.update();Will have the log output of:
Example: Updating
│Updating Bar
│Transitioning from Bar to Buzz
││Exiting Bar
││Exiting Foo
││Entering Fizz
││Entering Buzz
│└Transition complete
│Updating Top
└Update completeTop being the nearest common ancestor of the starting state, Bar, and the new state,
Buzz, so the update continues from Top.
Sourcefn top_down_update(&mut self)
fn top_down_update(&mut self)
Top-down update the state machine.
Starting with the TopState, calls Substate::top_down_update (or TopState::top_down_update).
Useful for propagating changes to state fields before calling StateMachine::update, or for
simply inverting the precedence of transitions (superstates may trigger transitions before
their substates).
If any state returns Some(state) from its update method, that transition will be
completed and the state machine will continue updating states starting from the first
active descendent of the nearest common ancestor of the previous state and the new state
after transition.
§Example
For some machine:
Top
├─ Foo
│ └─ Bar
└─ Fizz
└─ BuzzIf the Substate::top_down_update method of the Foo state returns State::Buzz.into(),
then:
assert!(matches!(machine.state(), State::Foo));
machine.top_down_update();Will have the log output of:
Example: Top-down updating
│Top-down updating Top
│Top-down updating Foo
│Transitioning from Foo to Fizz
││Exiting Foo
││Entering Fizz
││Entering Buzz
│└Transition complete
│Top-down updating Fizz
│Top-down updating Buzz
└Top-down update completeTop being the nearest common ancestor of the starting state, Foo, and the new state,
Fizz, so the top-down update continues from the first active descendent of Top: Fizz.
Sourcefn transition(&mut self, target: T)
fn transition(&mut self, target: T)
Attempt to transition the StateMachine to the target state.
If the target state is already in the currently active state hierarchy, no
transition is made. To force re-entry of an active state, use
StateMachine::exact_transition.
Subject to interruption by short circuit transitions (from Substate::enter or Substate::exit)
and initial transitions (from Substate::init or TopState::init).
§Example
// where Bar is a substate of Top:
machine.transition(State::Bar);
assert!(matches!(machine.state(), State::Bar));
machine.transition(State::Top);
assert!(matches!(machine.state(), State::Bar));Sourcefn exact_transition(&mut self, target: T)
fn exact_transition(&mut self, target: T)
Attempt to transition the StateMachine to the target state regardless of currently
active states.
Makes the transition even if the target state is in the current active state hierarchy.
The state will be re-initialized; Substate::enter and Substate::init will be called.
Subject to interruption by short circuit transitions (from Substate::enter or Substate::exit)
and initial transitions (from Substate::init or TopState::init).
§Example
// where Bar is a substate of Top:
machine.transition(State::Bar);
assert!(matches!(machine.state(), State::Bar));
machine.transition(State::Top);
assert!(matches!(machine.state(), State::Bar));
machine.exact_transition(State::Top);
assert!(matches!(machine.state(), State::Top));Sourcefn state(&self) -> T
fn state(&self) -> T
Get the current state of the StateMachine.
Returns the deepest active state.
§Example
For some machine:
Top
└─ Foo
└─ Barmachine.transition(State::Bar);
assert!(matches!(machine.state(), State::Bar));Sourcefn state_matches(&self, state: T) -> bool
fn state_matches(&self, state: T) -> bool
Check if a given state matches the current state of this StateMachine or any active
superstate.
§Example
For some machine:
Top
├─ Foo
│ └─ Bar
└─ Fizzmachine.transition(State::Bar);
assert!(machine.state_matches(State::Top));
assert!(machine.state_matches(State::Foo));
assert!(machine.state_matches(State::Bar));
assert!(!machine.state_matches(State::Fizz));Sourcefn top_ref(&self) -> &V
fn top_ref(&self) -> &V
Get a reference to the top state.
§Example
// ...
pub struct Top {
pub foo: u8,
}
impl TopState for Top {}
// ...
dbg!(machine.top_ref().foo);Sourcefn top_mut(&mut self) -> &mut V
fn top_mut(&mut self) -> &mut V
Get a mutable reference to the top state.
§Example
// ...
pub struct Top {
pub foo: u8,
}
impl TopState for Top {}
// ...
machine.top_mut().foo = 8;Sourcefn name(&self) -> &str
fn name(&self) -> &str
Get the name of this state machine.
This name is used in moku log messages.
§Example
assert_eq!(machine.name(), "Example");Sourcefn set_name(&mut self, name: String)
Available on crate feature std only.
fn set_name(&mut self, name: String)
std only.Set the name of this state machine.
This name is used in moku log messages.
§Example
machine.set_name("Kikai".to_owned());
assert_eq!(machine.name(), "Kikai");Sourcefn handle_event(&mut self, event: &U)
fn handle_event(&mut self, event: &U)
Handle an event.
Starting with the deepest state, calls Substate::handle_event (or TopState::handle_event)
for each active state.
If a state returns Response::Next with Next::None, event handling will continue with its superstate.
If any state returns Response::Next with something other than Next::None,
the given transition will be completed and no further handle_event functions are called.
If any state returns Response::Drop, event handling stops immediately and no further
handle_event functions are called.
§Example
// ...
pub enum Event { A }
impl StateMachineEvent for Event {}
pub struct Top;
impl TopState for Top {}
// ...
machine.handle_event(&example::Event::A);Sourcefn state_list(&self) -> Vec<T>
Available on crate feature std only.
fn state_list(&self) -> Vec<T>
std only.