1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtScxml 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 "qscxmlstatemachineinfo_p.h"
41#include "qscxmlstatemachine_p.h"
42#include "qscxmlexecutablecontent_p.h"
43
44QT_BEGIN_NAMESPACE
45
46class QScxmlStateMachineInfoPrivate: public QObjectPrivate
47{
48 Q_DECLARE_PUBLIC(QScxmlStateMachineInfo)
49
50public:
51 QScxmlStateMachine *stateMachine() const
52 { return qobject_cast<QScxmlStateMachine *>(object: q_func()->parent()); }
53
54 QScxmlStateMachinePrivate *stateMachinePrivate() const
55 { return QScxmlStateMachinePrivate::get(t: stateMachine()); }
56
57 const QScxmlExecutableContent::StateTable *stateTable() const
58 { return stateMachinePrivate()->m_stateTable; }
59};
60
61QScxmlStateMachineInfo::QScxmlStateMachineInfo(QScxmlStateMachine *stateMachine)
62 : QObject(*new QScxmlStateMachineInfoPrivate, stateMachine)
63{
64 QScxmlStateMachinePrivate::get(t: stateMachine)->attach(info: this);
65}
66
67QScxmlStateMachine *QScxmlStateMachineInfo::stateMachine() const
68{
69 Q_D(const QScxmlStateMachineInfo);
70
71 return d->stateMachine();
72}
73
74QVector<QScxmlStateMachineInfo::StateId> QScxmlStateMachineInfo::allStates() const
75{
76 Q_D(const QScxmlStateMachineInfo);
77
78 QVector<QScxmlStateMachineInfo::StateId> all;
79 for (int i = 0, ei = d->stateTable()->stateCount; i < ei; ++i) {
80 all.append(t: i);
81 }
82 return all;
83}
84
85QVector<QScxmlStateMachineInfo::TransitionId> QScxmlStateMachineInfo::allTransitions() const
86{
87 Q_D(const QScxmlStateMachineInfo);
88
89 QVector<QScxmlStateMachineInfo::TransitionId> all;
90 for (int i = 0, ei = d->stateTable()->transitionCount; i < ei; ++i) {
91 all.append(t: i);
92 }
93 return all;
94}
95
96QString QScxmlStateMachineInfo::stateName(int stateId) const
97{
98 Q_D(const QScxmlStateMachineInfo);
99
100 if (stateId < 0 || stateId >= d->stateTable()->stateCount)
101 return QString();
102
103 auto state = d->stateTable()->state(idx: stateId);
104 if (state.name >= 0)
105 return d->stateMachinePrivate()->m_tableData->string(id: state.name);
106 else
107 return QString();
108}
109
110QScxmlStateMachineInfo::StateId QScxmlStateMachineInfo::stateParent(StateId stateId) const
111{
112 Q_D(const QScxmlStateMachineInfo);
113
114 if (stateId < 0 || stateId >= d->stateTable()->stateCount)
115 return InvalidStateId;
116
117 auto state = d->stateTable()->state(idx: stateId);
118 return state.parent;
119}
120
121QScxmlStateMachineInfo::StateType QScxmlStateMachineInfo::stateType(StateId stateId) const
122{
123 Q_D(const QScxmlStateMachineInfo);
124
125 if (stateId < 0 || stateId >= d->stateTable()->stateCount)
126 return InvalidState;
127
128 auto state = d->stateTable()->state(idx: stateId);
129 switch (state.type) {
130 default: return InvalidState;
131 case QScxmlExecutableContent::StateTable::State::Normal: return NormalState;
132 case QScxmlExecutableContent::StateTable::State::Parallel: return ParallelState;
133 case QScxmlExecutableContent::StateTable::State::Final: return FinalState;
134 case QScxmlExecutableContent::StateTable::State::ShallowHistory: return ShallowHistoryState;
135 case QScxmlExecutableContent::StateTable::State::DeepHistory: return DeepHistoryState;
136 }
137}
138
139QVector<QScxmlStateMachineInfo::StateId> QScxmlStateMachineInfo::stateChildren(StateId stateId) const
140{
141 Q_D(const QScxmlStateMachineInfo);
142
143 int childStates = QScxmlExecutableContent::StateTable::InvalidIndex;
144 if (stateId == InvalidStateId)
145 childStates = d->stateTable()->childStates;
146 if (stateId >= 0 && stateId < d->stateTable()->stateCount)
147 childStates = d->stateTable()->state(idx: stateId).childStates;
148
149 QVector<QScxmlStateMachineInfo::StateId> all;
150 if (childStates == QScxmlExecutableContent::StateTable::InvalidIndex)
151 return all;
152
153 const auto kids = d->stateTable()->array(idx: childStates);
154 all.reserve(asize: kids.size());
155 for (auto childId : kids) {
156 all.append(t: childId);
157 }
158 return all;
159}
160
161QScxmlStateMachineInfo::TransitionType QScxmlStateMachineInfo::transitionType(QScxmlStateMachineInfo::TransitionId transitionId) const
162{
163 Q_D(const QScxmlStateMachineInfo);
164
165 if (transitionId < 0 || transitionId >= d->stateTable()->transitionCount)
166 return InvalidTransition;
167
168 auto transition = d->stateTable()->transition(idx: transitionId);
169 switch (transition.type) {
170 default: return InvalidTransition;
171 case QScxmlExecutableContent::StateTable::Transition::Invalid: return InvalidTransition;
172 case QScxmlExecutableContent::StateTable::Transition::Internal: return InternalTransition;
173 case QScxmlExecutableContent::StateTable::Transition::External: return ExternalTransition;
174 case QScxmlExecutableContent::StateTable::Transition::Synthetic: return SyntheticTransition;
175 }
176}
177
178QScxmlStateMachineInfo::TransitionId QScxmlStateMachineInfo::initialTransition(StateId stateId) const
179{
180 Q_D(const QScxmlStateMachineInfo);
181
182 if (stateId == InvalidStateId)
183 return d->stateTable()->initialTransition;
184
185 if (stateId < 0 || stateId >= d->stateTable()->stateCount)
186 return InvalidTransitionId;
187
188 return d->stateTable()->state(idx: stateId).initialTransition;
189}
190
191QScxmlStateMachineInfo::StateId QScxmlStateMachineInfo::transitionSource(TransitionId transitionId) const
192{
193 Q_D(const QScxmlStateMachineInfo);
194
195 if (transitionId < 0 || transitionId >= d->stateTable()->transitionCount)
196 return InvalidStateId;
197
198 auto transition = d->stateTable()->transition(idx: transitionId);
199 return transition.source;
200}
201
202QVector<QScxmlStateMachineInfo::StateId> QScxmlStateMachineInfo::transitionTargets(TransitionId transitionId) const
203{
204 Q_D(const QScxmlStateMachineInfo);
205
206 QVector<QScxmlStateMachineInfo::StateId> targets;
207 if (transitionId < 0 || transitionId >= d->stateTable()->transitionCount)
208 return targets;
209
210 auto transition = d->stateTable()->transition(idx: transitionId);
211 if (transition.targets == QScxmlExecutableContent::StateTable::InvalidIndex)
212 return targets;
213
214 for (int target : d->stateTable()->array(idx: transition.targets)) {
215 targets.append(t: target);
216 }
217
218 return targets;
219}
220
221QVector<QString> QScxmlStateMachineInfo::transitionEvents(TransitionId transitionId) const
222{
223 Q_D(const QScxmlStateMachineInfo);
224
225 QVector<QString> events;
226 if (transitionId < 0 || transitionId >= d->stateTable()->transitionCount)
227 return events;
228
229 auto transition = d->stateTable()->transition(idx: transitionId);
230 if (transition.events == QScxmlExecutableContent::StateTable::InvalidIndex)
231 return events;
232
233 auto eventIds = d->stateTable()->array(idx: transition.events);
234 events.reserve(asize: eventIds.size());
235 for (auto eventId : eventIds) {
236 events.append(t: d->stateMachinePrivate()->m_tableData->string(id: eventId));
237 }
238
239 return events;
240}
241
242QVector<QScxmlStateMachineInfo::StateId> QScxmlStateMachineInfo::configuration() const
243{
244 Q_D(const QScxmlStateMachineInfo);
245 const auto &list = d->stateMachinePrivate()->configuration().list();
246 return QVector<StateId>(list.cbegin(), list.cend());
247}
248
249QT_END_NAMESPACE
250

source code of qtscxml/src/scxml/qscxmlstatemachineinfo.cpp