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
qharmonyjsobjectref.cpp
Go to the documentation of this file.
1// Copyright (C) 2026 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
5#include <QtCore/private/qcore_ohos_p.h>
6#include <QtCore/private/qohoslogger_p.h>
7
8QT_BEGIN_NAMESPACE
9
10namespace {
11
17
18std::int64_t jsObjectIdentity(QOhosJsState &jsState, QNapi::Object object)
19{
20 auto &registry = jsState.getAttachedObjectWithLazyCreate<JsObjectIdentityRegistry>();
21 if (registry.weakMap.IsEmpty())
22 registry.weakMap = QNapi::Reference<>::makePersistentFrom(
23 QNapi::makeNewInstance(Napi::Env(jsState.env()).Global(), "WeakMap"));
24
25 auto weakMap = registry.weakMap.Value();
26 auto existingId = weakMap.eval("get(*)", {object});
27 if (existingId.IsNumber())
28 return QNapi::checkedCast<QNapi::Number>(existingId);
29
30 const auto id = registry.nextId++;
31 weakMap.eval("set(*)", {object, id});
32 return id;
33}
34
35}
36
37class QHarmonyJsObjectRef::Private
38{
39public:
40 Private(QNapi::Reference<QNapi::Object> reference, std::int64_t identity)
41 : reference(std::move(reference))
42 , identity(identity)
43 {
44 }
45
46 QNapi::Reference<QNapi::Object> reference;
47 std::int64_t identity;
48};
49
50/*!
51 \class QHarmonyJsObjectRef
52 \inmodule QtCore
53 \brief The QHarmonyJsObjectRef class keeps a JS object of a HarmonyOS
54 application alive and lets other threads hold a reference to it.
55
56 \reentrant
57
58 A \c napi_value is valid only on the JS thread, and only until the task
59 or callback that obtained it returns. A QHarmonyJsObjectRef holds a
60 strong reference to the object instead. You can copy, store, and compare
61 it on any thread. On the JS thread, value() returns the object again.
62
63 The reference is released when the last copy is destroyed, on whichever
64 thread that happens. The release itself runs asynchronously on the JS
65 thread, so the JS object may outlive the last copy for a short time.
66
67 Two references compare equal when they refer to the same JS object, even
68 if they were created independently.
69
70 \sa {Qt for HarmonyOS Platform API}
71*/
72
73/*!
74 Constructs a null reference.
75*/
76QHarmonyJsObjectRef::QHarmonyJsObjectRef() = default;
77
78/*!
79 Constructs a copy of \a other, which refers to the same JS object.
80*/
81QHarmonyJsObjectRef::QHarmonyJsObjectRef(const QHarmonyJsObjectRef &other) = default;
82
83/*!
84 Move-constructs a reference from \a other. \a other becomes a null
85 reference.
86*/
87QHarmonyJsObjectRef::QHarmonyJsObjectRef(QHarmonyJsObjectRef &&other) noexcept = default;
88
89/*!
90 Assigns \a other to this reference. This reference then refers to the
91 same JS object as \a other.
92*/
93QHarmonyJsObjectRef &QHarmonyJsObjectRef::operator=(const QHarmonyJsObjectRef &other) = default;
94
95/*!
96 Move-assigns \a other to this reference. \a other becomes a null
97 reference.
98*/
99QHarmonyJsObjectRef &QHarmonyJsObjectRef::operator=(QHarmonyJsObjectRef &&other) noexcept = default;
100
101/*!
102 Destroys the reference. If this is the last copy, the JS object is
103 released asynchronously on the JS thread.
104*/
105QHarmonyJsObjectRef::~QHarmonyJsObjectRef() = default;
106
107/*!
108 Returns a reference to the JS object \a value, obtained in \a jsContext
109 on the JS thread. Returns a null reference if \a value is not a JS
110 object, that is, if it is \nullptr, JS \c null, \c undefined, or a
111 primitive. Also returns a null reference if creating the reference
112 fails. In that case, the error is logged and no exception is left
113 pending.
114*/
115QHarmonyJsObjectRef QHarmonyJsObjectRef::fromValue(QHarmonyJsContext &jsContext, napi_value value)
116{
117 QHarmonyJsObjectRef ref;
118 if (!value)
119 return ref;
120
121 Napi::Value napiValue(jsContext.env(), value);
122 if (!napiValue.IsObject())
123 return ref;
124
125 auto object = QNapi::checkedCast<QNapi::Object>(napiValue);
126 try {
127 ref.d = QtOhos::makeProxyWithAsyncJsThreadDeleter(
128 std::make_shared<Private>(
129 QNapi::Reference<>::makePersistentFrom(object),
130 jsObjectIdentity(QOhosJsThreadOps::instance().jsState(), object)));
131 } catch (const Napi::Error &error) {
132 qOhosPrintfWarning("%s: creating the reference failed: %s", Q_FUNC_INFO, error.what());
133 }
134
135 return ref;
136}
137
138/*!
139 Returns the referenced JS object for use in \a jsContext on the JS
140 thread, or \nullptr for a null reference. The returned value is valid
141 until the current task or callback returns.
142*/
143napi_value QHarmonyJsObjectRef::value(QHarmonyJsContext &jsContext) const
144{
145 Q_UNUSED(jsContext);
146 return d ? d->reference.Value() : QNapi::Object();
147}
148
149/*!
150 Returns \c true if this reference does not refer to any JS object. You
151 can call this function on any thread.
152*/
153bool QHarmonyJsObjectRef::isNull() const
154{
155 return !d;
156}
157
158std::int64_t QHarmonyJsObjectRef::identity() const noexcept
159{
160 return d ? d->identity : 0;
161}
162
163/*!
164 \fn bool QHarmonyJsObjectRef::operator==(const QHarmonyJsObjectRef &lhs, const QHarmonyJsObjectRef &rhs)
165 \fn bool QHarmonyJsObjectRef::operator!=(const QHarmonyJsObjectRef &lhs, const QHarmonyJsObjectRef &rhs)
166
167 Returns whether \a lhs and \a rhs refer to the same JS object. Two null
168 references are equal. You can call these operators on any thread.
169*/
170bool comparesEqual(const QHarmonyJsObjectRef &lhs, const QHarmonyJsObjectRef &rhs) noexcept
171{
172 return lhs.identity() == rhs.identity();
173}
174
175/*!
176 \relates QHarmonyJsObjectRef
177
178 Returns the hash value for \a key, using \a seed to seed the
179 calculation. References that compare equal have the same hash value. You
180 can call this function on any thread.
181*/
182size_t qHash(const QHarmonyJsObjectRef &key, size_t seed) noexcept
183{
184 return qHash(key.identity(), seed);
185}
186
187QT_END_NAMESPACE
std::int64_t jsObjectIdentity(QOhosJsState &jsState, QNapi::Object object)
bool comparesEqual(const QFileInfo &lhs, const QFileInfo &rhs)
constexpr size_t qHash(const QSize &s, size_t seed=0) noexcept
Definition qsize.h:192