1 | // Copyright (C) 2016 Ford Motor Company |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
3 | |
4 | #include "state_p.h" |
5 | |
6 | #include <QQmlContext> |
7 | #include <QQmlEngine> |
8 | #include <QQmlInfo> |
9 | |
10 | State::State(QState *parent) |
11 | : QState(parent) |
12 | { |
13 | } |
14 | |
15 | QQmlListProperty<QObject> State::childrenActualCalculation() const |
16 | { |
17 | // Mutating accesses to m_children only happen in the QML thread, |
18 | // so there are no thread-safety issues. |
19 | // The engine only creates non-const instances of the class anyway |
20 | return QQmlListProperty<QObject>(const_cast<State*>(this), &m_children, |
21 | m_children.append, m_children.count, m_children.at, |
22 | m_children.clear, m_children.replace, m_children.removeLast); |
23 | } |
24 | |
25 | void State::componentComplete() |
26 | { |
27 | if (this->machine() == nullptr) { |
28 | static bool once = false; |
29 | if (!once) { |
30 | once = true; |
31 | qmlWarning(me: this) << "No top level StateMachine found. Nothing will run without a StateMachine." ; |
32 | } |
33 | } |
34 | } |
35 | |
36 | QQmlListProperty<QObject> State::children() |
37 | { |
38 | return m_childrenComputedProperty; |
39 | } |
40 | |
41 | void State::childrenContentChanged() |
42 | { |
43 | m_childrenComputedProperty.notify(); |
44 | emit childrenChanged(); |
45 | } |
46 | |
47 | QBindable<QQmlListProperty<QObject>> State::bindableChildren() const |
48 | { |
49 | return &m_childrenComputedProperty; |
50 | } |
51 | |
52 | /*! |
53 | \qmltype QAbstractState |
54 | \inqmlmodule QtQml.StateMachine |
55 | \ingroup statemachine-qmltypes |
56 | \since 5.4 |
57 | |
58 | \brief The QAbstractState type is the base type of States of a StateMachine. |
59 | |
60 | Do not use QAbstractState directly; use State, FinalState or |
61 | StateMachine instead. |
62 | |
63 | \sa StateMachine, State |
64 | */ |
65 | |
66 | /*! |
67 | \qmlproperty bool QAbstractState::active |
68 | \readonly active |
69 | |
70 | The active property of this state. A state is active between |
71 | entered() and exited() signals. This property is readonly. |
72 | |
73 | \sa entered, exited |
74 | */ |
75 | |
76 | /*! |
77 | \qmlsignal QAbstractState::entered() |
78 | |
79 | This signal is emitted when the State becomes active. |
80 | |
81 | \sa active, exited |
82 | */ |
83 | |
84 | /*! |
85 | \qmlsignal QAbstractState::exited() |
86 | |
87 | This signal is emitted when the State becomes inactive. |
88 | |
89 | \sa active, entered |
90 | */ |
91 | |
92 | /*! |
93 | \qmltype State |
94 | \inqmlmodule QtQml.StateMachine |
95 | \inherits QAbstractState |
96 | \ingroup statemachine-qmltypes |
97 | \since 5.4 |
98 | |
99 | \brief Provides a general-purpose state for StateMachine. |
100 | |
101 | State objects can have child states as well as transitions to other |
102 | states. State is part of \l{Qt State Machine QML Guide}{Qt State Machine QML API} |
103 | |
104 | \section1 States with Child States |
105 | |
106 | The childMode property determines how child states are treated. For |
107 | non-parallel state groups, the initialState property must be used to |
108 | set the initial state. The child states are mutually exclusive states, |
109 | and the state machine needs to know which child state to enter when the |
110 | parent state is the target of a transition. |
111 | |
112 | The state emits the State::finished() signal when a final child state |
113 | (FinalState) is entered. |
114 | |
115 | The errorState sets the state's error state. The error state is the state |
116 | that the state machine will transition to if an error is detected when |
117 | attempting to enter the state (e.g. because no initial state has been set). |
118 | |
119 | \section1 Example Usage |
120 | |
121 | \snippet qml/statemachine/basicstate.qml document |
122 | |
123 | \clearfloat |
124 | |
125 | \sa StateMachine, FinalState |
126 | */ |
127 | |
128 | /*! |
129 | \qmlproperty enumeration State::childMode |
130 | |
131 | \brief The child mode of this state |
132 | |
133 | The default value of this property is QState.ExclusiveStates. |
134 | |
135 | This enum specifies how a state's child states are treated: |
136 | \list |
137 | \li QState.ExclusiveStates The child states are mutually exclusive and an initial state must be set by setting initialState property. |
138 | \li QState.ParallelStates The child states are parallel. When the parent state is entered, all its child states are entered in parallel. |
139 | \endlist |
140 | */ |
141 | |
142 | /*! |
143 | \qmlproperty QAbstractState State::errorState |
144 | |
145 | \brief The error state of this state. |
146 | */ |
147 | |
148 | /*! |
149 | \qmlproperty QAbstractState State::initialState |
150 | |
151 | \brief The initial state of this state (one of its child states). |
152 | */ |
153 | |
154 | /*! |
155 | \qmlsignal State::finished() |
156 | |
157 | This signal is emitted when a final child state of this state is entered. |
158 | |
159 | \sa QAbstractState::active, QAbstractState::entered, QAbstractState::exited |
160 | */ |
161 | |
162 | /*! |
163 | \qmltype HistoryState |
164 | \inqmlmodule QtQml.StateMachine |
165 | \inherits QAbstractState |
166 | \ingroup statemachine-qmltypes |
167 | \since 5.4 |
168 | |
169 | \brief The HistoryState type provides a means of returning to a previously active substate. |
170 | |
171 | A history state is a pseudo-state that represents the child state that the |
172 | parent state was in the last time the parent state was exited. A transition |
173 | with a history state as its target is in fact a transition to one of the |
174 | other child states of the parent state. |
175 | HistoryState is part of \l{Qt State Machine QML Guide}{Qt State Machine QML API}. |
176 | |
177 | Use the defaultState property to set the state that should be entered |
178 | if the parent state has never been entered. |
179 | |
180 | \section1 Example Usage |
181 | |
182 | \snippet qml/statemachine/historystate.qml document |
183 | |
184 | \clearfloat |
185 | |
186 | By default, a history state is shallow, meaning that it will not remember |
187 | nested states. This can be configured through the historyType property. |
188 | |
189 | \sa StateMachine, State |
190 | */ |
191 | |
192 | /*! |
193 | \qmlproperty QAbstractState HistoryState::defaultState |
194 | |
195 | \brief The default state of this history state. |
196 | |
197 | The default state indicates the state to transition to if the parent |
198 | state has never been entered before. |
199 | */ |
200 | |
201 | /*! |
202 | \qmlproperty enumeration HistoryState::historyType |
203 | |
204 | \brief The type of history that this history state records. |
205 | |
206 | The default value of this property is HistoryState.ShallowHistory. |
207 | |
208 | This enum specifies the type of history that a HistoryState records. |
209 | \list |
210 | \li HistoryState.ShallowHistory Only the immediate child states of the |
211 | parent state are recorded. In this case, a transition with the history |
212 | state as its target will end up in the immediate child state that the |
213 | parent was in the last time it was exited. This is the default. |
214 | \li HistoryState.DeepHistory Nested states are recorded. In this case |
215 | a transition with the history state as its target will end up in the |
216 | most deeply nested descendant state the parent was in the last time |
217 | it was exited. |
218 | \endlist |
219 | */ |
220 | |
221 | #include "moc_state_p.cpp" |
222 | |