Skip to content

Commit

Permalink
Make state machine hooks functions instead of function pointers
Browse files Browse the repository at this point in the history
  • Loading branch information
mdeloof committed Jan 8, 2025
1 parent 17e52c2 commit 5dcf0b0
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 37 deletions.
4 changes: 2 additions & 2 deletions examples/no_macro/basic/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ impl IntoStateMachine for Blinky {
}

/// This method is called on every transition of the state machine.
const AFTER_TRANSITION: fn(&mut Self, &Self::State, &Self::State) = |_, source, target| {
fn after_transition(&mut self, source: &Self::State, target: &Self::State) {
println!("transitioned from {source:?} to {target:?}");
};
}
}

impl blocking::State<Blinky> for State {
Expand Down
6 changes: 3 additions & 3 deletions examples/no_macro/history/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ impl IntoStateMachine for Dishwasher {

// On every transition we update the previous state, so we can
// transition back to it.
const AFTER_TRANSITION: fn(&mut Self, &Self::State, &Self::State) = |shared, source, target| {
shared.previous_state = source.clone();
};
fn after_transition(&mut self, source: &Self::State, _target: &Self::State) {
self.previous_state = source.clone();
}
}

impl blocking::State<Dishwasher> for State {
Expand Down
40 changes: 28 additions & 12 deletions macro/src/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,13 @@ fn codegen_state_machine_impl(ir: &Ir) -> ItemImpl {
None => quote!(),
Some(before_dispatch) => match ir.state_machine.mode {
Mode::Blocking => quote!(
const BEFORE_DISPATCH: fn(
&mut Self,
StateOrSuperstate<'_, Self::State, Self::Superstate<'_>>,
&Self::Event<'_>,
) = #before_dispatch;
fn before_dispatch(
&mut self,
state_or_superstate: StateOrSuperstate<'_, Self::State, Self::Superstate<'_>>,
event: &Self::Event<'_>,
) {
#before_dispatch;
}
),
Mode::Awaitable => quote!(
fn before_dispatch(
Expand All @@ -83,11 +85,13 @@ fn codegen_state_machine_impl(ir: &Ir) -> ItemImpl {
None => quote!(),
Some(after_dispatch) => match ir.state_machine.mode {
Mode::Blocking => quote!(
const AFTER_DISPATCH: fn(
&mut Self,
StateOrSuperstate<'_, Self::State, Self::Superstate<'_>>,
&Self::Event<'_>,
) = #after_dispatch;
fn after_dispatch(
&mut self,
state_or_superstate: StateOrSuperstate<'_, Self::State, Self::Superstate<'_>>,
event: &Self::Event<'_>,
) {
#after_dispatch;
}
),
Mode::Awaitable => quote!(
fn after_dispatch(
Expand All @@ -105,7 +109,13 @@ fn codegen_state_machine_impl(ir: &Ir) -> ItemImpl {
None => quote!(),
Some(before_transition) => match ir.state_machine.mode {
Mode::Blocking => quote!(
const BEFORE_TRANSITION: fn(&mut Self, &Self::State, &Self::State) = #before_transition;
fn before_transition(
&mut self,
source: &Self::State,
target: &Self::State,
) {
#before_transition;
}
),
Mode::Awaitable => quote!(
fn before_transition(
Expand All @@ -123,7 +133,13 @@ fn codegen_state_machine_impl(ir: &Ir) -> ItemImpl {
None => quote!(),
Some(after_transition) => match ir.state_machine.mode {
Mode::Blocking => quote!(
const AFTER_TRANSITION: fn(&mut Self, &Self::State, &Self::State) = #after_transition;
fn after_transition(
&mut self,
source: &Self::State,
target: &Self::State,
) {
#after_transition;
}
),
Mode::Awaitable => quote!(
fn after_transition(
Expand Down
5 changes: 3 additions & 2 deletions statig/src/blocking/inner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ where

/// Transition from the current state to the given target state.
pub fn transition(&mut self, mut target: M::State, context: &mut M::Context<'_>) {
M::BEFORE_TRANSITION(&mut self.shared_storage, &target, &self.state);
M::before_transition(&mut self.shared_storage, &target, &self.state);

// Get the transition path we need to perform from one state to the next.
let (exit_levels, enter_levels) = self.state.transition_path(&mut target);

Expand All @@ -50,7 +51,7 @@ where
self.state
.enter(&mut self.shared_storage, context, enter_levels);

M::AFTER_TRANSITION(&mut self.shared_storage, &target, &self.state);
M::after_transition(&mut self.shared_storage, &target, &self.state);
}
}

Expand Down
26 changes: 14 additions & 12 deletions statig/src/blocking/into_state_machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,23 +24,25 @@ where

/// Method that is called *before* an event is dispatched to a state or
/// superstate handler.
const BEFORE_DISPATCH: fn(
&mut Self,
StateOrSuperstate<'_, Self::State, Self::Superstate<'_>>,
&Self::Event<'_>,
) = |_, _, _| {};
fn before_dispatch(
&mut self,
_state_or_superstate: StateOrSuperstate<'_, Self::State, Self::Superstate<'_>>,
_event: &Self::Event<'_>,
) {
}

/// Method that is called *after* an event is dispatched to a state or
/// superstate handler.
const AFTER_DISPATCH: fn(
&mut Self,
StateOrSuperstate<'_, Self::State, Self::Superstate<'_>>,
&Self::Event<'_>,
) = |_, _, _| {};
fn after_dispatch(
&mut self,
_state_or_superstate: StateOrSuperstate<'_, Self::State, Self::Superstate<'_>>,
_event: &Self::Event<'_>,
) {
}

/// Method that is called *before* every transition.
const BEFORE_TRANSITION: fn(&mut Self, &Self::State, &Self::State) = |_, _, _| {};
fn before_transition(&mut self, _source: &Self::State, _target: &Self::State) {}

/// Method that is called *after* every transition.
const AFTER_TRANSITION: fn(&mut Self, &Self::State, &Self::State) = |_, _, _| {};
fn after_transition(&mut self, _source: &Self::State, _target: &Self::State) {}
}
8 changes: 4 additions & 4 deletions statig/src/blocking/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,25 +93,25 @@ where
where
Self: Sized,
{
M::BEFORE_DISPATCH(shared_storage, StateOrSuperstate::State(self), event);
M::before_dispatch(shared_storage, StateOrSuperstate::State(self), event);

let response = self.call_handler(shared_storage, event, context);

M::AFTER_DISPATCH(shared_storage, StateOrSuperstate::State(self), event);
M::after_dispatch(shared_storage, StateOrSuperstate::State(self), event);

match response {
Response::Handled => Response::Handled,
Response::Super => match self.superstate() {
Some(mut superstate) => {
M::BEFORE_DISPATCH(
M::before_dispatch(
shared_storage,
StateOrSuperstate::Superstate(&superstate),
event,
);

let response = superstate.handle(shared_storage, event, context);

M::AFTER_DISPATCH(
M::after_dispatch(
shared_storage,
StateOrSuperstate::Superstate(&superstate),
event,
Expand Down
4 changes: 2 additions & 2 deletions statig/src/blocking/superstate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,15 +102,15 @@ where
Response::Handled => Response::Handled,
Response::Super => match self.superstate() {
Some(mut superstate) => {
M::BEFORE_DISPATCH(
M::before_dispatch(
shared_storage,
StateOrSuperstate::Superstate(&superstate),
event,
);

let response = superstate.handle(shared_storage, event, context);

M::AFTER_DISPATCH(
M::after_dispatch(
shared_storage,
StateOrSuperstate::Superstate(&superstate),
event,
Expand Down

0 comments on commit 5dcf0b0

Please sign in to comment.