1/****************************************************************************
2**
3** Copyright (C) 2016 Ford Motor Company
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtQml module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#include "statemachine.h"
41
42#include <QAbstractTransition>
43#include <QQmlContext>
44#include <QQmlEngine>
45#include <QQmlInfo>
46
47#include <private/qqmlopenmetaobject_p.h>
48#include <private/qqmlengine_p.h>
49
50StateMachine::StateMachine(QObject *parent)
51 : QStateMachine(parent), m_completed(false), m_running(false)
52{
53 connect(asender: this, SIGNAL(runningChanged(bool)), SIGNAL(qmlRunningChanged()));
54 connect(asender: this, SIGNAL(childModeChanged()), SLOT(checkChildMode()));
55}
56
57bool StateMachine::isRunning() const
58{
59 return QStateMachine::isRunning();
60}
61
62void StateMachine::setRunning(bool running)
63{
64 if (m_completed)
65 QStateMachine::setRunning(running);
66 else
67 m_running = running;
68}
69
70void StateMachine::checkChildMode()
71{
72 if (childMode() != QState::ExclusiveStates) {
73 qmlWarning(me: this) << "Setting the childMode of a StateMachine to anything else than\n"
74 "QState.ExclusiveStates will result in an invalid state machine,\n"
75 "and can lead to incorrect behavior!";
76 }
77}
78
79void StateMachine::componentComplete()
80{
81 if (QStateMachine::initialState() == nullptr && childMode() == QState::ExclusiveStates)
82 qmlWarning(me: this) << "No initial state set for StateMachine";
83
84 // Everything is proper setup, now start the state-machine if we got
85 // asked to do so.
86 m_completed = true;
87 if (m_running)
88 setRunning(true);
89}
90
91QQmlListProperty<QObject> StateMachine::children()
92{
93 return QQmlListProperty<QObject>(this, &m_children,
94 m_children.append, m_children.count, m_children.at,
95 m_children.clear, m_children.replace, m_children.removeLast);
96}
97
98/*!
99 \qmltype StateMachine
100 \inqmlmodule QtQml.StateMachine
101 \inherits State
102 \ingroup statemachine-qmltypes
103 \since 5.4
104
105 \brief Provides a hierarchical finite state machine.
106
107 StateMachine is based on the concepts and notation of
108 \l{http://www.wisdom.weizmann.ac.il/~dharel/SCANNED.PAPERS/Statecharts.pdf}{Statecharts}.
109 StateMachine is part of \l{The Declarative State Machine Framework}.
110
111 A state machine manages a set of states and transitions between those
112 states; these states and transitions define a state graph. Once a state
113 graph has been built, the state machine can execute it. StateMachine's
114 execution algorithm is based on the \l{http://www.w3.org/TR/scxml/}{State Chart XML (SCXML)}
115 algorithm. The framework's \l{The Declarative State Machine Framework}{overview}
116 gives several state graphs and the code to build them.
117
118 Before the machine can be started, the \l{State::initialState}{initialState}
119 must be set. The initial state is the state that the
120 machine enters when started. You can then set running property to true
121 or start() the state machine. The started signal is emitted when the
122 initial state is entered.
123
124 The state machine processes events and takes transitions until a
125 top-level final state is entered; the state machine then emits the
126 finished() signal. You can also stop() the state machine
127 explicitly (you can also set running property to false).
128 The stopped signal is emitted in this case.
129
130 \section1 Example Usage
131 The following snippet shows a state machine that will finish when a button
132 is clicked:
133
134 \snippet qml/statemachine/simplestatemachine.qml document
135
136 If an error is encountered, the machine will look for an
137 \l{State::errorState}{errorState}, and if one is available, it will
138 enter this state. After the error state is entered, the type of the error
139 can be retrieved with error(). The execution of the state graph will not
140 stop when the error state is entered. If no error state applies to the
141 erroneous state, the machine will stop executing and an error message will
142 be printed to the console.
143
144 \warning Setting the childMode of a StateMachine to anything else than QState::ExclusiveStates
145 will result in an invalid state machine, and can lead to incorrect behavior.
146
147 \clearfloat
148
149 \sa QAbstractState, State, SignalTransition, TimeoutTransition, HistoryState {The Declarative State Machine Framework}
150*/
151
152/*!
153 \qmlproperty enumeration StateMachine::globalRestorePolicy
154
155 \brief The restore policy for states of this state machine.
156
157 The default value of this property is QState.DontRestoreProperties.
158
159 This enum specifies the restore policy type. The restore policy
160 takes effect when the machine enters a state which sets one or more
161 properties. If the restore policy is set to QState.RestoreProperties,
162 the state machine will save the original value of the property before the
163 new value is set.
164
165 Later, when the machine either enters a state which does not set a
166 value for the given property, the property will automatically be restored
167 to its initial value.
168
169 Only one initial value will be saved for any given property. If a value
170 for a property has already been saved by the state machine, it will not be
171 overwritten until the property has been successfully restored.
172
173 \list
174 \li QState.DontRestoreProperties The state machine should not save the initial values of properties and restore them later.
175 \li QState.RestoreProperties The state machine should save the initial values of properties and restore them later.
176 \endlist
177*/
178
179/*!
180 \qmlproperty bool StateMachine::running
181
182 \brief The running state of this state machine.
183 \sa start(), stop()
184*/
185
186/*!
187 \qmlproperty string StateMachine::errorString
188 \readonly errorString
189
190 \brief The error string of this state machine.
191*/
192
193
194/*!
195 \qmlmethod StateMachine::start()
196
197 Starts this state machine. The machine will reset its configuration and
198 transition to the initial state. When a final top-level state (FinalState)
199 is entered, the machine will emit the finished() signal.
200
201 \note A state machine will not run without a running event loop, such as
202 the main application event loop started with QCoreApplication::exec() or
203 QApplication::exec().
204
205 \sa started, State::finished, stop(), State::initialState, running
206*/
207
208/*!
209 \qmlsignal StateMachine::started()
210
211 This signal is emitted when the state machine has entered its initial state
212 (State::initialState).
213
214 \sa running, start(), State::finished
215*/
216
217/*!
218 \qmlmethod StateMachine::stop()
219
220 Stops this state machine. The state machine will stop processing events
221 and then emit the stopped signal.
222
223 \sa stopped, start(), running
224*/
225
226/*!
227 \qmlsignal StateMachine::stopped()
228
229 This signal is emitted when the state machine has stopped.
230
231 \sa running, stop(), State::finished
232*/
233
234#include "moc_statemachine.cpp"
235

source code of qtdeclarative/src/imports/statemachine/statemachine.cpp