diff --git a/README.md b/README.md index 3eb87a0..167c6de 100644 --- a/README.md +++ b/README.md @@ -266,6 +266,12 @@ The statemachine will create for all states an `on_entry_` and `on_exit_` functi If the are not used, they will be optimized away by the compiler. An example be found in `on_entry_on_exit_generic`. +### Transition callback + +The statemachine will call for every transition a transition callback. This function +is called with both the old state and new state as arguments. An example can be found +in `transition_callback`. + ## Helpers ### Auto-derive certain traits for states and events diff --git a/macros/src/codegen.rs b/macros/src/codegen.rs index 6664a8b..dfef05b 100644 --- a/macros/src/codegen.rs +++ b/macros/src/codegen.rs @@ -490,8 +490,10 @@ pub fn generate_code(sm: &ParsedStateMachine) -> proc_macro2::TokenStream { if guard_result.map_err(#error_type_name::GuardFailed)? { #action_code let out_state = #states_type_name::#out_state; + let in_state = #states_type_name::#in_state; self.context.log_state_change(&out_state); #entry_exit_states + self.context().transition_callback(&in_state, &out_state); self.state = Some(out_state); return self.state() } @@ -500,8 +502,10 @@ pub fn generate_code(sm: &ParsedStateMachine) -> proc_macro2::TokenStream { quote!{ #action_code let out_state = #states_type_name::#out_state; + let in_state = #states_type_name::#in_state; self.context.log_state_change(&out_state); #entry_exit_states + self.context().transition_callback(&in_state, &out_state); self.state = Some(out_state); return self.state(); } @@ -609,6 +613,11 @@ pub fn generate_code(sm: &ParsedStateMachine) -> proc_macro2::TokenStream { /// `process_event()`. No-op by default but can be overridden in implementations /// of a state machine's `StateMachineContext` trait. fn log_state_change(&self, new_state: & #states_type_name) {} + + /// Called when transitioning to a new state as a result of an event passed to + /// `process_event()`. No-op by default but can be overridden in implementations + /// of a state machine's `StateMachineContext` trait. + fn transition_callback(&self, old_state: & #states_type_name, new_state: & #states_type_name) {} } /// List of auto-generated states. diff --git a/macros/src/parser/state_machine.rs b/macros/src/parser/state_machine.rs index 85f4402..e44dc13 100644 --- a/macros/src/parser/state_machine.rs +++ b/macros/src/parser/state_machine.rs @@ -142,12 +142,12 @@ impl parse::Parse for StateMachine { return Err(parse::Error::new( input.span(), format!( - "Unknown keyword {}. Support keywords: [\"name\", \ - \"transitions\", \ - \"temporary_context\", \ - \"custom_guard_error\", \ - \"derive_states\", \ - \"derive_events\" + "Unknown keyword {}. Support keywords: [\"name\", + \"transitions\", + \"temporary_context\", + \"custom_guard_error\", + \"derive_states\", + \"derive_events\", ]", keyword ),