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
qohosjsutils.cpp
Go to the documentation of this file.
1// Copyright (C) 2025 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
4#include "qohosjsutils.h"
5#include <QtCore/private/qohoscommon_p.h>
6#include <qohosutils.h>
7#include <utility>
8
9using namespace std::chrono_literals;
10
11QT_BEGIN_NAMESPACE
12
13namespace QtOhos {
14
15std::shared_ptr<void> startDelayedJsThreadTask(
16 JsState &jsState, std::function<void(JsState &)> task,
17 std::chrono::milliseconds delay)
18{
19 struct Context
20 {
21 std::function<void(JsState &)> task;
22 QOhosOptional<int> timerId;
23 };
24
25 auto context = std::make_shared<Context>();
26 context->task = std::move(task);
27
28 int timerId = jsState.eval<QNapi::Number>(
29 "Global.setTimeout(*)",
30 {
31 [context](const CallbackInfo &cbInfo) {
32 if (context->task) {
33 auto task = std::exchange(context->task, nullptr);
34 context->timerId.reset();
35 task(cbInfo.jsState());
36 }
37 },
38 std::max(delay, std::chrono::milliseconds(0)).count(),
39 });
40 context->timerId = timerId;
41
42 return QtOhos::makeDestroyNotifier(
43 [context]() {
44 if (context->timerId.has_value()) {
45 runInJsThreadAndWait(
46 [&](JsState &jsState) {
47 jsState.eval("Global.clearTimeout(*)", {context->timerId.value()});
48 },
49 Q_FUNC_INFO);
50 context->task = nullptr;
51 context->timerId.reset();
52 }
53 });
54}
55
56int setJsTimeout(
57 JsState &jsState, std::function<void(const CallbackInfo &)> timeoutFunc,
58 std::chrono::milliseconds delay)
59{
60 int timerId = jsState.eval<QNapi::Number>(
61 "Global.setTimeout(*)", {std::move(timeoutFunc), delay.count()});
62 return timerId;
63}
64
65void clearJsTimeout(JsState &jsState, int timerId)
66{
67 jsState.eval("Global.clearTimeout(*)", {timerId});
68}
69
70QNapi::Promise makeResolvedPromise(QNapi::Value valueForResolve)
71{
72 auto promiseDeferred = QNapi::Promise::Deferred::New(valueForResolve.Env());
73 promiseDeferred.Resolve(valueForResolve);
74 return promiseDeferred.Promise();
75}
76
77QOhosOptional<std::uint32_t> tryGetCodeFromJsBusinessError(const Napi::Error &error)
78{
79 if (!error.Value().IsObject())
80 return {};
81
82 auto errorObject = QNapi::checkedCast<QNapi::Object>(error.Value());
83 auto optErrorCode = QNapi::getOptionalPropOrEmpty<QNapi::Number>(errorObject, "code");
84
85 return !optErrorCode.IsEmpty()
86 ? makeQOhosOptional(optErrorCode.Uint32Value())
88}
89
90void rethrowUnlessJsBusinessErrorIs(
91 const Napi::Error &error, std::uint32_t suppressedErrorCode, const char *callerContextName)
92{
93 if (tryGetCodeFromJsBusinessError(error) != suppressedErrorCode)
94 throw;
95
96 qOhosPrintfWarning(
97 "%s: ignored expected JS business error %u",
98 callerContextName, suppressedErrorCode);
99}
100
101bool runIgnoringJsBusinessError(
102 JsState &, std::uint32_t suppressedErrorCode, const char *callerContextName,
103 const std::function<void()> &action)
104{
105 try {
106 action();
107 return true;
108 } catch (const Napi::Error &error) {
109 rethrowUnlessJsBusinessErrorIs(error, suppressedErrorCode, callerContextName);
110 return false;
111 }
112}
113
114}
115
116QT_END_NAMESPACE
std::nullopt_t makeEmptyQOhosOptional()