summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--examples/scxml/mediaplayer-qml-cppdatamodel/thedatamodel.cpp3
-rw-r--r--examples/scxml/mediaplayer-qml-cppdatamodel/thedatamodel.h1
-rw-r--r--examples/scxml/pinball/doc/src/pinball.qdoc77
-rw-r--r--examples/scxml/pinball/mainwindow.cpp13
-rw-r--r--examples/scxml/pinball/mainwindow.h3
-rw-r--r--examples/scxml/pinball/pinball.scxml44
-rw-r--r--src/scxml/doc/qtscxml-index.qdoc16
-rw-r--r--src/scxml/qscxmlcppdatamodel.cpp8
-rw-r--r--src/scxml/qscxmlcppdatamodel.h8
-rw-r--r--src/scxml/qscxmlstatemachine.cpp14
10 files changed, 82 insertions, 105 deletions
diff --git a/examples/scxml/mediaplayer-qml-cppdatamodel/thedatamodel.cpp b/examples/scxml/mediaplayer-qml-cppdatamodel/thedatamodel.cpp
index 8ac6864..aa0e427 100644
--- a/examples/scxml/mediaplayer-qml-cppdatamodel/thedatamodel.cpp
+++ b/examples/scxml/mediaplayer-qml-cppdatamodel/thedatamodel.cpp
@@ -57,9 +57,6 @@ TheDataModel::TheDataModel(QScxmlStateMachine *stateMachine)
{
}
-TheDataModel::~TheDataModel()
-{}
-
bool TheDataModel::isValidMedia() const
{
QString eventMedia = eventData().value(QStringLiteral("media")).toString();
diff --git a/examples/scxml/mediaplayer-qml-cppdatamodel/thedatamodel.h b/examples/scxml/mediaplayer-qml-cppdatamodel/thedatamodel.h
index ce4ac67..5c07436 100644
--- a/examples/scxml/mediaplayer-qml-cppdatamodel/thedatamodel.h
+++ b/examples/scxml/mediaplayer-qml-cppdatamodel/thedatamodel.h
@@ -59,7 +59,6 @@ class TheDataModel: public QScxmlCppDataModel
public:
TheDataModel(QScxmlStateMachine *stateMachine);
- ~TheDataModel();
private:
bool isValidMedia() const;
diff --git a/examples/scxml/pinball/doc/src/pinball.qdoc b/examples/scxml/pinball/doc/src/pinball.qdoc
index f67b66d..63309cf 100644
--- a/examples/scxml/pinball/doc/src/pinball.qdoc
+++ b/examples/scxml/pinball/doc/src/pinball.qdoc
@@ -105,11 +105,11 @@
\printuntil scxml
In this example we've chosen ecmascript data model
- ("datamodel" attribute of <scxml> element).
+ ("datamodel" attribute of \c <scxml> element).
This data model enables declaring variables with
initial values, which can be modified later.
We declare two variables in our model: "highscore" and "score",
- with initial values of 0 (two <data> elements inside <datamodel> element).
+ with initial values of 0 (two \c <data> elements inside \c <datamodel> element).
We also define a root parallel state "global",
with two child states: \c guiControl and \c internalState,
which are also parallel. Since the top \c global state is
@@ -158,7 +158,7 @@
As mentioned before, \c guiControl state is always active, and since
it is of parallel type, all its direct children are always active too.
So, \c cLight state is always active, however,
- only one of \c cLightOn or \c cLightOff it active at a time.
+ only one of \c cLightOn or \c cLightOff is active at a time.
The same applies to other children of \c guiControl state.
In addition, we define transitions between on and off substates, e.g.
whenever the active state is \c cLightOn and someone posts \c turnOffC event,
@@ -215,16 +215,16 @@
\quotefromfile pinball/pinball.scxml
\skipto letterState
\printuntil lettersState
- \printuntil rLetter
+ \printuntil letter.R
\dots 28
\skipto /^\ {24}<\//
- \printuntil aLetter
+ \printuntil letter.A
\dots 28
\skipto /^\ {24}<\//
- \printuntil zLetter
+ \printuntil letter.Z
\dots 28
\skipto /^\ {24}<\//
- \printuntil yLetter
+ \printuntil letter.Y
\dots 28
\skipto /^\ {24}<\//
\printuntil /^\ {16}<\//
@@ -262,40 +262,34 @@
correspond to five different letters. The content
for other letters states than C, which is omitted here, is analogous.
- The \c cLetter contains two substates reflecting its off and on states:
- \c cLetterOff and \c cLetterOn. The "cLetter" state inside its parallel
- parent \c lettersState is always active (under condition that
+ The \c {letter.C} contains two substates reflecting its off and on states:
+ \c cLetterOff and \c cLetterOn. The \c {letter.C} state inside its parallel
+ parent \c lettersState is always active (under the condition that
\c lettersState is active, too, what was described before), however,
only one of its child states is active at a time: \c cLetterOff or \c cLetterOn.
- The initial substate of \c cLetter state is \c cLetterOff meaning
- that whenever \c cLetter state is being activated (what happens
+ The initial substate of \c {letter.C} state is \c cLetterOff meaning
+ that whenever \c {letter.C} state is being activated (what happens
initially and after \c resetLetters event) its active
substate will be set to \c cLetterOff.
The \c cLetterOff defines a transition, which will be triggered by
the \c {cLetterTriggered} event. This transition activates the \c cLetterOn,
- the other child of \c cLetter, only when the machine is in \c onState
+ the other child of \c {letter.C}, only when the machine is in \c onState
(which will be defined later, but in short: when the pinball game is running).
The \c {cLetterTriggered} event is expected to be an event posted into the state machine
from outside of the state machine. This event should be generated when
the ball hits the \uicontrol C letter target. In our example we mimic
it by the pressing \uicontrol C letter button.
- The \c cLetterOn state defines additional action. The action is defined
- inside \c onentry element of the state, which means it will be executed
- when the state machine enters this state. The action will generate
- the event \c letterOn, which is common for all other letter states
- defined in \c lettersState. This event will be used in further part
- for updating the current score. So, whenever any of letters will switch
- its state from off to on (but not vice versa), the \c letterOn
- event will be posted.
-
The \c cLetterOn state is defined as a final state, which means that
- whenever this state is activated the \c {done.state.cLetter} event
- will be automatically posted by the state machine. Moreover,
- when all \c lettersState children reach their final state,
+ whenever this state is activated the \c {done.state.letter.C} event
+ will be automatically posted by the state machine. This event will be used
+ later for updating the current score.
+
+ Moreover, when all \c lettersState children reach their final state,
the state machine will automatically post \c {done.state.lettersState} event.
- Later, we will make use of it.
+ This event will be used later, too, for updating the current score
+ and for turning on or off the hurry state.
\quotefromfile pinball/pinball.scxml
\skipto modeState
@@ -348,8 +342,8 @@
\c resetLetters and \c update (the same as we generate when entering the \c onState).
In addition when we enter the \c hurryStateOn we send a delayed event
\c goToHurryOff with a delay of 5s, marked with \c hurryId. It means, that after 5s we just
- switch the state back to \c hurryStateOff. In this way we implement
- the five seconds hurry feature of the pinball table.
+ switch the state back to \c hurryStateOff without granting the bonus points.
+ In this way we implement the five seconds hurry feature of the pinball table.
We also define transitions: \c hurryStateOff -> \c hurryStateOn
when \c goToHurryOn event occurs and the opposite,
\c hurryStateOn -> \c hurryStateOff when \c goToHurryOff event occurs.
@@ -377,10 +371,10 @@
\quotefromfile pinball/pinball.scxml
\skipto workflow
- \printuntil letterOn
+ \printuntil done.state.letter.*
\dots 20
\skipto /^\ {16}<\//
- \printuntil lettersState
+ \printuntil done.state.lettersState
\dots 20
\skipto /^\ {16}<\//
\printuntil updateLights
@@ -416,13 +410,19 @@
\quotefromfile pinball/pinball.scxml
\skipto workflow
- \skipto letterOn
+ \skipto done.state.letter.*
\printuntil /^\ {16}<\//
\printuntil /^\ {16}<\//
- Whenever we receive the \c letterOn event we update the current score.
- The transition for the \c letterOn event is targetless, since we just
- listen for that event and update the internal data accordingly
+ Whenever we receive the event the name of which matches the
+ \c {done.state.letter.*} we update the current score.
+ When the machine enters the final substate of the \c {letter.C}
+ it emits the \c {done.state.letter.C} event. The same happens for
+ all other letters we have previously defined. We capture here
+ the events for all letters, that is why we've used an asterisk
+ after a dot in the event name.
+ The transition above is targetless, since we just
+ listen for matching events and update the internal data accordingly
without changing any active state. The new score is being
increased by 1.000 or 10.000 points, depending if we currently are
in \c hurryStateOff or \c hurryStateOn.
@@ -471,7 +471,7 @@
When we receive \c updateLights event, we first want to send a
\c updateScore signal outside of the state machine. We pass
- to the signal current value of highscore and score variables.
+ the current value of highscore and score variables to the signal.
This signal is received by the cpp part.
Next, depending if we are in \c jackpotStateOn or \c jackpotStateOff
@@ -530,9 +530,10 @@
the widget is disabled. We do that for all lights, targets
and description lables.
- We also connect to the \c updateScore propagated
- by the state machine and update the score displays
- with the values passed with the event.
+ We also connect to the \c eventOccurred() signal, propagated
+ by the state machine and intercept the \c updateScore
+ event sent from the SCXML document in order to update
+ the score displays with the values passed with the event.
The info about hitting any GUI target needs to be passed
to the state machine and we do that by connecting
diff --git a/examples/scxml/pinball/mainwindow.cpp b/examples/scxml/pinball/mainwindow.cpp
index 424a786..f2887f0 100644
--- a/examples/scxml/pinball/mainwindow.cpp
+++ b/examples/scxml/pinball/mainwindow.cpp
@@ -89,8 +89,8 @@ MainWindow::MainWindow(Pinball *machine, QWidget *parent) :
initAndConnect(QLatin1String("onState"), m_ui->ballOutButton);
// datamodel update
- connect(m_machine, SIGNAL(updateScore(const QVariant &)),
- this, SLOT(updateScore(const QVariant &)));
+ connect(m_machine, SIGNAL(eventOccurred(const QScxmlEvent &)),
+ this, SLOT(eventOccurred(const QScxmlEvent &)));
// gui interaction
connect(m_ui->cButton, &QAbstractButton::clicked,
@@ -127,8 +127,15 @@ void MainWindow::initAndConnect(const QString &state, QWidget *widget)
m_machine->connectToState(state, widget, SLOT(setEnabled(bool)));
}
-void MainWindow::updateScore(const QVariant &data)
+void MainWindow::eventOccurred(const QScxmlEvent &event)
{
+ if (event.originType() != QLatin1String("qt:signal"))
+ return;
+
+ if (event.name() != QLatin1String("updateScore"))
+ return;
+
+ const QVariant data = event.data();
const QString highScore = data.toMap().value("highScore").toString();
m_ui->highScoreLabel->setText(highScore);
const QString score = data.toMap().value("score").toString();
diff --git a/examples/scxml/pinball/mainwindow.h b/examples/scxml/pinball/mainwindow.h
index 985f77c..174248c 100644
--- a/examples/scxml/pinball/mainwindow.h
+++ b/examples/scxml/pinball/mainwindow.h
@@ -57,6 +57,7 @@ QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
+class QScxmlEvent;
QT_END_NAMESPACE
class Pinball;
@@ -70,7 +71,7 @@ public:
~MainWindow();
private slots:
- void updateScore(const QVariant &data);
+ void eventOccurred(const QScxmlEvent &event);
private:
void initAndConnect(const QString &state, QWidget *widget);
diff --git a/examples/scxml/pinball/pinball.scxml b/examples/scxml/pinball/pinball.scxml
index 735bca2..1ec7487 100644
--- a/examples/scxml/pinball/pinball.scxml
+++ b/examples/scxml/pinball/pinball.scxml
@@ -50,7 +50,7 @@
**
****************************************************************************/
-->
-<!-- enable-qt-mode: yes -->
+<!-- enable-qt-mode: no -->
<scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0"
name="Pinball" datamodel="ecmascript">
<datamodel>
@@ -129,55 +129,35 @@
<parallel id="logicalState">
<state id="letterState">
<parallel id="lettersState">
- <state id="cLetter">
+ <state id="letter.C">
<state id="cLetterOff">
<transition event="cLetterTriggered" cond="In('onState')" target="cLetterOn"/>
</state>
- <final id="cLetterOn">
- <onentry>
- <raise event="letterOn"/>
- </onentry>
- </final>
+ <final id="cLetterOn"/>
</state>
- <state id="rLetter">
+ <state id="letter.R">
<state id="rLetterOff">
<transition event="rLetterTriggered" cond="In('onState')" target="rLetterOn"/>
</state>
- <final id="rLetterOn">
- <onentry>
- <raise event="letterOn"/>
- </onentry>
- </final>
+ <final id="rLetterOn"/>
</state>
- <state id="aLetter">
+ <state id="letter.A">
<state id="aLetterOff">
<transition event="aLetterTriggered" cond="In('onState')" target="aLetterOn"/>
</state>
- <final id="aLetterOn">
- <onentry>
- <raise event="letterOn"/>
- </onentry>
- </final>
+ <final id="aLetterOn"/>
</state>
- <state id="zLetter">
+ <state id="letter.Z">
<state id="zLetterOff">
<transition event="zLetterTriggered" cond="In('onState')" target="zLetterOn"/>
</state>
- <final id="zLetterOn">
- <onentry>
- <raise event="letterOn"/>
- </onentry>
- </final>
+ <final id="zLetterOn"/>
</state>
- <state id="yLetter">
+ <state id="letter.Y">
<state id="yLetterOff">
<transition event="yLetterTriggered" cond="In('onState')" target="yLetterOn"/>
</state>
- <final id="yLetterOn">
- <onentry>
- <raise event="letterOn"/>
- </onentry>
- </final>
+ <final id="yLetterOn"/>
</state>
<transition event="resetLetters" target="lettersState"/>
</parallel>
@@ -264,7 +244,7 @@
<transition event="lightImpulse" cond="In('lightImpulseOff')" target="lightImpulseOn"/>
</state>
- <transition event="letterOn">
+ <transition event="done.state.letter.*">
<if cond="In('hurryStateOff')">
<assign location="score" expr="score + 1000"/>
<elseif cond="In('hurryStateOn')"/>
diff --git a/src/scxml/doc/qtscxml-index.qdoc b/src/scxml/doc/qtscxml-index.qdoc
index b3bbf02..e399c17 100644
--- a/src/scxml/doc/qtscxml-index.qdoc
+++ b/src/scxml/doc/qtscxml-index.qdoc
@@ -119,7 +119,7 @@
Light {
id: greenLight
color: "green"
- visible: stateMachine.green.active
+ visible: stateMachine.green
}
\endqml
@@ -129,7 +129,7 @@
event, you can write:
\code
- QObject::connect(stateMachine, &MediaPlayer::event_playbackStopped, [](){
+ QObject::connect(stateMachine, &MediaPlayer::playbackStopped, [](){
qDebug() << "Stopped!";
});
\endcode
@@ -139,7 +139,7 @@
\qml
Connections {
target: stateMachine
- onEvent_playbackStopped: console.log("Stopped!")
+ onPlaybackStopped: console.log("Stopped!")
}
\endqml
@@ -147,17 +147,17 @@
connect to) the slot:
\code
- stateMachine->event_tap_song(QVariantMap({
+ stateMachine->tap(QVariantMap({
std::make_pair("artist", "Fatboy Slim"),
std::make_pair("title", "The Rockafeller Skank")
});
\endcode
- This will generate a "tap_song" event with the map contents available in
+ This will generate a "tap" event with the map contents available in
_event.data inside the state machine. In QML:
\code
- stateMacine.event_tap_song({
+ stateMacine.tap({
"artist": "Fatboy Slim"
"title": "The Rockafeller Skank"
})
@@ -206,8 +206,8 @@
value \c "qt:signal" accepted by the attribute \c type.
The generated state machine or the state machine which has loaded
the SCXML file dynamically will contain corresponding
- signal, which name will consist of the \c event_ prefix
- followed by the value of the \c event attribute inside the \c <send> tag.
+ signal, the name of which will be equal to the value of the
+ \e event attribute inside the \c <send> tag.
All of the \c <param> children will be placed inside the
QMap<QString, QVariant> map, and this map will be passed as a
QVariant argument of the mentioned signal.
diff --git a/src/scxml/qscxmlcppdatamodel.cpp b/src/scxml/qscxmlcppdatamodel.cpp
index 1a34ba5..27783d5 100644
--- a/src/scxml/qscxmlcppdatamodel.cpp
+++ b/src/scxml/qscxmlcppdatamodel.cpp
@@ -70,15 +70,11 @@ using namespace QScxmlExecutableContent;
class TheDataModel: public QScxmlCppDataModel
{
Q_SCXML_DATAMODEL
-
-public:
- ~TheDataModel();
-
};
\endcode
The Q_SCXML_DATAMODEL has to appear in the private section of the class definition, for example
- right after the opening bracket, or after a Q_OBJECT macro. The destructor is needed to tell
- the C++ compiler where to generate the vtable, because this subclass implements some virtual
+ right after the opening bracket, or after a Q_OBJECT macro.
+ This macro expands to the declaration of some virtual
methods whose implementation is generated by the Qt SCXML compiler.
\note You can of course inherit from both QScxmlCppDataModel and QObject.
diff --git a/src/scxml/qscxmlcppdatamodel.h b/src/scxml/qscxmlcppdatamodel.h
index e0cd223..63226f7 100644
--- a/src/scxml/qscxmlcppdatamodel.h
+++ b/src/scxml/qscxmlcppdatamodel.h
@@ -44,10 +44,10 @@
#define Q_SCXML_DATAMODEL \
public: \
- QString evaluateToString(QScxmlExecutableContent::EvaluatorId id, bool *ok) Q_DECL_OVERRIDE; \
- bool evaluateToBool(QScxmlExecutableContent::EvaluatorId id, bool *ok) Q_DECL_OVERRIDE; \
- QVariant evaluateToVariant(QScxmlExecutableContent::EvaluatorId id, bool *ok) Q_DECL_OVERRIDE; \
- void evaluateToVoid(QScxmlExecutableContent::EvaluatorId id, bool *ok) Q_DECL_OVERRIDE; \
+ QString evaluateToString(QScxmlExecutableContent::EvaluatorId id, bool *ok) Q_DECL_OVERRIDE Q_DECL_FINAL; \
+ bool evaluateToBool(QScxmlExecutableContent::EvaluatorId id, bool *ok) Q_DECL_OVERRIDE Q_DECL_FINAL; \
+ QVariant evaluateToVariant(QScxmlExecutableContent::EvaluatorId id, bool *ok) Q_DECL_OVERRIDE Q_DECL_FINAL; \
+ void evaluateToVoid(QScxmlExecutableContent::EvaluatorId id, bool *ok) Q_DECL_OVERRIDE Q_DECL_FINAL; \
private:
QT_BEGIN_NAMESPACE
diff --git a/src/scxml/qscxmlstatemachine.cpp b/src/scxml/qscxmlstatemachine.cpp
index b520063..9b3f069 100644
--- a/src/scxml/qscxmlstatemachine.cpp
+++ b/src/scxml/qscxmlstatemachine.cpp
@@ -194,10 +194,8 @@ QScxmlEventFilter::~QScxmlEventFilter()
*
* All states which are defined in the SCXML file
* are accessible as properties of QScxmlStateMachine.
- * The type of these properties is a pointer to
- * QAbstractState. Every occurience of
- * a \c - character in the state's name inside SCXML file
- * is replaced with \c _dash_ sequence in the property name.
+ * These properties are of bool type which indicates
+ * whether the state is active or inactive.
*
* All external signals defined inside SCXML file,
* which are of "qt:signal" type, are accessible
@@ -206,11 +204,9 @@ QScxmlEventFilter::~QScxmlEventFilter()
* is always QVariant, which is of QMap<QString, QVariant>
* type containing the content of all \c <param>
* elements specified as children of \c <send> tag.
- * The signal names of QScxmlStateMachine
- * correspond to those defined in SCXML file
- * but are prefixed with \c event_, and \c -
- * characters are escaped with \c _dash_ sequence,
- * like in case of states' property names.
+ * The name of each QScxmlStateMachine signal
+ * corresponds to the value defined in the
+ * \e event attribute of one \c <send> tag in the SCXML file.
*/
QAtomicInt QScxmlStateMachinePrivate::m_sessionIdCounter = QAtomicInt(0);