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
qohosjstools.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/qohoscommon_p.h>
6#include <QtCore/private/qohoslogger_p.h>
7#include <iterator>
8#include <vector>
9
10QT_BEGIN_NAMESPACE
11
12std::shared_ptr<void> registerQOhosOnOffMethodsBasedEventHandler(
13 QNapi::Object eventSourceObject, const std::string &eventTypeName,
14 QNapi::CallbackFuncWrapper eventHandler, QOhosOnOffMethodsBasedEventHandlerOptions options)
15{
16 struct Context
17 {
18 std::function<QNapi::Value(const QNapi::CallbackInfo &)> eventHandler;
19 std::function<bool(QNapi::Object)> eventSourceAliveCheckFunc;
20 QNapi::Reference<QNapi::Value> optExtraOnArg;
21 QNapi::Reference<QNapi::Value> optExtraOffArg;
22 };
23
24 auto env = eventSourceObject.Env();
25
26 auto sharedContext = QtOhos::moveToSharedPtr(
27 Context{
28 .eventHandler = std::move(eventHandler.callbackFunc()),
29 .eventSourceAliveCheckFunc = options.optEventSourceAliveCheckFunc
30 ? std::move(options.optEventSourceAliveCheckFunc)
31 : [](QNapi::Object) {
32 return true;
33 },
34 .optExtraOnArg = options.extraOnArg.has_value()
35 ? QNapi::Reference<>::makePersistentFrom(
36 options.extraOnArg.value().mapToValue(env))
37 : QNapi::Reference<>::makeEmpty(),
38 .optExtraOffArg = options.extraOffArg.has_value()
39 ? QNapi::Reference<>::makePersistentFrom(
40 options.extraOffArg.value().mapToValue(env))
41 : QNapi::Reference<>::makeEmpty(),
42 });
43
44 auto jsEventHandlerRef = QtOhos::moveToSharedPtr(
45 QNapi::Reference<>::makePersistentFrom(
46 QNapi::Function::New(
47 eventSourceObject.Env(),
48 [eventTypeName, weakContext = QtOhos::makeWeakPtr(sharedContext)](const QNapi::CallbackInfo &cbInfo) {
49 auto sharedContext = weakContext.lock();
50 if (sharedContext) {
51 return sharedContext->eventHandler(cbInfo);
52 } else {
53 qOhosPrintfWarning(
54 "%s: got unexpected '%s' event callback call for detached handler",
55 Q_FUNC_INFO, eventTypeName.c_str());
56 return cbInfo.Env().Undefined();
57 }
58 })));
59
60 std::vector<QNapi::ValueWrapper> onCallArgs;
61 onCallArgs.push_back(eventTypeName);
62 if (!sharedContext->optExtraOnArg.IsEmpty())
63 onCallArgs.push_back(sharedContext->optExtraOnArg.Value());
64 onCallArgs.push_back(jsEventHandlerRef->Value());
65 bool onCallSuccessful;
66 try {
67 eventSourceObject.eval("on(*)", onCallArgs);
68 onCallSuccessful = true;
69 } catch (const Napi::Error &error) {
70 onCallSuccessful = false;
71 if (options.optOnCallExceptionHandler) {
72 options.optOnCallExceptionHandler(error);
73 } else {
74 throw;
75 }
76 }
77
78 if (!onCallSuccessful)
79 return nullptr;
80
81 auto eventSourceWeakRef = QtOhos::moveToSharedPtr(Napi::Weak(eventSourceObject));
82
83 return QtOhos::makeDestroyNotifier(
84 [eventSourceWeakRef, eventTypeName, sharedContext, jsEventHandlerRef]() {
85 auto eventSourceValue = eventSourceWeakRef->Value();
86 if (eventSourceValue.IsObject()) {
87 auto eventSourceObject = QNapi::checkedCast<QNapi::Object>(eventSourceValue);
88 if (sharedContext->eventSourceAliveCheckFunc(eventSourceObject)) {
89 try {
90 std::vector<QNapi::ValueWrapper> offCallArgs;
91 offCallArgs.push_back(eventTypeName);
92 if (!sharedContext->optExtraOffArg.IsEmpty())
93 offCallArgs.push_back(sharedContext->optExtraOffArg.Value());
94 offCallArgs.push_back(jsEventHandlerRef->Value());
95 eventSourceObject.eval("off(*)", offCallArgs);
96 } catch (const Napi::Error &e) {
97 qOhosPrintfError(
98 "%s: got exception from off(%s, ...) call (ignoring): %s",
99 Q_FUNC_INFO, eventTypeName.c_str(), e.what());
100 }
101 } else {
102 qOhosPrintfDebug(
103 "%s: not calling off(%s, ...), event source 'considered' not alive",
104 Q_FUNC_INFO, eventTypeName.c_str());
105 }
106 } else {
107 qOhosPrintfDebug(
108 "%s: not calling off(%s, ...), event source not alive",
109 Q_FUNC_INFO, eventTypeName.c_str());
110 }
111 });
112}
113
115 QOhosJsState &jsState,
116 std::vector<std::pair<std::string, QNapi::CallbackFuncWrapper>> environmentCallbackMethods)
117{
118 auto optQAbility = jsState.defaultQAbility();
119 if (!optQAbility.has_value())
120 return {};
121
122 auto environmentCallback = QNapi::makeObject(
123 jsState.env(),
124 std::vector<std::pair<std::string, QNapi::ValueWrapper>>(
125 std::make_move_iterator(environmentCallbackMethods.begin()),
126 std::make_move_iterator(environmentCallbackMethods.end())));
127
128 auto appContextRefPtr = QtOhos::moveToSharedPtr(
129 QNapi::Reference<>::makePersistentFrom(
130 optQAbility->eval<QNapi::Object>("context.getApplicationContext()")));
131
132 double environmentCallbackId = appContextRefPtr->eval<QNapi::Number>(
133 "on(*)",
134 {"environment", environmentCallback});
135
136 return std::shared_ptr<void>(
137 nullptr,
138 [environmentCallbackId, appContextRefPtr](auto) {
139 QOhosJsThreadGateway::runAndWait(
140 [&](QOhosJsState &) {
141 auto appContextRef = std::move(*appContextRefPtr);
142 appContextRef.eval(
143 "off(*)",
144 {"environment", environmentCallbackId});
145 },
146 Q_FUNC_INFO);
147 });
148}
149
150QT_END_NAMESPACE
std::shared_ptr< void > registerOhosAppContextEnvironmentCallback(QOhosJsState &jsState, std::vector< std::pair< std::string, QNapi::CallbackFuncWrapper > > environmentCallbackMethods)