Closed zamazan4ik closed 1 year ago
Hi, thanks for taking a look at statig
. I did my best to do create somewhat of a comparison between statig
and HSM. There are a couple of points that could probably use a more in-depth exploration but I haven't personally used HSM, so I'm hesitant to go into great detail for now. I do want to state that it isn't the goal of statig
to implement the full UML spec for state machines. My main inspiration was the work of Miro Samek and the state machines as implemented in the Quantum Framework library. In his book Pracical UML Statecharts in C/C++ he goes into great detail on why he chose to implement certain features but also why he dismissed others, and generally I agree with his conclusions. But anyway, here is a rough comparison of statig
with HSM.
[x] External transition
[ ] Anonymous transition (Completion)
These are not supported by statig
as I feel the added complexity isn't worth it. (But I could be wrong so if you disagree I'm happy to discuss potential use cases).
[x] Internal transition
[ ] Direct transition Not supported as I feel they somewhat break the semantics of hierarchical state machines by not executing entry or exit actions when transitioning.
[x] Guards / actions
In statig
guards are expressed as native Rust code.
#[state]
fn on(event: &Event) -> Response<State> {
match event {
Event::TimerElapsed { timer_id } if *timer_id == 10 => Transition(State::off()),
Event::ButtonPressed => Handled,
_ => Super
}
}
[x] Entry / exit actions
[ ] Orthogonal regions
Not supported and I honestly can't imagine how they would work within statig
.
[x] Hierarchies / sub state machines
[x] Event defering
[x] Transition logging
Yes with the on_transition
and on_dispatch
methods.
[x] Initial pseudo state
[ ] History pseudo state Not directly supported but you can quite easily add the functionality yourself:
impl StateMachine for Dishwasher {
// Omitted ...
// On every transition we update the previous state, so we can
// transition back to it.
fn on_transition(&mut self, source: &Self::State, _: &Self::State) {
self.previous_state = source.clone();
}
}
And then you can just do:
#[state]
fn door_opened(&mut self, event: &Event) -> Response<State> {
match event {
// When the door is closed again, the program is resumed from
// the previous state.
Event::DoorClosed => Transition(self.previous_state.clone()),
_ => Super,
}
}
[ ] Entry / exit pseudo state Not supported for similar reasons as for anonymous transitions. More generally I don't think you should be able to redirect a transition as it makes the state machine harder to reason about.
[x] State data members
[x] Unexpected event / no transition handler
[x] Dependency injection You can make your event type a composite of any dependency you want to pass together with the actual event.
[ ] Custom target state construction Not yet, but it's on my to-do list.
[x] Chain actions Actions are just native Rust code so you can orchestrate function calls as you wish.
Feel free to respond with your thoughts. I'm curious to hear if there any things you'd miss from HSM.
Hi! Thanks for the library.
I have some experience with Hierarchial State Machines in C++ world. I've used HSM library: https://github.com/erikzenker/hsm
Could you please compare
statig
to the HSM? E.g. which feature from HSM are already supported in statig. I hope HSM would be for you at least a good roadmap :)Thanks in advance!