Examples - igor-krechetov/hsmcpp Wiki

Referencing states defined in an external file

When defining your HSM structure you might want to reuse a state or a group of states for some common logic (for example error handling). Included file must comply with SCXML format and have a root node <scxml> defined.

There are two ways to include another file inside of your scxml:

Include using <xi:include>

This is a standard way which is compliant with W3 specification. For this tag to work additional namespace must be added to your scxml:

xmlns:xi="http://www.w3.org/2001/XInclude"

Restrictions and things to consider:

Using <xi:include> with a wrapper state

xi_include_wrapped.scxml

<scxml initial="State0" version="1.0" xmlns="http://www.w3.org/2005/07/scxml" xmlns:xi="http://www.w3.org/2001/XInclude">
    <state id="State0">
        <transition event="EVENT_1" target="ImportedState"></transition>
    </state>
    <state id="ImportedState">
        <transition event="EVENT_2" target="State2"></transition>
        <xi:include href="./substates1.scxml" parse="xml"></xi:include>
    </state>
    <state id="State2"></state>
</scxml>

substates1.scxml

<scxml initial="state_a" version="1.0" xmlns="http://www.w3.org/2005/07/scxml">
    <state id="state_a">
        <transition event="EVENT_B" target="state_b"></transition>
    </state>
    <state id="state_b">
        <transition event="EVENT_C" target="state_c"></transition>
    </state>
    <state id="state_c">
        <transition event="EVENT_B" target="state_b"></transition>
    </state>
</scxml>

Result structure wiki_examples_xiinclude_wrapped

Including <xi:include> directly

NOTE: SCXML files were edited manually xi_include_direct.scxml

<scxml initial="State0" version="1.0" xmlns="http://www.w3.org/2005/07/scxml" xmlns:xi="http://www.w3.org/2001/XInclude">
    <state id="State0">
        <transition event="EVENT_1" target="State1"></transition>
    </state>
    <xi:include href="state1.scxml" parse="xml"></xi:include>
    <state id="State2"></state>
</scxml>

Note how we define a transition to State1 even though it's not defined in xi_include_direct.scxml. Transition will become valid after code from state1.scxml will be included.

<transition event="EVENT_1" target="State1"></transition>

state1.scxml

<scxml version="1.0" xmlns="http://www.w3.org/2005/07/scxml">
    <state id="State1">
        <onentry>
            <script>onEnteringState1</script>
        </onentry>
        <onexit>
            <script>onExitingState1</script>
        </onexit>
        <transition event="SELF_TRANSITION"></transition>
        <transition event="EVENT_2" target="State2"></transition>
        <invoke srcexpr="onState1"></invoke>
    </state>
</scxml>

Note how we define a transition to State2 even though it's not defined in state1.scxml:

<transition event="EVENT_2" target="State2"></transition>

Result structure wiki_examples_xiinclude_direct

Include using "src" attribute of <state>

It's possible to reference external scxml files by using "src" attribute of a <state>.

<state id="..." src="file path">
    ...
</state>

This will behave exactly same as a <xi:include> tag wrapped inside a <state>.

Keep in mind that this is not a part of W3 SCXML specification and was added only because it's supported by scxmlgui.

<scxml initial="State0" version="1.0" xmlns="http://www.w3.org/2005/07/scxml">
    <state id="State0">
        <transition event="EVENT_1" target="Substates1"></transition>
    </state>
    <state id="State2"></state>
    <state id="Substates1" src="./substates1.scxml">
        <transition event="EVENT_2" target="State2"></transition>
    </state>
</scxml>

Result structure

wiki_examples_state_src_include