Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

After dispatch hook #23

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion examples/macro/async_blinky/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ pub enum Event {
// Set the `on_transition` callback.
on_transition = "Self::on_transition",
// Set the `on_dispatch` callback.
on_dispatch = "Self::on_dispatch"
on_dispatch = "Self::on_dispatch",
// Set the `on_dispatch` callback.
after_dispatch = "Self::after_dispatch"
)]
impl Blinky {
#[action]
Expand Down Expand Up @@ -86,6 +88,10 @@ impl Blinky {
fn on_dispatch(&mut self, state: StateOrSuperstate<Self>, event: &Event) {
println!("dispatching `{event:?}` to `{state:?}`");
}

fn after_dispatch(&mut self, state: StateOrSuperstate<Self>, event: &Event) {
println!("dispatched `{event:?}` to `{state:?}`");
}
}

#[tokio::main]
Expand Down
13 changes: 13 additions & 0 deletions macro/src/analyze.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ pub struct StateMachine {
pub on_transition: Option<Path>,
/// Optional `on_dispatch` callback.
pub on_dispatch: Option<Path>,
/// Optional `after_dispatch` callback.
pub after_dispatch: Option<Path>,
}

/// Information regarding a state.
Expand Down Expand Up @@ -181,6 +183,7 @@ pub fn analyze_state_machine(attribute_args: &AttributeArgs, item_impl: &ItemImp

let mut on_transition = None;
let mut on_dispatch = None;
let mut after_dispatch = None;

let mut visibility = parse_quote!(pub);
let mut event_ident = parse_quote!(event);
Expand Down Expand Up @@ -232,6 +235,14 @@ pub fn analyze_state_machine(attribute_args: &AttributeArgs, item_impl: &ItemImp
_ => abort!(name_value, "must be a string literal"),
}
}
NestedMeta::Meta(Meta::NameValue(name_value))
if name_value.path.is_ident("after_dispatch") =>
{
after_dispatch = match &name_value.lit {
Lit::Str(input_pat) => Some(input_pat.parse().unwrap()),
_ => abort!(name_value, "must be a string literal"),
}
}
NestedMeta::Meta(Meta::NameValue(name_value))
if name_value.path.is_ident("visibility") =>
{
Expand Down Expand Up @@ -340,6 +351,7 @@ pub fn analyze_state_machine(attribute_args: &AttributeArgs, item_impl: &ItemImp
superstate_ident,
superstate_derives,
on_dispatch,
after_dispatch,
on_transition,
event_ident,
context_ident,
Expand Down Expand Up @@ -661,6 +673,7 @@ fn valid_state_analyze() {
superstate_derives,
on_transition,
on_dispatch,
after_dispatch,
event_ident,
context_ident,
visibility,
Expand Down
7 changes: 7 additions & 0 deletions macro/src/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,12 @@ fn codegen_state_machine_impl(ir: &Ir) -> ItemImpl {
const ON_DISPATCH: fn(&mut Self, StateOrSuperstate<'_, '_, Self>, &Self::Event<'_>) = #on_dispatch;
),
};
let after_dispatch = match &ir.state_machine.after_dispatch {
None => quote!(),
Some(after_dispatch) => quote!(
const AFTER_DISPATCH: fn(&mut Self, StateOrSuperstate<'_, '_, Self>, &Self::Event<'_>) = #after_dispatch;
),
};

parse_quote!(
impl #impl_generics statig::#mode::IntoStateMachine for #shared_storage_type #where_clause
Expand All @@ -85,6 +91,7 @@ fn codegen_state_machine_impl(ir: &Ir) -> ItemImpl {
#on_transition

#on_dispatch
#after_dispatch
}
)
}
Expand Down
6 changes: 6 additions & 0 deletions macro/src/lower.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ pub struct StateMachine {
pub on_transition: Option<Path>,
/// The path of the `on_dispatch` callback.
pub on_dispatch: Option<Path>,
/// The path of the `after_dispatch` callback.
pub after_dispatch: Option<Path>,
/// The visibility for the derived types,
pub visibility: Visibility,
/// The external input pattern.
Expand Down Expand Up @@ -138,6 +140,7 @@ pub fn lower(model: &Model) -> Ir {
let superstate_ident = model.state_machine.superstate_ident.clone();
let on_transition = model.state_machine.on_transition.clone();
let on_dispatch = model.state_machine.on_dispatch.clone();
let after_dispatch = model.state_machine.after_dispatch.clone();
let event_ident = model.state_machine.event_ident.clone();
let context_ident = model.state_machine.context_ident.clone();
let shared_storage_type = model.state_machine.shared_storage_type.clone();
Expand Down Expand Up @@ -422,6 +425,7 @@ pub fn lower(model: &Model) -> Ir {
superstate_generics,
on_transition,
on_dispatch,
after_dispatch,
visibility,
event_ident,
context_ident,
Expand Down Expand Up @@ -709,6 +713,7 @@ fn create_analyze_state_machine() -> analyze::StateMachine {
superstate_derives: vec![parse_quote!(Copy), parse_quote!(Clone)],
on_transition: None,
on_dispatch: None,
after_dispatch: None,
visibility: parse_quote!(pub),
event_ident: parse_quote!(input),
context_ident: parse_quote!(context),
Expand All @@ -734,6 +739,7 @@ fn create_lower_state_machine() -> StateMachine {
superstate_generics,
on_transition: None,
on_dispatch: None,
after_dispatch: None,
visibility: parse_quote!(pub),
event_ident: parse_quote!(input),
context_ident: parse_quote!(context),
Expand Down
12 changes: 11 additions & 1 deletion statig/src/awaitable/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ where

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

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

match response {
Response::Handled => Response::Handled,
Response::Super => match self.superstate() {
Expand All @@ -125,7 +127,15 @@ where
event,
);

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

M::AFTER_DISPATCH(
shared_storage,
StateOrSuperstate::Superstate(&superstate),
event,
);

response
}
None => Response::Super,
},
Expand Down
10 changes: 9 additions & 1 deletion statig/src/awaitable/superstate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,15 @@ where
event,
);

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

M::AFTER_DISPATCH(
shared_storage,
StateOrSuperstate::Superstate(&superstate),
event,
);

response
}
None => Response::Super,
},
Expand Down
12 changes: 11 additions & 1 deletion statig/src/blocking/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ where

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

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

match response {
Response::Handled => Response::Handled,
Response::Super => match self.superstate() {
Expand All @@ -110,7 +112,15 @@ where
event,
);

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

M::AFTER_DISPATCH(
shared_storage,
StateOrSuperstate::Superstate(&superstate),
event,
);

response
}
None => Response::Super,
},
Expand Down
10 changes: 9 additions & 1 deletion statig/src/blocking/superstate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,15 @@ where
event,
);

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

M::AFTER_DISPATCH(
shared_storage,
StateOrSuperstate::Superstate(&superstate),
event,
);

response
}
None => Response::Super,
},
Expand Down
5 changes: 5 additions & 0 deletions statig/src/into_state_machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ where
const ON_DISPATCH: fn(&mut Self, StateOrSuperstate<'_, '_, Self>, &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>, &Self::Event<'_>) =
|_, _, _| {};

/// Method that is called *after* every transition.
const ON_TRANSITION: fn(&mut Self, &Self::State, &Self::State) = |_, _, _| {};
}
5 changes: 5 additions & 0 deletions statig/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,7 @@
//! points during state machine execution.
//!
//! - `on_dispatch` is called before an event is dispatched to a specific state or superstate.
//! - `after_dispatch` is called after an event is dispatched to a specific state or superstate.
//! - `on_transition` is called after a transition has occurred.
//!
//! ```
Expand All @@ -395,6 +396,7 @@
//! #[state_machine(
//! initial = "State::on()",
//! on_dispatch = "Self::on_dispatch",
//! after_dispatch = "Self::after_dispatch",
//! on_transition = "Self::on_transition",
//! state(derive(Debug)),
//! superstate(derive(Debug))
Expand All @@ -412,6 +414,9 @@
//! fn on_dispatch(&mut self, state: StateOrSuperstate<Blinky>, event: &Event) {
//! println!("dispatched `{:?}` to `{:?}`", event, state);
//! }
//! fn after_dispatch(&mut self, state: StateOrSuperstate<Blinky>, event: &Event) {
//! println!("dispatched `{:?}` to `{:?}`", event, state);
//! }
//! }
//! ```
//!
Expand Down