1// Copyright (C) 2016 The Qt Company Ltd.
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 "qscxmlstatemachineinfo_p.h"
5#include "qscxmlstatemachine_p.h"
6#include "qscxmlexecutablecontent_p.h"
7
8QT_BEGIN_NAMESPACE
9
10class QScxmlStateMachineInfoPrivate: public QObjectPrivate
11{
12 Q_DECLARE_PUBLIC(QScxmlStateMachineInfo)
13
14public:
15 QScxmlStateMachine *stateMachine() const
16 { return qobject_cast<QScxmlStateMachine *>(object: q_func()->parent()); }
17
18 QScxmlStateMachinePrivate *stateMachinePrivate() const
19 { return QScxmlStateMachinePrivate::get(t: stateMachine()); }
20
21 const QScxmlExecutableContent::StateTable *stateTable() const
22 { return stateMachinePrivate()->m_stateTable; }
23};
24
25QScxmlStateMachineInfo::QScxmlStateMachineInfo(QScxmlStateMachine *stateMachine)
26 : QObject(*new QScxmlStateMachineInfoPrivate, stateMachine)
27{
28 QScxmlStateMachinePrivate::get(t: stateMachine)->attach(info: this);
29}
30
31QScxmlStateMachine *QScxmlStateMachineInfo::stateMachine() const
32{
33 Q_D(const QScxmlStateMachineInfo);
34
35 return d->stateMachine();
36}
37
38QList<QScxmlStateMachineInfo::StateId> QScxmlStateMachineInfo::allStates() const
39{
40 Q_D(const QScxmlStateMachineInfo);
41
42 QList<QScxmlStateMachineInfo::StateId> all;
43 for (int i = 0, ei = d->stateTable()->stateCount; i < ei; ++i) {
44 all.append(t: i);
45 }
46 return all;
47}
48
49QList<QScxmlStateMachineInfo::TransitionId> QScxmlStateMachineInfo::allTransitions() const
50{
51 Q_D(const QScxmlStateMachineInfo);
52
53 QList<QScxmlStateMachineInfo::TransitionId> all;
54 for (int i = 0, ei = d->stateTable()->transitionCount; i < ei; ++i) {
55 all.append(t: i);
56 }
57 return all;
58}
59
60QString QScxmlStateMachineInfo::stateName(int stateId) const
61{
62 Q_D(const QScxmlStateMachineInfo);
63
64 if (stateId < 0 || stateId >= d->stateTable()->stateCount)
65 return QString();
66
67 auto state = d->stateTable()->state(idx: stateId);
68 if (state.name >= 0)
69 return d->stateMachinePrivate()->m_tableData->string(id: state.name);
70 else
71 return QString();
72}
73
74QScxmlStateMachineInfo::StateId QScxmlStateMachineInfo::stateParent(StateId stateId) const
75{
76 Q_D(const QScxmlStateMachineInfo);
77
78 if (stateId < 0 || stateId >= d->stateTable()->stateCount)
79 return InvalidStateId;
80
81 auto state = d->stateTable()->state(idx: stateId);
82 return state.parent;
83}
84
85QScxmlStateMachineInfo::StateType QScxmlStateMachineInfo::stateType(StateId stateId) const
86{
87 Q_D(const QScxmlStateMachineInfo);
88
89 if (stateId < 0 || stateId >= d->stateTable()->stateCount)
90 return InvalidState;
91
92 auto state = d->stateTable()->state(idx: stateId);
93 switch (state.type) {
94 default: return InvalidState;
95 case QScxmlExecutableContent::StateTable::State::Normal: return NormalState;
96 case QScxmlExecutableContent::StateTable::State::Parallel: return ParallelState;
97 case QScxmlExecutableContent::StateTable::State::Final: return FinalState;
98 case QScxmlExecutableContent::StateTable::State::ShallowHistory: return ShallowHistoryState;
99 case QScxmlExecutableContent::StateTable::State::DeepHistory: return DeepHistoryState;
100 }
101}
102
103QList<QScxmlStateMachineInfo::StateId> QScxmlStateMachineInfo::stateChildren(StateId stateId) const
104{
105 Q_D(const QScxmlStateMachineInfo);
106
107 int childStates = QScxmlExecutableContent::StateTable::InvalidIndex;
108 if (stateId == InvalidStateId)
109 childStates = d->stateTable()->childStates;
110 if (stateId >= 0 && stateId < d->stateTable()->stateCount)
111 childStates = d->stateTable()->state(idx: stateId).childStates;
112
113 QList<QScxmlStateMachineInfo::StateId> all;
114 if (childStates == QScxmlExecutableContent::StateTable::InvalidIndex)
115 return all;
116
117 const auto kids = d->stateTable()->array(idx: childStates);
118 all.reserve(asize: kids.size());
119 for (auto childId : kids) {
120 all.append(t: childId);
121 }
122 return all;
123}
124
125QScxmlStateMachineInfo::TransitionType QScxmlStateMachineInfo::transitionType(QScxmlStateMachineInfo::TransitionId transitionId) const
126{
127 Q_D(const QScxmlStateMachineInfo);
128
129 if (transitionId < 0 || transitionId >= d->stateTable()->transitionCount)
130 return InvalidTransition;
131
132 auto transition = d->stateTable()->transition(idx: transitionId);
133 switch (transition.type) {
134 default: return InvalidTransition;
135 case QScxmlExecutableContent::StateTable::Transition::Invalid: return InvalidTransition;
136 case QScxmlExecutableContent::StateTable::Transition::Internal: return InternalTransition;
137 case QScxmlExecutableContent::StateTable::Transition::External: return ExternalTransition;
138 case QScxmlExecutableContent::StateTable::Transition::Synthetic: return SyntheticTransition;
139 }
140}
141
142QScxmlStateMachineInfo::TransitionId QScxmlStateMachineInfo::initialTransition(StateId stateId) const
143{
144 Q_D(const QScxmlStateMachineInfo);
145
146 if (stateId == InvalidStateId)
147 return d->stateTable()->initialTransition;
148
149 if (stateId < 0 || stateId >= d->stateTable()->stateCount)
150 return InvalidTransitionId;
151
152 return d->stateTable()->state(idx: stateId).initialTransition;
153}
154
155QScxmlStateMachineInfo::StateId QScxmlStateMachineInfo::transitionSource(TransitionId transitionId) const
156{
157 Q_D(const QScxmlStateMachineInfo);
158
159 if (transitionId < 0 || transitionId >= d->stateTable()->transitionCount)
160 return InvalidStateId;
161
162 auto transition = d->stateTable()->transition(idx: transitionId);
163 return transition.source;
164}
165
166QList<QScxmlStateMachineInfo::StateId> QScxmlStateMachineInfo::transitionTargets(TransitionId transitionId) const
167{
168 Q_D(const QScxmlStateMachineInfo);
169
170 QList<QScxmlStateMachineInfo::StateId> targets;
171 if (transitionId < 0 || transitionId >= d->stateTable()->transitionCount)
172 return targets;
173
174 auto transition = d->stateTable()->transition(idx: transitionId);
175 if (transition.targets == QScxmlExecutableContent::StateTable::InvalidIndex)
176 return targets;
177
178 for (int target : d->stateTable()->array(idx: transition.targets)) {
179 targets.append(t: target);
180 }
181
182 return targets;
183}
184
185QList<QString> QScxmlStateMachineInfo::transitionEvents(TransitionId transitionId) const
186{
187 Q_D(const QScxmlStateMachineInfo);
188
189 QList<QString> events;
190 if (transitionId < 0 || transitionId >= d->stateTable()->transitionCount)
191 return events;
192
193 auto transition = d->stateTable()->transition(idx: transitionId);
194 if (transition.events == QScxmlExecutableContent::StateTable::InvalidIndex)
195 return events;
196
197 auto eventIds = d->stateTable()->array(idx: transition.events);
198 events.reserve(asize: eventIds.size());
199 for (auto eventId : eventIds) {
200 events.append(t: d->stateMachinePrivate()->m_tableData->string(id: eventId));
201 }
202
203 return events;
204}
205
206QList<QScxmlStateMachineInfo::StateId> QScxmlStateMachineInfo::configuration() const
207{
208 Q_D(const QScxmlStateMachineInfo);
209 const auto &list = d->stateMachinePrivate()->configuration().list();
210 return QList<StateId>(list.cbegin(), list.cend());
211}
212
213QT_END_NAMESPACE
214

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