pub trait Substate<Parent>: Sized {
type State: StateEnum;
type Event: StateMachineEvent;
type Context<'a>;
// Required method
fn enter(
_ctx: &mut Self::Context<'_>,
) -> impl Into<Entry<Self::State, Self>>;
// Provided methods
fn init(
&mut self,
_ctx: &mut Self::Context<'_>,
) -> impl Into<Next<Self::State>> { ... }
fn update(
&mut self,
_ctx: &mut Self::Context<'_>,
) -> impl Into<Next<Self::State>> { ... }
fn top_down_update(
&mut self,
_ctx: &mut Self::Context<'_>,
) -> impl Into<Next<Self::State>> { ... }
fn exit(self, _ctx: &mut Self::Context<'_>) -> impl Into<Next<Self::State>> { ... }
fn handle_event(
&mut self,
_ctx: &mut Self::Context<'_>,
event: &Self::Event,
) -> impl Into<Response<Self::State>> { ... }
}Expand description
A substate of a StateMachine.
Implement this trait for each non-top state in a state_machine module.
The generic parameter specifies the superstate (parent state).
§Example
#[moku::state_machine]
mod example {
#[moku::machine_module]
mod machine {}
use machine::State;
struct Top;
impl moku::TopState for Top {}
struct Foo;
impl moku::Substate<Top> for Foo {}
struct Bar;
impl moku::Substate<Foo> for Bar {}
}Required Associated Types§
Sourcetype State: StateEnum
type State: StateEnum
The state enum type. Auto-filled by the state_machine macro.
Sourcetype Event: StateMachineEvent
type Event: StateMachineEvent
The event type. Auto-filled by the state_machine macro.
Sourcetype Context<'a>
type Context<'a>
Context providing mutable access to all active superstates.
Auto-filled by the state_machine macro.
Required Methods§
Sourcefn enter(_ctx: &mut Self::Context<'_>) -> impl Into<Entry<Self::State, Self>>
fn enter(_ctx: &mut Self::Context<'_>) -> impl Into<Entry<Self::State, Self>>
Called when a StateMachine enters this state.
Serves as a constructor for the state. If the state type is defined within the
state_machine module and has no fields, this method will be autogenerated.
This method is only called when the state becomes active, and is not called upon re-entrant transitions (if this state is already active).
Returning a value of Entry::Target(T) will result in a “short circuit”
transition that will be completed by the StateMachine.
§Example
// ...
pub struct Foo {
bar: u8,
}
impl Substate<Top> for Foo {
fn enter(
ctx: &mut Self::Context<'_>,
) -> impl Into<Entry<Self::State, Self>> {
Self { bar: 8 }
}
}
// ...Provided Methods§
Sourcefn init(&mut self, _ctx: &mut Self::Context<'_>) -> impl Into<Next<Self::State>>
fn init(&mut self, _ctx: &mut Self::Context<'_>) -> impl Into<Next<Self::State>>
Called when a StateMachine transitions directly to this state.
This method can return a target state representing the initial transition to take upon entry of this state. It is called only when the state machine transitions directly to this state, meaning that it will not be called when transitioning with a target state that is a substate of this state.
This method is called upon re-entrant transitions (if this state is already active).
Returning a value of Next::None results in the StateMachine remaining in this state after
transition.
§Example
// ...
impl Substate<Top> for Foo {
fn init(
&mut self,
ctx: &mut Self::Context<'_>,
) -> impl Into<Next<Self::State>> {
State::Bar
}
}
// ...Sourcefn update(
&mut self,
_ctx: &mut Self::Context<'_>,
) -> impl Into<Next<Self::State>>
fn update( &mut self, _ctx: &mut Self::Context<'_>, ) -> impl Into<Next<Self::State>>
Called when StateMachine::update is called.
This method may return a target state to transition to as a result of updating.
§Example
// ...
impl Substate<Top> for Foo {
fn update(
&mut self,
ctx: &mut Self::Context<'_>,
) -> impl Into<Next<Self::State>> {
State::Bar
}
}
// ...Sourcefn top_down_update(
&mut self,
_ctx: &mut Self::Context<'_>,
) -> impl Into<Next<Self::State>>
fn top_down_update( &mut self, _ctx: &mut Self::Context<'_>, ) -> impl Into<Next<Self::State>>
Called when StateMachine::top_down_update is called.
This method may return a target state to transition to as a result of updating.
§Example
// ...
impl Substate<Top> for Foo {
fn top_down_update(
&mut self,
ctx: &mut Self::Context<'_>,
) -> impl Into<Next<Self::State>> {
State::Bar
}
}
// ...Sourcefn exit(self, _ctx: &mut Self::Context<'_>) -> impl Into<Next<Self::State>>
fn exit(self, _ctx: &mut Self::Context<'_>) -> impl Into<Next<Self::State>>
Called when a StateMachine exits this state.
The state is consumed by this call.
This method may return a target state to “short circuit” transition to as a result of exiting this state.
§Example
// ...
impl Substate<Top> for Foo {
fn exit(
self,
ctx: &mut Self::Context<'_>,
) -> impl Into<Next<Self::State>> {
State::Bar
}
}
// ...Sourcefn handle_event(
&mut self,
_ctx: &mut Self::Context<'_>,
event: &Self::Event,
) -> impl Into<Response<Self::State>>
fn handle_event( &mut self, _ctx: &mut Self::Context<'_>, event: &Self::Event, ) -> impl Into<Response<Self::State>>
Called when StateMachine::handle_event is called.
Return Response::Next with Next::None to continue event handling with the superstate.
Return Response::Next with something other than Next::None
to transition to the given state, after which event handling is stopped.
Return Response::Drop to immediately stop event handling.
§Example
// ...
pub struct Foo;
impl Substate<Top> for Foo {
fn handle_event(
&mut self,
_ctx: &mut Self::Context<'_>,
event: &Self::Event,
) -> impl Into<Response<Self::State>> {
match event {
Event::A => Response::Next(Next::None),
Event::B => Response::Drop,
Event::C => Response::Next(Next::Target(State::Bar)),
}
}
}
// ...Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.