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