@dusted/anqst 1.7.1 → 1.7.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AnQstWebBase/AnQstWebBaseAbi.cmake +1 -0
- package/AnQstWebBase/CMakeLists.txt +116 -0
- package/AnQstWebBase/CMakeUserPresets.json +14 -0
- package/AnQstWebBase/README.md +65 -0
- package/AnQstWebBase/src/AnQstBase93.cpp +91 -0
- package/AnQstWebBase/src/AnQstBase93.h +15 -0
- package/AnQstWebBase/src/AnQstBridgeProxy.cpp +30 -0
- package/AnQstWebBase/src/AnQstBridgeProxy.h +41 -0
- package/AnQstWebBase/src/AnQstHostBridgeFacade.cpp +345 -0
- package/AnQstWebBase/src/AnQstHostBridgeFacade.h +99 -0
- package/AnQstWebBase/src/AnQstWebBaseAbi.h +4 -0
- package/AnQstWebBase/src/AnQstWebBaseAbi.h.in +4 -0
- package/AnQstWebBase/src/AnQstWebHostBase.cpp +1822 -0
- package/AnQstWebBase/src/AnQstWebHostBase.h +227 -0
- package/AnQstWebBase/src/AnQstWidgetDebugDialog.cpp +425 -0
- package/AnQstWebBase/src/AnQstWidgetDebugDialog.h +105 -0
- package/AnQstWebBase/src/AngularHttpBaseServer.cpp +965 -0
- package/AnQstWebBase/src/AngularHttpBaseServer.h +97 -0
- package/AnQstWebBase/src/UI/AnQstWidgetDebugDialog.ui +235 -0
- package/AnQstWebBase/tests/CMakeLists.txt +22 -0
- package/AnQstWebBase/tests/test_AnQstWebHostBase.cpp +1102 -0
- package/dist/src/abi-hash-stamp.js +5 -0
- package/dist/src/abi-hash.js +33 -0
- package/dist/src/app.js +67 -19
- package/dist/src/boundary-codec-render.js +17 -10
- package/dist/src/emit.js +76 -30
- package/dist/src/project.js +11 -1
- package/dist/src/webbase.js +94 -0
- package/package.json +2 -1
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
#include "AnQstHostBridgeFacade.h"
|
|
2
|
+
|
|
3
|
+
#include <QEventLoop>
|
|
4
|
+
#include <QTimer>
|
|
5
|
+
|
|
6
|
+
namespace ANQST_WEBBASE_NAMESPACE {
|
|
7
|
+
|
|
8
|
+
AnQstHostBridgeFacade::AnQstHostBridgeFacade(QObject* parent)
|
|
9
|
+
: QObject(parent)
|
|
10
|
+
, m_dispatchEnabled(false)
|
|
11
|
+
, m_slotRequestCounter(0)
|
|
12
|
+
, m_slotInvocationTimeoutMs(1000) {
|
|
13
|
+
connect(this, &AnQstHostBridgeFacade::slotInvocationResolved, this, [this](const QString&) {
|
|
14
|
+
// no-op connection so tests can wait for this signal deterministically.
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
void AnQstHostBridgeFacade::setCallHandler(const CallHandler& handler) {
|
|
19
|
+
m_callHandler = handler;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
void AnQstHostBridgeFacade::setEmitterHandler(const EmitterHandler& handler) {
|
|
23
|
+
m_emitterHandler = handler;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
void AnQstHostBridgeFacade::setInputHandler(const InputHandler& handler) {
|
|
27
|
+
m_inputHandler = handler;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
void AnQstHostBridgeFacade::setOutputValue(const QString& service, const QString& member, const QVariant& value) {
|
|
31
|
+
const QString key = makeSlotKey(service, member);
|
|
32
|
+
m_outputValues.insert(key, value);
|
|
33
|
+
if (m_dispatchEnabled) {
|
|
34
|
+
emit bridgeOutputUpdated(service, member, value);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
bool AnQstHostBridgeFacade::invokeSlot(const QString& service, const QString& member, const QVariantList& args, QVariant* result, QString* error) {
|
|
39
|
+
const QString key = makeSlotKey(service, member);
|
|
40
|
+
const QString requestId = QStringLiteral("slot-%1").arg(++m_slotRequestCounter);
|
|
41
|
+
m_slotInvocationResponses.insert(requestId, SlotInvocationResponse{});
|
|
42
|
+
|
|
43
|
+
PendingSlotInvocation pending{requestId, service, member, args};
|
|
44
|
+
if (m_dispatchEnabled && m_registeredSlots.value(key, false)) {
|
|
45
|
+
emit bridgeSlotInvocationRequested(requestId, service, member, args);
|
|
46
|
+
} else {
|
|
47
|
+
auto& queue = m_queuedSlotInvocations[key];
|
|
48
|
+
if (queue.size() >= kMaxQueuedSlotInvocations) {
|
|
49
|
+
emitQueuedSlotOverflowError(key);
|
|
50
|
+
m_slotInvocationResponses.remove(requestId);
|
|
51
|
+
if (error != nullptr) {
|
|
52
|
+
*error = QStringLiteral("slot queue overflow");
|
|
53
|
+
}
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
queue.enqueue(pending);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
SlotInvocationResponse& response = m_slotInvocationResponses[requestId];
|
|
60
|
+
QEventLoop loop;
|
|
61
|
+
QTimer timeout;
|
|
62
|
+
timeout.setSingleShot(true);
|
|
63
|
+
|
|
64
|
+
connect(this, &AnQstHostBridgeFacade::slotInvocationResolved, &loop, [&](const QString& resolvedRequestId) {
|
|
65
|
+
if (resolvedRequestId == requestId) {
|
|
66
|
+
loop.quit();
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
connect(&timeout, &QTimer::timeout, &loop, &QEventLoop::quit);
|
|
70
|
+
|
|
71
|
+
timeout.start(m_slotInvocationTimeoutMs);
|
|
72
|
+
while (!response.done && timeout.isActive()) {
|
|
73
|
+
loop.exec();
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (!response.done) {
|
|
77
|
+
const bool slotRegistered = m_registeredSlots.value(key, false);
|
|
78
|
+
emitHostError(
|
|
79
|
+
slotRegistered ? QStringLiteral("BridgeTimeoutError") : QStringLiteral("HandlerNotRegisteredError"),
|
|
80
|
+
QStringLiteral("runtime"),
|
|
81
|
+
QStringLiteral("error"),
|
|
82
|
+
true,
|
|
83
|
+
slotRegistered
|
|
84
|
+
? QStringLiteral("Slot invocation timed out while waiting for a frontend reply.")
|
|
85
|
+
: QStringLiteral("Slot invocation timed out before the frontend registered the slot handler."),
|
|
86
|
+
{
|
|
87
|
+
{QStringLiteral("service"), service},
|
|
88
|
+
{QStringLiteral("member"), member},
|
|
89
|
+
{QStringLiteral("requestId"), requestId},
|
|
90
|
+
{QStringLiteral("timeoutMs"), m_slotInvocationTimeoutMs},
|
|
91
|
+
{QStringLiteral("slotRegistered"), slotRegistered},
|
|
92
|
+
{QStringLiteral("reason"), slotRegistered ? QStringLiteral("reply_timeout") : QStringLiteral("registration_timeout")},
|
|
93
|
+
});
|
|
94
|
+
m_slotInvocationResponses.remove(requestId);
|
|
95
|
+
if (error != nullptr) {
|
|
96
|
+
*error = QStringLiteral("slot invocation timeout");
|
|
97
|
+
}
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (result != nullptr) {
|
|
102
|
+
*result = response.payload;
|
|
103
|
+
}
|
|
104
|
+
if (error != nullptr) {
|
|
105
|
+
*error = response.error;
|
|
106
|
+
}
|
|
107
|
+
const bool ok = response.ok;
|
|
108
|
+
m_slotInvocationResponses.remove(requestId);
|
|
109
|
+
return ok;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
void AnQstHostBridgeFacade::setSlotInvocationTimeoutMs(int timeoutMs) {
|
|
113
|
+
if (timeoutMs <= 0) {
|
|
114
|
+
emitHostError(
|
|
115
|
+
QStringLiteral("HOST_MAPPING_PAYLOAD_INVALID"),
|
|
116
|
+
QStringLiteral("mapping"),
|
|
117
|
+
QStringLiteral("warn"),
|
|
118
|
+
true,
|
|
119
|
+
QStringLiteral("Slot invocation timeout must be positive."),
|
|
120
|
+
{{QStringLiteral("providedTimeoutMs"), timeoutMs}});
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
m_slotInvocationTimeoutMs = timeoutMs;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
int AnQstHostBridgeFacade::slotInvocationTimeoutMs() const {
|
|
127
|
+
return m_slotInvocationTimeoutMs;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
void AnQstHostBridgeFacade::setDispatchEnabled(bool enabled) {
|
|
131
|
+
const bool changed = (m_dispatchEnabled != enabled);
|
|
132
|
+
m_dispatchEnabled = enabled;
|
|
133
|
+
if (!m_dispatchEnabled) {
|
|
134
|
+
m_registeredSlots.clear();
|
|
135
|
+
}
|
|
136
|
+
if (m_dispatchEnabled && changed) {
|
|
137
|
+
emitOutputSnapshot();
|
|
138
|
+
const auto registeredSlots = m_registeredSlots.keys();
|
|
139
|
+
for (const QString& slotKey : registeredSlots) {
|
|
140
|
+
dispatchQueuedSlotInvocations(slotKey);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
bool AnQstHostBridgeFacade::dispatchEnabled() const {
|
|
146
|
+
return m_dispatchEnabled;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
void AnQstHostBridgeFacade::registerSlot(const QString& service, const QString& member) {
|
|
150
|
+
const QString key = makeSlotKey(service, member);
|
|
151
|
+
m_registeredSlots.insert(key, true);
|
|
152
|
+
if (m_dispatchEnabled) {
|
|
153
|
+
dispatchQueuedSlotInvocations(key);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
QVariant AnQstHostBridgeFacade::call(const QString& service, const QString& member, const QVariantList& args) {
|
|
158
|
+
if (!m_callHandler) {
|
|
159
|
+
emitHostError(
|
|
160
|
+
QStringLiteral("HOST_BRIDGE_SETUP_FAILED"),
|
|
161
|
+
QStringLiteral("bridge"),
|
|
162
|
+
QStringLiteral("error"),
|
|
163
|
+
false,
|
|
164
|
+
QStringLiteral("No Call handler has been configured."),
|
|
165
|
+
{
|
|
166
|
+
{QStringLiteral("service"), service},
|
|
167
|
+
{QStringLiteral("member"), member},
|
|
168
|
+
});
|
|
169
|
+
return QVariant();
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
try {
|
|
173
|
+
return m_callHandler(service, member, args);
|
|
174
|
+
} catch (...) {
|
|
175
|
+
emitHostError(
|
|
176
|
+
QStringLiteral("HOST_MAPPING_PAYLOAD_INVALID"),
|
|
177
|
+
QStringLiteral("mapping"),
|
|
178
|
+
QStringLiteral("error"),
|
|
179
|
+
true,
|
|
180
|
+
QStringLiteral("Call handler threw while processing payload."),
|
|
181
|
+
{
|
|
182
|
+
{QStringLiteral("service"), service},
|
|
183
|
+
{QStringLiteral("member"), member},
|
|
184
|
+
});
|
|
185
|
+
return QVariant();
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
void AnQstHostBridgeFacade::emitMessage(const QString& service, const QString& member, const QVariantList& args) {
|
|
190
|
+
if (!m_emitterHandler) {
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
try {
|
|
195
|
+
m_emitterHandler(service, member, args);
|
|
196
|
+
} catch (const std::exception& ex) {
|
|
197
|
+
emitHostError(
|
|
198
|
+
QStringLiteral("EmitterHandlerError"),
|
|
199
|
+
QStringLiteral("bridge"),
|
|
200
|
+
QStringLiteral("error"),
|
|
201
|
+
true,
|
|
202
|
+
QStringLiteral("Emitter handler threw while processing payload."),
|
|
203
|
+
{
|
|
204
|
+
{QStringLiteral("service"), service},
|
|
205
|
+
{QStringLiteral("member"), member},
|
|
206
|
+
{QStringLiteral("detail"), QString::fromUtf8(ex.what())},
|
|
207
|
+
});
|
|
208
|
+
} catch (...) {
|
|
209
|
+
emitHostError(
|
|
210
|
+
QStringLiteral("EmitterHandlerError"),
|
|
211
|
+
QStringLiteral("bridge"),
|
|
212
|
+
QStringLiteral("error"),
|
|
213
|
+
true,
|
|
214
|
+
QStringLiteral("Emitter handler threw while processing payload."),
|
|
215
|
+
{
|
|
216
|
+
{QStringLiteral("service"), service},
|
|
217
|
+
{QStringLiteral("member"), member},
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
void AnQstHostBridgeFacade::setInput(const QString& service, const QString& member, const QVariant& value) {
|
|
223
|
+
if (!m_inputHandler) {
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
try {
|
|
228
|
+
m_inputHandler(service, member, value);
|
|
229
|
+
} catch (const std::exception& ex) {
|
|
230
|
+
emitHostError(
|
|
231
|
+
QStringLiteral("InputHandlerError"),
|
|
232
|
+
QStringLiteral("bridge"),
|
|
233
|
+
QStringLiteral("error"),
|
|
234
|
+
true,
|
|
235
|
+
QStringLiteral("Input handler threw while processing payload."),
|
|
236
|
+
{
|
|
237
|
+
{QStringLiteral("service"), service},
|
|
238
|
+
{QStringLiteral("member"), member},
|
|
239
|
+
{QStringLiteral("detail"), QString::fromUtf8(ex.what())},
|
|
240
|
+
});
|
|
241
|
+
} catch (...) {
|
|
242
|
+
emitHostError(
|
|
243
|
+
QStringLiteral("InputHandlerError"),
|
|
244
|
+
QStringLiteral("bridge"),
|
|
245
|
+
QStringLiteral("error"),
|
|
246
|
+
true,
|
|
247
|
+
QStringLiteral("Input handler threw while processing payload."),
|
|
248
|
+
{
|
|
249
|
+
{QStringLiteral("service"), service},
|
|
250
|
+
{QStringLiteral("member"), member},
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
void AnQstHostBridgeFacade::resolveSlot(const QString& requestId, bool ok, const QVariant& payload, const QString& error) {
|
|
256
|
+
if (!m_slotInvocationResponses.contains(requestId)) {
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
SlotInvocationResponse& response = m_slotInvocationResponses[requestId];
|
|
260
|
+
response.done = true;
|
|
261
|
+
response.ok = ok;
|
|
262
|
+
response.payload = payload;
|
|
263
|
+
response.error = error;
|
|
264
|
+
emit slotInvocationResolved(requestId);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
void AnQstHostBridgeFacade::emitDrop(const QString& service, const QString& member, const QVariant& payload, double x, double y) {
|
|
268
|
+
if (m_dispatchEnabled) {
|
|
269
|
+
emit bridgeDropReceived(service, member, payload, x, y);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
void AnQstHostBridgeFacade::emitHover(const QString& service, const QString& member, const QVariant& payload, double x, double y) {
|
|
274
|
+
if (m_dispatchEnabled) {
|
|
275
|
+
emit bridgeHoverUpdated(service, member, payload, x, y);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
void AnQstHostBridgeFacade::emitHoverLeft(const QString& service, const QString& member) {
|
|
280
|
+
if (m_dispatchEnabled) {
|
|
281
|
+
emit bridgeHoverLeft(service, member);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
void AnQstHostBridgeFacade::emitHostError(
|
|
286
|
+
const QString& code,
|
|
287
|
+
const QString& category,
|
|
288
|
+
const QString& severity,
|
|
289
|
+
bool recoverable,
|
|
290
|
+
const QString& message,
|
|
291
|
+
const QVariantMap& context) {
|
|
292
|
+
QVariantMap payload;
|
|
293
|
+
payload.insert(QStringLiteral("code"), code);
|
|
294
|
+
payload.insert(QStringLiteral("category"), category);
|
|
295
|
+
payload.insert(QStringLiteral("severity"), severity);
|
|
296
|
+
payload.insert(QStringLiteral("recoverable"), recoverable);
|
|
297
|
+
payload.insert(QStringLiteral("message"), message);
|
|
298
|
+
payload.insert(QStringLiteral("context"), context);
|
|
299
|
+
payload.insert(QStringLiteral("timestamp"), QDateTime::currentDateTimeUtc().toString(Qt::ISODateWithMs));
|
|
300
|
+
emit bridgeHostError(payload);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
QString AnQstHostBridgeFacade::makeSlotKey(const QString& service, const QString& member) const {
|
|
304
|
+
return service + QStringLiteral("::") + member;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
void AnQstHostBridgeFacade::dispatchQueuedSlotInvocations(const QString& slotKey) {
|
|
308
|
+
if (!m_queuedSlotInvocations.contains(slotKey)) {
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
auto& queue = m_queuedSlotInvocations[slotKey];
|
|
313
|
+
while (!queue.isEmpty()) {
|
|
314
|
+
const PendingSlotInvocation pending = queue.dequeue();
|
|
315
|
+
emit bridgeSlotInvocationRequested(pending.requestId, pending.service, pending.member, pending.args);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
void AnQstHostBridgeFacade::emitQueuedSlotOverflowError(const QString& slotKey) {
|
|
320
|
+
emitHostError(
|
|
321
|
+
QStringLiteral("HOST_SLOT_QUEUE_OVERFLOW"),
|
|
322
|
+
QStringLiteral("runtime"),
|
|
323
|
+
QStringLiteral("error"),
|
|
324
|
+
true,
|
|
325
|
+
QStringLiteral("Slot queue exceeded capacity."),
|
|
326
|
+
{
|
|
327
|
+
{QStringLiteral("slot"), slotKey},
|
|
328
|
+
{QStringLiteral("maxQueueSize"), kMaxQueuedSlotInvocations},
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
void AnQstHostBridgeFacade::emitOutputSnapshot() {
|
|
333
|
+
for (auto it = m_outputValues.constBegin(); it != m_outputValues.constEnd(); ++it) {
|
|
334
|
+
const QString key = it.key();
|
|
335
|
+
const int splitIdx = key.indexOf(QStringLiteral("::"));
|
|
336
|
+
if (splitIdx <= 0) {
|
|
337
|
+
continue;
|
|
338
|
+
}
|
|
339
|
+
const QString service = key.left(splitIdx);
|
|
340
|
+
const QString member = key.mid(splitIdx + 2);
|
|
341
|
+
emit bridgeOutputUpdated(service, member, it.value());
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
} // namespace ANQST_WEBBASE_NAMESPACE
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include "AnQstWebBaseAbi.h"
|
|
4
|
+
|
|
5
|
+
#include <QDateTime>
|
|
6
|
+
#include <QHash>
|
|
7
|
+
#include <QMap>
|
|
8
|
+
#include <QObject>
|
|
9
|
+
#include <QQueue>
|
|
10
|
+
#include <QString>
|
|
11
|
+
#include <QVariant>
|
|
12
|
+
#include <QVariantList>
|
|
13
|
+
#include <QVariantMap>
|
|
14
|
+
#include <functional>
|
|
15
|
+
|
|
16
|
+
namespace ANQST_WEBBASE_NAMESPACE {
|
|
17
|
+
|
|
18
|
+
class AnQstHostBridgeFacade : public QObject {
|
|
19
|
+
Q_OBJECT
|
|
20
|
+
|
|
21
|
+
public:
|
|
22
|
+
static constexpr int kMaxQueuedSlotInvocations = 1024;
|
|
23
|
+
|
|
24
|
+
using CallHandler = std::function<QVariant(const QString& service, const QString& member, const QVariantList& args)>;
|
|
25
|
+
using EmitterHandler = std::function<void(const QString& service, const QString& member, const QVariantList& args)>;
|
|
26
|
+
using InputHandler = std::function<void(const QString& service, const QString& member, const QVariant&)>;
|
|
27
|
+
|
|
28
|
+
explicit AnQstHostBridgeFacade(QObject* parent = nullptr);
|
|
29
|
+
|
|
30
|
+
void setCallHandler(const CallHandler& handler);
|
|
31
|
+
void setEmitterHandler(const EmitterHandler& handler);
|
|
32
|
+
void setInputHandler(const InputHandler& handler);
|
|
33
|
+
void setOutputValue(const QString& service, const QString& member, const QVariant& value);
|
|
34
|
+
bool invokeSlot(const QString& service, const QString& member, const QVariantList& args, QVariant* result = nullptr, QString* error = nullptr);
|
|
35
|
+
void setSlotInvocationTimeoutMs(int timeoutMs);
|
|
36
|
+
int slotInvocationTimeoutMs() const;
|
|
37
|
+
|
|
38
|
+
void setDispatchEnabled(bool enabled);
|
|
39
|
+
bool dispatchEnabled() const;
|
|
40
|
+
void emitOutputSnapshot();
|
|
41
|
+
|
|
42
|
+
void emitDrop(const QString& service, const QString& member, const QVariant& payload, double x, double y);
|
|
43
|
+
void emitHover(const QString& service, const QString& member, const QVariant& payload, double x, double y);
|
|
44
|
+
void emitHoverLeft(const QString& service, const QString& member);
|
|
45
|
+
|
|
46
|
+
void registerSlot(const QString& service, const QString& member);
|
|
47
|
+
QVariant call(const QString& service, const QString& member, const QVariantList& args);
|
|
48
|
+
void emitMessage(const QString& service, const QString& member, const QVariantList& args);
|
|
49
|
+
void setInput(const QString& service, const QString& member, const QVariant& value);
|
|
50
|
+
void resolveSlot(const QString& requestId, bool ok, const QVariant& payload, const QString& error);
|
|
51
|
+
|
|
52
|
+
signals:
|
|
53
|
+
void bridgeOutputUpdated(const QString& service, const QString& member, const QVariant& value);
|
|
54
|
+
void bridgeSlotInvocationRequested(const QString& requestId, const QString& service, const QString& member, const QVariantList& args);
|
|
55
|
+
void bridgeHostError(const QVariantMap& errorPayload);
|
|
56
|
+
void slotInvocationResolved(const QString& requestId);
|
|
57
|
+
void bridgeDropReceived(const QString& service, const QString& member, const QVariant& payload, double x, double y);
|
|
58
|
+
void bridgeHoverUpdated(const QString& service, const QString& member, const QVariant& payload, double x, double y);
|
|
59
|
+
void bridgeHoverLeft(const QString& service, const QString& member);
|
|
60
|
+
|
|
61
|
+
private:
|
|
62
|
+
struct PendingSlotInvocation {
|
|
63
|
+
QString requestId;
|
|
64
|
+
QString service;
|
|
65
|
+
QString member;
|
|
66
|
+
QVariantList args;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
struct SlotInvocationResponse {
|
|
70
|
+
bool done{false};
|
|
71
|
+
bool ok{false};
|
|
72
|
+
QVariant payload;
|
|
73
|
+
QString error;
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
void emitHostError(
|
|
77
|
+
const QString& code,
|
|
78
|
+
const QString& category,
|
|
79
|
+
const QString& severity,
|
|
80
|
+
bool recoverable,
|
|
81
|
+
const QString& message,
|
|
82
|
+
const QVariantMap& context = QVariantMap());
|
|
83
|
+
QString makeSlotKey(const QString& service, const QString& member) const;
|
|
84
|
+
void dispatchQueuedSlotInvocations(const QString& slotKey);
|
|
85
|
+
void emitQueuedSlotOverflowError(const QString& slotKey);
|
|
86
|
+
|
|
87
|
+
bool m_dispatchEnabled;
|
|
88
|
+
quint64 m_slotRequestCounter;
|
|
89
|
+
CallHandler m_callHandler;
|
|
90
|
+
EmitterHandler m_emitterHandler;
|
|
91
|
+
InputHandler m_inputHandler;
|
|
92
|
+
QHash<QString, bool> m_registeredSlots;
|
|
93
|
+
QHash<QString, QQueue<PendingSlotInvocation>> m_queuedSlotInvocations;
|
|
94
|
+
QHash<QString, SlotInvocationResponse> m_slotInvocationResponses;
|
|
95
|
+
QHash<QString, QVariant> m_outputValues;
|
|
96
|
+
int m_slotInvocationTimeoutMs;
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
} // namespace ANQST_WEBBASE_NAMESPACE
|