1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
|
// Copyright (C) 2021 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QREMOTEOBJECTSQML_P_H
#define QREMOTEOBJECTSQML_P_H
#include <QtRemoteObjects/qremoteobjectnode.h>
#include <QtRemoteObjects/qremoteobjectpendingcall.h>
#include <QtRemoteObjects/qremoteobjectsettingsstore.h>
#include <QtCore/qtimer.h>
#include <QtQml/QJSValue>
#include <QtQml/qqml.h>
#include <QtQml/qqmlengine.h>
#include <QtQml/qqmlinfo.h>
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
QT_BEGIN_NAMESPACE
struct QtQmlRemoteObjectsResponse
{
QJSValue promise;
QTimer *timer;
};
// documentation updates for this class can be made in remoteobjects-qml.qdoc
class QtQmlRemoteObjects : public QObject
{
Q_OBJECT
QML_NAMED_ELEMENT(QtRemoteObjects)
QML_SINGLETON
QML_ADDED_IN_VERSION(5, 14)
public:
~QtQmlRemoteObjects()
{
auto i = m_callbacks.begin();
while (i != m_callbacks.end()) {
delete i.key();
delete i.value().timer;
i = m_callbacks.erase(i);
}
}
Q_INVOKABLE QJSValue watch(const QRemoteObjectPendingCall &reply, int timeout = 30000)
{
if (m_accessiblePromise.isUndefined())
m_accessiblePromise = qmlEngine(this)->evaluate(QLatin1String(
"(function() { var obj = {}; obj.promise = new Promise(function(resolve, "
"reject) { obj.resolve = resolve; obj.reject = reject; }); return obj; })"));
QRemoteObjectPendingCallWatcher *watcher = new QRemoteObjectPendingCallWatcher(reply);
QJSValue promise = m_accessiblePromise.call();
QtQmlRemoteObjectsResponse response;
response.promise = promise;
response.timer = new QTimer();
response.timer->setSingleShot(true);
m_callbacks.insert(watcher, response);
// handle timeout
connect(response.timer, &QTimer::timeout, this, [this, watcher]() {
auto i = m_callbacks.find(watcher);
if (i == m_callbacks.end()) {
qmlWarning(this) << "could not find callback for watcher.";
return;
}
QJSValue v(QLatin1String("timeout"));
i.value().promise.property(QLatin1String("reject")).call(QJSValueList() << v);
delete i.key();
delete i.value().timer;
m_callbacks.erase(i);
});
// handle success
connect(watcher, &QRemoteObjectPendingCallWatcher::finished, this,
[this](QRemoteObjectPendingCallWatcher *self) {
auto i = m_callbacks.find(self);
if (i == m_callbacks.end()) {
qmlWarning(this) << "could not find callback for watcher.";
return;
}
QJSValue v = qmlEngine(this)->toScriptValue(self->returnValue());
i.value().promise.property(QLatin1String("resolve")).call(QJSValueList() << v);
delete i.key();
delete i.value().timer;
m_callbacks.erase(i);
});
response.timer->start(timeout);
return promise.property(QLatin1String("promise"));
}
private:
QHash<QRemoteObjectPendingCallWatcher *, QtQmlRemoteObjectsResponse> m_callbacks;
QJSValue m_accessiblePromise;
};
struct QRemoteObjectNodeForeign
{
Q_GADGET
QML_FOREIGN(QRemoteObjectNode)
QML_NAMED_ELEMENT(Node)
QML_ADDED_IN_VERSION(5, 12)
};
struct QRemoteObjectSettingsStoreForeign
{
Q_GADGET
QML_FOREIGN(QRemoteObjectSettingsStore)
QML_NAMED_ELEMENT(SettingsStore)
QML_ADDED_IN_VERSION(5, 12)
};
struct QRemoteObjectHostForeign
{
Q_GADGET
QML_FOREIGN(QRemoteObjectHost)
QML_NAMED_ELEMENT(Host)
QML_ADDED_IN_VERSION(5, 15)
};
struct QRemoteObjectAbstractPersistedStoreForeign
{
Q_GADGET
QML_FOREIGN(QRemoteObjectAbstractPersistedStore)
QML_NAMED_ELEMENT(PersistedStore)
QML_UNCREATABLE("QRemoteObjectAbstractPersistedStore is Abstract")
QML_ADDED_IN_VERSION(5, 12)
};
QT_END_NAMESPACE
#endif // QREMOTEOBJECTSQML_P_H
|