Contents | SCXML Wiki | Forum |
---|
How to debug SCXML statecharts
ScxmlEditor has an ability to execute SCXML statecharts via testing applications or to listen external UDP commands such as state enter or exit, etc.
ScxmlEditor starts a testing application, intercepts its command line output and may communicate in two modes:
- UDP mode (receives UDP commands and sends events as UDP packages to testing application)
- Pipes mode (since version 2.1.8) (capture enter-exit events from console output by regexp, and submit trigger event to state machine to console input)
There are two ready-to-use testing applications:
-
Based on USCXML framework. Supports null, lua, ecmascript(since 2.1.5.1507) datamodels
-
QtScxmlTester - based on Qt SCXML framework Supports null, ecmascript datamodels
Also you may write your own testing application using the corresponding API
@@@
- clear highlighted states in all statecharts@@@ScxmlName@Id
- clear highlighted states in statechart where <scxml> 'name' is equalScxmlName
andId
is the identifier of the invoked state machine when message comes from invoked session.ScxmlName
orId
can be empty. In this case state chart will be cleared either byScxmlName
orId
Type@ScxmlName@Msg@Id
- command to highlight state or display message in CallStack panel Description:
Type
- integer type of command:1 - AfterEnter, 2 - BeforeEnter, 3 - AfterExit, 4 - BeforeExit, 5 - Step, 6 - BeforeExecContent, 7 - AfterExecContent, 8 - BeforeInvoke, 9 - AfterInvoke, 10 - BeforeUnInvoke, 11 - AfterUnInvoke, 12 - BeforeTakingTransition, 13 - AfterTakingTransition, 14 - StableConfiguration, 15 - BeforeProcessingEvent
ScxmlName
- name of <scxml>Msg
- message which depends on type of command. For example: for BeforeEnter or BeforeExit - it is the id(name) of states, for BeforeInvoke or BeforeUnInvoke it is the name of invoked element, etc.Id
- identifier of the invoked state machine (Since ScxmlEditor 2.2). Can be empty for root machines
BeforeEnter graphically highlight and BeforeExit unhighlight the corresponding states, other commands are displayed in CallStack panel
Since ScxmlEditor 2.3 there is an option to highlight taking transitions in BeforeTakingTransition Message format:
FromState|TransitionIndex
whereTransitionIndex
is transition xml child index
2@CalculatorStateMachine@operand1
- highlight state operand1 in statechart CalculatorStateMachine4@CalculatorStateMachine@operand1
- unhighlight state operand1 in statechart CalculatorStateMachine2@ScxmlSub1@isSub1@ID_SUB_1
- highlight state isSub1 in statechart ScxmlSub1 when invoke Id is ID_SUB_112@CalculatorStateMachine@operand1|0
- highlight the first transition from operand1 state in statechart CalculatorStateMachine
You can also trace the execution of the chart and use breakpoints.
It is similar to SCXML send events logic
%EVENT_NAME%
- valid event name%PARAM_NAME%
- valid param name%DATA_TYPE%
-0-Default
(Variant type),1-Bool
,2-Integer
,3-Double
,4-String
Since ScxmlEditor 2.3 there were added5-Json
,6-UserData
. Json is converted to QVariant in QScxmlTester. User data may be used in custom testing applications.%CONTENT_DATA%
,%PARAM_DATA%
- event data depending on%DATA_TYPE%
<EVENT name="%EVENT_NAME%" >
<content type="%DATA_TYPE%" >
%CONTENT_DATA%
</content>
</EVENT>
<EVENT name="%EVENT_NAME%" >
<param name="%PARAM_NAME%" type="%DATA_TYPE%" expr="%PARAM_DATA%">
<param name="%PARAM_NAME%" type="%DATA_TYPE%" expr="%PARAM_DATA%">
</EVENT>
Triggers are used to submit events to the state machine
For simple events you can double click (or click depending on settings) on event name to trigger an event
Triggers will create a GUI elements for passing data to statechart
If you need to pass nested event.data
like event.data.val
there is a menu Params in inspector
DEMO. In runtime params will be represented as edits with buttons
You can associate breakpoints with states. When the state with breakpoint set is entered, state machine events queue is interrupted and program highlights the breakpoint and changes the scxml root element background into light yellow colour.
- select shape
- set 'Breakpoint' menu option checked
In trace mode state machine event queue is interrupted and waits for user 'Next Step' button is clicked.
This mode is activated when:
- breakpoint is triggered
- pause button is pressed
Let's take a look at the example when state machine invokes two same nested state machines
If invoke identifier of submachine is not set then the first identifier is used
- Select SCXML element
- Call IDE Insight 'InvokeID'
- Type new id
In this mode ScxmlEditor only listens UDP commands for highlighting states and displaying messages in CallStack panel
It was an old dream to monitor state machine workflow without any external dependencies in Qt and finally it comes true. We prepared some native SCXML SVG monitors:
- scxmlsvgview.h - for widgets (based on QGraphicsView)
- see how to use it in Dining Philosophers Example
- scxmlsvgqmlitem.h - for QML (based on QQuickPaintedItem)
- see how to use it in Stopwatch Example
Since ScxmlEditor 2.2.1 you can export SCXML to SVG, include only monitor headers in your app and create monitor instances any time.
NOTICE: While state machine pointer is not set, the monitor does nothing and can be left in Release.
For Qt SCXML applications you may include scxmlexternmonitor2.h header to your project and follow the instructions
- Select Run->Start listening from external application
- Select Run->Run
- Launch Calculator-QML.exe
- Use Pause for tracing (optionally)
If you need to pass event or custom data to CallStack view, you can override monitor class.
class MyMonitor: public Scxmlmonitor::UDPScxmlExternMonitor {
public:
inline explicit MyMonitor(QObject *parent = nullptr): Scxmlmonitor::UDPScxmlExternMonitor(parent) {}
protected:
inline virtual void processEventMessage(QScxmlStateMachine *machine, const QString &id, const QScxmlEvent &event) {
const QString sEventData = event.data().toString();
processMonitorMessage(machine->name(),
id,
sEventData.isEmpty() ? event.name() : (event.name() + ": [" + sEventData + "]"),
Scxmlmonitor::smttBeforeTakingTransition);
// ---> example: add custom info to all events, that starts with 'in.'
if (event.name().startsWith("in.")) {
processMonitorMessage(machine->name(),
id,
"my custom data: " + sEventData,
Scxmlmonitor::smttBeforeProcessingEvent);
}
}
};
You should enable custom data types in ScxmlEditor settings if you want to receive it in CallStack View
Since version 2.1.8 there is an option to communicate with testing applications via pipes.
Example: how to setup The SCION command-line tool as custom testing application
- install SCION CLI by command
npm install -g @scion-scxml/cli
- after installation check c:\Users\USER_NAME\AppData\Roaming\npm\node_modules@scion-scxml\cli\bin\cli.js is to be the latest from the corresponding gitlab repo
- run any test scxml file in CMD to check that SCION CLI is working without errors
- open
Settings->TestApplicationPresets
and check that it is properly adjusted according to the image below
If API is changed in the future you may edit regular expressions to capture enter-exit events properly
- select SCION CLI in application run presets
- if everything is set properly you will see callstack messages and state machine will flow from state to state
TOP | Contents | SCXML Wiki | Forum |
---|