Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qqmlpreviewclient.cpp
Go to the documentation of this file.
1// Copyright (C) 2018 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// Qt-Security score:significant
4
5
7#include <private/qpacket_p.h>
8
9#include <QtCore/qurl.h>
10#include <QtCore/qfile.h>
11#include <QtCore/qfileinfo.h>
12#include <QtCore/qdir.h>
13#include <QtQml/qqmlfile.h>
14
16
17QQmlPreviewClient::QQmlPreviewClient(QQmlDebugConnection *connection)
18 : QQmlDebugClient(*(new QQmlPreviewClientPrivate(connection)))
19{
20 connect(this, &QQmlPreviewClient::confirmation, this,
21 [this](const QQmlPreviewClient::Settings &) { configureEventReplay(); });
22}
23
24void QQmlPreviewClient::messageReceived(const QByteArray &message)
25{
26 QPacket packet(connection()->currentDataStreamVersion(), message);
27
28 qint8 command;
29 packet >> command;
30
31 switch (command) {
32 case Error: {
33 QString seviceError;
34 packet >> seviceError;
35 emit error(seviceError);
36 break;
37 }
38 case Request: {
39 QString fileName;
40 packet >> fileName;
41 emit request(fileName);
42 break;
43 }
44 case Fps: {
45 FpsInfo info;
46 packet >> info.numSyncs >> info.minSync >> info.maxSync >> info.totalSync
47 >> info.numRenders >> info.minRender >> info.maxRender >> info.totalRender;
48 emit fps(info);
49 break;
50 }
51 case Confirmation: {
52 Settings settings;
53 packet >> settings.enableInPlaceUpdates;
54 emit confirmation(settings);
55 break;
56 }
57 case HotReloadFailure: {
58 QString reason;
59 packet >> reason;
60 emit hotReloadFailure(reason);
61 break;
62 }
63 default:
64 emit error(QString::fromLatin1("Unknown command received: %1").arg(command));
65 break;
66 }
67}
68
69void QQmlPreviewClient::sendDirectory(const QString &path, const QStringList &entries)
70{
71 QPacket packet(connection()->currentDataStreamVersion());
72 packet << static_cast<qint8>(Directory) << path << entries;
73 sendMessage(packet.data());
74}
75
76void QQmlPreviewClient::sendFile(const QString &path, const QByteArray &contents)
77{
78 QPacket packet(connection()->currentDataStreamVersion());
79 packet << static_cast<qint8>(File) << path << contents;
80 sendMessage(packet.data());
81}
82
83void QQmlPreviewClient::sendError(const QString &path)
84{
85 QPacket packet(connection()->currentDataStreamVersion());
86 packet << static_cast<qint8>(Error) << path;
87 sendMessage(packet.data());
88}
89
91{
92 QPacket packet(connection()->currentDataStreamVersion());
93 packet << static_cast<qint8>(Configuration) << config.enableInPlaceUpdates;
94 sendMessage(packet.data());
95}
96
97void QQmlPreviewClient::triggerLoad(const QUrl &url)
98{
99 QPacket packet(connection()->currentDataStreamVersion());
100 packet << static_cast<qint8>(Load) << url;
101 sendMessage(packet.data());
102}
103
105{
106 QPacket packet(connection()->currentDataStreamVersion());
107 packet << static_cast<qint8>(Rerun);
108 sendMessage(packet.data());
109}
110
112{
113 QPacket packet(connection()->currentDataStreamVersion());
114 packet << static_cast<qint8>(Zoom) << factor;
115 sendMessage(packet.data());
116}
117
119{
120 QPacket packet(connection()->currentDataStreamVersion());
121 packet << static_cast<qint8>(AnimationSpeed) << factor;
122 sendMessage(packet.data());
123}
124
125void QQmlPreviewClient::configureEventReplay()
126{
127 Q_ASSERT(connection());
128 if (!d_func()->m_recordingData) {
129 d_func()->m_recordingData =
130 std::make_unique<QQmlPreviewClientPrivate::PreviewRecordingData>(connection());
131 }
132
133 recordClient().setFlushInterval(1);
134 recordClient().setRecording(true);
135 auto &timer = replayTimer();
136 timer.setInterval(100);
137 connect(&timer, &QTimer::timeout, this, [this, &timer]() {
138 if (eventReceiver().numLoadedEvents() < numExpectedEvents())
139 return;
141 timer.stop();
142 });
143
144 // We want to start the replay as soon as possible after the configuration is confirmed.
145 if (eventReceiver().numLoadedEvents() > 0 && replayClient().state() == Enabled) {
146 replayEventsForUrl(QUrl());
147 }
148}
149
151{
152 const auto events = eventReceiver().events();
153 const auto types = eventReceiver().eventTypes();
155 triggerLoad(url);
156 for (const auto &event : events)
157 replayClient().sendEvent(types[event.typeIndex()], event);
158 eventReceiver().clear();
159 replayTimer().start();
160}
161
162void QQmlPreviewClient::loadUrl(const QUrl &url)
163{
164 if (!d_func()->m_recordingData)
165 return triggerLoad(url);
166
167 setNumExpectedEvents(eventReceiver().numLoadedEvents());
168 if (numExpectedEvents() > 0 && replayClient().state() == Enabled) {
169 replayEventsForUrl(url);
170 } else {
171 eventReceiver().clear();
172 triggerLoad(url);
173 }
174}
175
176void QQmlPreviewClient::setNumExpectedEvents(qsizetype eventCount)
177{
178 Q_D(QQmlPreviewClient);
179 d->m_numExpectedEvents = eventCount;
180}
181
182qsizetype QQmlPreviewClient::numExpectedEvents() const
183{
184 Q_D(const QQmlPreviewClient);
185 return d->m_numExpectedEvents;
186}
187
188QTimer &QQmlPreviewClient::replayTimer() const
189{
190 Q_D(const QQmlPreviewClient);
191 return d->m_recordingData->replayTimer;
192}
193
194QQmlProfilerClient &QQmlPreviewClient::recordClient() const
195{
196 Q_D(const QQmlPreviewClient);
197 return d->m_recordingData->recordClient;
198}
199
200QQuickEventReplayClient &QQmlPreviewClient::replayClient() const
201{
202 Q_D(const QQmlPreviewClient);
203 return d->m_recordingData->replayClient;
204}
205
206QQmlProfilerQtdWriter &QQmlPreviewClient::eventReceiver() const
207{
208 Q_D(const QQmlPreviewClient);
209 return d->m_recordingData->eventReceiver;
210}
211
212QT_END_NAMESPACE
213
214#include "moc_qqmlpreviewclient_p.cpp"
void messageReceived(const QByteArray &message) override
void triggerZoom(float factor)
void replayEventsForUrl(const QUrl &url)
void triggerAnimationSpeed(float factor)
void sendFile(const QString &path, const QByteArray &contents)
void sendError(const QString &path)
void sendDirectory(const QString &path, const QStringList &entries)
void sendConfiguration(const Settings &settings)
void triggerLoad(const QUrl &url)
void loadUrl(const QUrl &url)
Combined button and popup list for selecting options.