korken89 / smlang-rs

A State Machine Language DSL procedual macro for Rust
Apache License 2.0
203 stars 29 forks source link

Feature: Hierarchical State Machines #31

Open dzimmanck opened 2 years ago

dzimmanck commented 2 years ago

I think that hierarchical state machines could be implemented quite elegantly with this framework by using state data which is simply another state machine. Right now, it would be on the user to handle the hierarchical event processing code, and to define and stitch together the state machines. I think first class support though would mean:

  1. Supporting hierarchical state definitions in the DSL syntax
  2. Auto-forwarding events to sub machines if we are in a hierarchical state.
  3. Generate nice looking hierarchical .dot files for graphviz.
korken89 commented 2 years ago

This would be an awesome extension!

dzimmanck commented 2 years ago

Some proposals for hierarchical syntax.

  1. Dot Notation:
statemachine! {
    transitions: {
        *Off + TurnOn = On.Continutous,
        On.Continuous + RunBurst = On.Burst.On,
        On.Burst.On + BurstOff = On.Burst.Off,
        On.Burst.Off + BurstOn = On.Burst.On,
        On.Burst + RunCont = On.Continuous,
        On + TurnOff = Off
    },
}

Advantages: -Very easy to parse -Explicit -Flexible. You can define a transition between any two states on any hierarchy. Nicely supports mass exits from any level. On.Burst + RunCont = On.Continuous is equivalent to On.Burst._ + RunCont = On.Continuous

Disadvantages: -Does not look very hierarchical

  1. Nested:
statemachine! {
    transitions: {
        *Off + TurnOn = On,
        On + TurnOff = Off,
        On {
            *Continuous + RunBurst = Burst,
            Burst + RunCont = Continuous,
            Burst {
                *On + BurstOff = Off,
                Off + BurstOn = On,
            },
        },
    },
}

Advantages: -Looks very hierarchical

Disadvantages: -Harder to parse -Limited. Does not allow complete freedom to transition between specific states in various hierarchies. For example, we could not have 2 different states above Burst that support transitions into different Burst starting states. We might be able to get around that by combining this with dot notation.

corecode commented 2 years ago

[Boost::ext].SML calls this composite state machines (I guess a term from UML): https://boost-ext.github.io/sml/examples.html#composite. They are defined as separate state machines and used as state in the parent state machine. Events bubble from leaves to trunk until they find a transition. Sub-state machines can optionally re-enter the most recent state they were in (history).

pleepleus commented 2 years ago

Thanks @corecode, I'll take a look at this and be consistent with the behavior as long as it makes sense for Rust environments.