KDStateMachineEditor API Documentation 2.1
Loading...
Searching...
No Matches
debuginterfaceclient.cpp
Go to the documentation of this file.
1/*
2 This file is part of the KDAB State Machine Editor Library.
3
4 SPDX-FileCopyrightText: 2015 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
5 Author: Kevin Funk <kevin.funk@kdab.com>
6
7 SPDX-License-Identifier: LGPL-2.1-only OR LicenseRef-KDAB-KDStateMachineEditor
8
9 Licensees holding valid commercial KDAB State Machine Editor Library
10 licenses may use this file in accordance with the KDAB State Machine Editor
11 Library License Agreement provided with the Software.
12
13 Contact info@kdab.com if any conditions of this licensing are not clear to you.
14*/
15
17
18#include <config-kdsme.h>
19
20#include "rep_debuginterface_replica.h"
21
22#include "runtimecontroller.h"
23#include "state.h"
24#include "transition.h"
25
26#include <QDebug>
27
28#define IF_DEBUG(x)
29
30using namespace KDSME;
31using namespace KDSME::DebugInterface;
32
33namespace {
34
35RuntimeController::Configuration toSmeConfiguration(const StateMachineConfiguration &config,
36 const QHash<StateId, State *> &map)
37{
39 for (const StateId &id : config) {
40 if (auto state = map.value(id)) {
41 result << state;
42 }
43 }
44 return result;
45}
46
47}
48
49struct DebugInterfaceClient::Private : public QObject
50{
51 Q_OBJECT
52
53public:
54 Private(DebugInterfaceClient *q)
55 : q(q)
56 , m_debugInterface(nullptr)
57 , m_machine(nullptr)
58 {
60 }
61
62public Q_SLOTS:
63 void showMessage(const QString &message);
64 void stateAdded(const DebugInterface::StateId stateId, const DebugInterface::StateId parentId, const bool hasChildren,
65 const QString &label, const DebugInterface::StateType type, const bool connectToInitial);
66 void stateConfigurationChanged(const DebugInterface::StateMachineConfiguration &config);
67 void transitionAdded(const DebugInterface::TransitionId transitionId, const DebugInterface::StateId source,
68 const DebugInterface::StateId target, const QString &label);
69 void statusChanged(const bool haveStateMachine, const bool running);
70 void transitionTriggered(DebugInterface::TransitionId transition, const QString &label);
71
72 void repopulateView();
73 void clearGraph();
74
75 void stateChanged(QRemoteObjectReplica::State state);
76
77public:
79 DebugInterfaceReplica *m_debugInterface;
80
81 QHash<DebugInterface::StateId, State *> m_idToStateMap;
82 QHash<DebugInterface::TransitionId, Transition *> m_idToTransitionMap;
83 StateMachine *m_machine;
84};
85
87 : RuntimeController(parent)
88 , d(new Private(this))
89{
90}
91
95
96DebugInterfaceReplica *DebugInterfaceClient::debugInterface() const
97{
98 return d->m_debugInterface;
99}
100
101void DebugInterfaceClient::setDebugInterface(DebugInterfaceReplica *debugInterface)
102{
103 if (d->m_debugInterface == debugInterface)
104 return;
105
106 if (d->m_debugInterface) {
107 disconnect(d->m_debugInterface, &DebugInterfaceReplica::message,
108 d.data(), &Private::showMessage);
109 disconnect(d->m_debugInterface, &DebugInterfaceReplica::stateConfigurationChanged,
110 d.data(), &Private::stateConfigurationChanged);
111 disconnect(d->m_debugInterface, &DebugInterfaceReplica::stateAdded,
112 d.data(), &Private::stateAdded);
113 disconnect(d->m_debugInterface, &DebugInterfaceReplica::transitionAdded,
114 d.data(), &Private::transitionAdded);
115 disconnect(d->m_debugInterface, &DebugInterfaceReplica::statusChanged,
116 d.data(), &Private::statusChanged);
117 disconnect(d->m_debugInterface, &DebugInterfaceReplica::transitionTriggered,
118 d.data(), &Private::transitionTriggered);
119 disconnect(d->m_debugInterface, &DebugInterfaceReplica::aboutToRepopulateGraph,
120 d.data(), &Private::clearGraph);
121 disconnect(d->m_debugInterface, &DebugInterfaceReplica::graphRepopulated,
122 d.data(), &Private::repopulateView);
123 disconnect(d->m_debugInterface, &DebugInterfaceReplica::stateChanged,
124 d.data(), &Private::stateChanged);
125
126 d->clearGraph();
127 }
128
129 d->m_debugInterface = debugInterface;
130
131 if (d->m_debugInterface) {
132 connect(d->m_debugInterface, &DebugInterfaceReplica::message,
133 d.data(), &Private::showMessage);
134 connect(d->m_debugInterface, &DebugInterfaceReplica::stateConfigurationChanged,
135 d.data(), &Private::stateConfigurationChanged);
136 connect(d->m_debugInterface, &DebugInterfaceReplica::stateAdded,
137 d.data(), &Private::stateAdded);
138 connect(d->m_debugInterface, &DebugInterfaceReplica::transitionAdded,
139 d.data(), &Private::transitionAdded);
140 connect(d->m_debugInterface, &DebugInterfaceReplica::statusChanged,
141 d.data(), &Private::statusChanged);
142 connect(d->m_debugInterface, &DebugInterfaceReplica::transitionTriggered,
143 d.data(), &Private::transitionTriggered);
144 connect(d->m_debugInterface, &DebugInterfaceReplica::aboutToRepopulateGraph,
145 d.data(), &Private::clearGraph);
146 connect(d->m_debugInterface, &DebugInterfaceReplica::graphRepopulated,
147 d.data(), &Private::repopulateView);
148 connect(d->m_debugInterface, &DebugInterfaceReplica::stateChanged,
149 d.data(), &Private::stateChanged);
150
151 d->m_debugInterface->repopulateGraph();
152 }
153}
154
156{
157 return d->m_machine;
158}
159
160void DebugInterfaceClient::Private::showMessage(const QString &message)
161{
162 Q_UNUSED(message);
163 // FIXME: Port
164}
165
166void DebugInterfaceClient::Private::stateConfigurationChanged(const StateMachineConfiguration &config)
167{
168 const auto smeConfig = toSmeConfiguration(config, m_idToStateMap);
169 q->setActiveConfiguration(smeConfig);
170}
171
172void DebugInterfaceClient::Private::stateAdded(const StateId stateId, const StateId parentId, const bool hasChildren,
173 const QString &label, const StateType type, const bool connectToInitial)
174{
175 Q_UNUSED(hasChildren);
176 IF_DEBUG(qDebug() << "stateAdded" << stateId << parentId << hasChildren << label << type << connectToInitial);
177
178 if (m_idToStateMap.contains(stateId)) {
179 return;
180 }
181
182 State *parentState = m_idToStateMap.value(parentId);
183 State *state = nullptr;
184 if (type == StateMachineState) {
185 state = m_machine = new StateMachine;
186 m_machine->setRuntimeController(q);
187 } else if (type == DebugInterface::FinalState) {
188 state = new FinalState(parentState);
189 } else if (type == DebugInterface::ShallowHistoryState) {
190 state = new HistoryState(HistoryState::ShallowHistory, parentState);
191 } else if (type == DebugInterface::DeepHistoryState) {
192 state = new HistoryState(HistoryState::DeepHistory, parentState);
193 } else {
194 state = new State(parentState);
195 }
196
197 if (connectToInitial && parentState) {
198 State *initialState = new PseudoState(PseudoState::InitialState, parentState);
200 Transition *transition = new Transition(initialState);
201 transition->setTargetState(state);
203 }
204
205 Q_ASSERT(state);
206 state->setLabel(label);
207 state->setInternalId(stateId);
209 m_idToStateMap[stateId] = state;
210}
211
212void DebugInterfaceClient::Private::transitionAdded(const TransitionId transitionId, const StateId sourceId, const StateId targetId, const QString &label)
213{
214 if (m_idToTransitionMap.contains(transitionId))
215 return;
216
217 IF_DEBUG(qDebug() << transitionId << label << sourceId << targetId);
218
219 State *source = m_idToStateMap.value(sourceId);
220 State *target = m_idToStateMap.value(targetId);
221 if (!source || !target) {
222 qDebug() << "Null source or target for transition:" << transitionId;
223 return;
224 }
225
226 Transition *transition = new Transition(source);
227 transition->setTargetState(target);
228 transition->setLabel(label);
230 m_idToTransitionMap[transitionId] = transition;
231}
232
233void DebugInterfaceClient::Private::statusChanged(const bool haveStateMachine, const bool running)
234{
235 Q_UNUSED(haveStateMachine);
236 IF_DEBUG(qDebug() << haveStateMachine << running);
237
238 if (m_machine) {
239 q->setIsRunning(running);
240 }
241}
242
243void DebugInterfaceClient::Private::transitionTriggered(TransitionId transitionId, const QString &label)
244{
245 Q_UNUSED(label);
246 q->setLastTransition(m_idToTransitionMap.value(transitionId));
247}
248
249void DebugInterfaceClient::Private::clearGraph()
250{
251 IF_DEBUG(qDebug());
252
253 m_idToStateMap.clear();
254 m_idToTransitionMap.clear();
255
256 Q_EMIT q->clearGraph();
257}
258
259void DebugInterfaceClient::Private::stateChanged(QRemoteObjectReplica::State state)
260{
261 if (state == QRemoteObjectReplica::Valid) {
262 m_debugInterface->repopulateGraph();
263 } else {
264 clearGraph();
265 }
266}
267
268void DebugInterfaceClient::Private::repopulateView()
269{
270 IF_DEBUG(qDebug() << m_machine);
271
272 Q_EMIT q->repopulateView();
273}
274
275#include "debuginterfaceclient.moc"
KDSME::StateMachine * machine() const
DebugInterfaceClient(QObject *parent=nullptr)
DebugInterfaceReplica * debugInterface() const
void setDebugInterface(DebugInterfaceReplica *debugInterface)
void setLabel(const QString &label)
Definition element.cpp:63
@ ElementIsSelectable
Definition element.h:73
void setInternalId(quintptr id)
Definition element.cpp:77
void setFlags(Flags flags)
Definition element.cpp:50
void setRuntimeController(RuntimeController *runtimeController)
Definition state.cpp:252
void setTargetState(State *targetState)
QList< StateId > StateMachineConfiguration
#define IF_DEBUG(x)

© Klarälvdalens Datakonsult AB (KDAB)
"The Qt, C++ and OpenGL Experts"
https://www.kdab.com/
KDStateMachineEditor
Create Qt State Machine metacode using a graphical user interface
https://github.com/KDAB/KDStateMachineEditor
Generated on Tue Jul 15 2025 15:21:47 for KDStateMachineEditor API Documentation by doxygen 1.9.8