Contents | SCXML Wiki | Forum |
---|
How to split State Chart without using <invoke>
SCXML has an option to split state machine into sub state machines using <invoke> element. But in this case we need to provide data sharing between all parts. This procedure in some cases may be redundant or complex. And not all SCXML SDKs support such feature. But what to do if state chart becomes too large and difficult to read?
Let's take a look at QT pinball state chart example
We see that state global could be splitted into guiControl and internalState
Select state that you wish to make virtual, press right mouse button and select in the popup-menu Convert To->Virtual
This operation will create virtual state machine unit and move selected state machine logic to the new one
Save the unit with the corresponding name. We recommend to give prefix like include_ or virtual_ for better understanding of project unit roles.
Do the same procedures for other units you'd like to make virtual
Also save the new virtual unit and give the same prefix
After splitting you may reduce the width and height of virtual state chart shapes
Procedures for splitting virtual units are the same as procedures made for root state machine
After splitting virtual unit will be marked. And nested virtual state chart shapes will have a links to the corresponding virtual units.
Since ScxmlEditor 2.1.9 it is available to add onentry, onexit, datamodel and invoke either to virtual state or to referenced state on splitted chart
Set SCXML unit which will be as root
Choose layout that will be more suitable for you during debugging
After run all entered states will be highlighted
You may double click on virtual shape to switch to the its source unit
Since ScxmlEditor 2.5 there is an option to include state chart parts multiple times
Inspired by discussion how could we avoid invoke element in systems that do not support it:
Let's take a look at the next example:
The principle is based on the fact that we find repeated prefixes in the state identifiers or other scxml attributes such as data identifiers or values. According to scxml standard we can not use states with the same names in one scxml chart, so we will use Alias which is filled with value assigned in parent Virtual State.
- Convert
State_1
to Virtual State
- Replace state identifiers with Alias variable
%1
- Set Virtual State Alias
- Set Aliases to other virtual states
ScxmlEditor will perform substition of Alias variable %1
to Alias value which is set in Virtual State. So in target scxml file you will get different state identifiers
<state id="State_1" initial="Off_1">
...
<state id="State_2" initial="Off_2">
...
<state id="State_3" initial="Off_3">
...
<state id="State_4" initial="Off_4">
<onexit>
<cancel sendid="ID.Do.Timer"/>
</onexit>
<state id="Off_4">
<onentry>
<send delay="1s" event="Do.Timer" id="ID.Do.Timer"/>
<log expr=""OFF " .. 4" label="INFO"/>
</onentry>
<transition event="Do.Timer" target="On_4" type="external"/>
</state>
<state id="On_4">
<onentry>
<send delay="1s" event="Do.Timer" id="ID.Do.Timer"/>
<log expr=""ON " .. 4" label="INFO"/>
</onentry>
<transition event="Do.Timer" target="Off_4" type="external"/>
</state>
<transition event="Go.Next" target="State_3" type="external"/>
</state>
TOP | Contents | SCXML Wiki | Forum |
---|