react-native-windows 0.69.6 → 0.69.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Microsoft.ReactNative/JSDispatcherWriter.cpp +60 -22
- package/Microsoft.ReactNative/JSDispatcherWriter.h +5 -3
- package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp +3 -1
- package/Microsoft.ReactNative/TurboModulesProvider.cpp +146 -84
- package/Microsoft.ReactNative/TurboModulesProvider.h +5 -0
- package/Microsoft.ReactNative/Views/ViewManagerBase.cpp +4 -2
- package/Microsoft.ReactNative.Cxx/JSI/LongLivedJsiValue.h +84 -0
- package/Microsoft.ReactNative.Cxx/Microsoft.ReactNative.Cxx.vcxitems +1 -0
- package/Microsoft.ReactNative.Cxx/Microsoft.ReactNative.Cxx.vcxitems.filters +3 -0
- package/Mso/src/dispatchQueue/uiScheduler_winrt.cpp +6 -1
- package/PropertySheets/Generated/PackageVersion.g.props +2 -2
- package/Shared/InstanceManager.cpp +29 -0
- package/Shared/InstanceManager.h +14 -0
- package/Shared/OInstance.cpp +13 -1
- package/Shared/OInstance.h +4 -13
- package/Shared/Threading/BatchingQueueThread.cpp +18 -12
- package/package.json +5 -5
|
@@ -8,35 +8,57 @@
|
|
|
8
8
|
|
|
9
9
|
namespace winrt::Microsoft::ReactNative {
|
|
10
10
|
|
|
11
|
+
// Special IJSValueWriter that does nothing.
|
|
12
|
+
// We use it instead of JsiWriter when JSI runtime is not available anymore.
|
|
13
|
+
struct JSNoopWriter : winrt::implements<JSNoopWriter, IJSValueWriter> {
|
|
14
|
+
public: // IJSValueWriter
|
|
15
|
+
void WriteNull() noexcept;
|
|
16
|
+
void WriteBoolean(bool value) noexcept;
|
|
17
|
+
void WriteInt64(int64_t value) noexcept;
|
|
18
|
+
void WriteDouble(double value) noexcept;
|
|
19
|
+
void WriteString(const winrt::hstring &value) noexcept;
|
|
20
|
+
void WriteObjectBegin() noexcept;
|
|
21
|
+
void WritePropertyName(const winrt::hstring &name) noexcept;
|
|
22
|
+
void WriteObjectEnd() noexcept;
|
|
23
|
+
void WriteArrayBegin() noexcept;
|
|
24
|
+
void WriteArrayEnd() noexcept;
|
|
25
|
+
};
|
|
26
|
+
|
|
11
27
|
//===========================================================================
|
|
12
28
|
// JSDispatcherWriter implementation
|
|
13
29
|
//===========================================================================
|
|
14
30
|
|
|
15
31
|
JSDispatcherWriter::JSDispatcherWriter(
|
|
16
32
|
IReactDispatcher const &jsDispatcher,
|
|
17
|
-
|
|
18
|
-
: m_jsDispatcher(jsDispatcher),
|
|
33
|
+
std::weak_ptr<LongLivedJsiRuntime> jsiRuntimeHolder) noexcept
|
|
34
|
+
: m_jsDispatcher(jsDispatcher), m_jsiRuntimeHolder(std::move(jsiRuntimeHolder)) {}
|
|
19
35
|
|
|
20
36
|
void JSDispatcherWriter::WithResultArgs(
|
|
21
37
|
Mso::Functor<void(facebook::jsi::Runtime &rt, facebook::jsi::Value const *args, size_t argCount)>
|
|
22
38
|
handler) noexcept {
|
|
23
39
|
if (m_jsDispatcher.HasThreadAccess()) {
|
|
24
40
|
VerifyElseCrash(!m_dynamicWriter);
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
41
|
+
if (auto jsiRuntimeHolder = m_jsiRuntimeHolder.lock()) {
|
|
42
|
+
const facebook::jsi::Value *args{nullptr};
|
|
43
|
+
size_t argCount{0};
|
|
44
|
+
m_jsiWriter->AccessResultAsArgs(args, argCount);
|
|
45
|
+
handler(jsiRuntimeHolder->Runtime(), args, argCount);
|
|
46
|
+
m_jsiWriter = nullptr;
|
|
47
|
+
}
|
|
29
48
|
} else {
|
|
30
49
|
VerifyElseCrash(!m_jsiWriter);
|
|
31
50
|
folly::dynamic dynValue = m_dynamicWriter->TakeValue();
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
51
|
+
VerifyElseCrash(dynValue.isArray());
|
|
52
|
+
m_jsDispatcher.Post([handler, dynValue = std::move(dynValue), weakJsiRuntimeHolder = m_jsiRuntimeHolder]() {
|
|
53
|
+
if (auto jsiRuntimeHolder = weakJsiRuntimeHolder.lock()) {
|
|
54
|
+
std::vector<facebook::jsi::Value> args;
|
|
55
|
+
args.reserve(dynValue.size());
|
|
56
|
+
auto &runtime = jsiRuntimeHolder->Runtime();
|
|
57
|
+
for (auto const &item : dynValue) {
|
|
58
|
+
args.emplace_back(facebook::jsi::valueFromDynamic(runtime, item));
|
|
59
|
+
}
|
|
60
|
+
handler(runtime, args.data(), args.size());
|
|
38
61
|
}
|
|
39
|
-
handler(runtime, args.data(), args.size());
|
|
40
62
|
});
|
|
41
63
|
}
|
|
42
64
|
}
|
|
@@ -82,20 +104,36 @@ void JSDispatcherWriter::WriteArrayEnd() noexcept {
|
|
|
82
104
|
}
|
|
83
105
|
|
|
84
106
|
IJSValueWriter JSDispatcherWriter::GetWriter() noexcept {
|
|
85
|
-
if (
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
107
|
+
if (!m_writer) {
|
|
108
|
+
if (m_jsDispatcher.HasThreadAccess()) {
|
|
109
|
+
if (auto jsiRuntimeHolder = m_jsiRuntimeHolder.lock()) {
|
|
110
|
+
m_jsiWriter = winrt::make_self<JsiWriter>(jsiRuntimeHolder->Runtime());
|
|
111
|
+
m_writer = m_jsiWriter.as<IJSValueWriter>();
|
|
112
|
+
} else {
|
|
113
|
+
m_writer = winrt::make<JSNoopWriter>();
|
|
114
|
+
}
|
|
115
|
+
} else {
|
|
94
116
|
m_dynamicWriter = winrt::make_self<DynamicWriter>();
|
|
95
117
|
m_writer = m_dynamicWriter.as<IJSValueWriter>();
|
|
96
118
|
}
|
|
97
119
|
}
|
|
120
|
+
Debug(VerifyElseCrash(m_dynamicWriter != nullptr || m_jsDispatcher.HasThreadAccess()));
|
|
98
121
|
return m_writer;
|
|
99
122
|
}
|
|
100
123
|
|
|
124
|
+
//===========================================================================
|
|
125
|
+
// JSNoopWriter implementation
|
|
126
|
+
//===========================================================================
|
|
127
|
+
|
|
128
|
+
void JSNoopWriter::WriteNull() noexcept {}
|
|
129
|
+
void JSNoopWriter::WriteBoolean(bool /*value*/) noexcept {}
|
|
130
|
+
void JSNoopWriter::WriteInt64(int64_t /*value*/) noexcept {}
|
|
131
|
+
void JSNoopWriter::WriteDouble(double /*value*/) noexcept {}
|
|
132
|
+
void JSNoopWriter::WriteString(const winrt::hstring & /*value*/) noexcept {}
|
|
133
|
+
void JSNoopWriter::WriteObjectBegin() noexcept {}
|
|
134
|
+
void JSNoopWriter::WritePropertyName(const winrt::hstring & /*name*/) noexcept {}
|
|
135
|
+
void JSNoopWriter::WriteObjectEnd() noexcept {}
|
|
136
|
+
void JSNoopWriter::WriteArrayBegin() noexcept {}
|
|
137
|
+
void JSNoopWriter::WriteArrayEnd() noexcept {}
|
|
138
|
+
|
|
101
139
|
} // namespace winrt::Microsoft::ReactNative
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
// Licensed under the MIT License.
|
|
3
3
|
#pragma once
|
|
4
4
|
|
|
5
|
+
#include <JSI/LongLivedJsiValue.h>
|
|
5
6
|
#include <functional/functor.h>
|
|
6
7
|
#include "DynamicWriter.h"
|
|
7
8
|
#include "JsiWriter.h"
|
|
8
|
-
#include "folly/dynamic.h"
|
|
9
9
|
#include "winrt/Microsoft.ReactNative.h"
|
|
10
10
|
|
|
11
11
|
namespace winrt::Microsoft::ReactNative {
|
|
@@ -14,7 +14,9 @@ namespace winrt::Microsoft::ReactNative {
|
|
|
14
14
|
// In case if writing is done outside of JSDispatcher, it uses DynamicWriter to create
|
|
15
15
|
// folly::dynamic which then is written to JsiWriter in JSDispatcher.
|
|
16
16
|
struct JSDispatcherWriter : winrt::implements<JSDispatcherWriter, IJSValueWriter> {
|
|
17
|
-
JSDispatcherWriter(
|
|
17
|
+
JSDispatcherWriter(
|
|
18
|
+
IReactDispatcher const &jsDispatcher,
|
|
19
|
+
std::weak_ptr<LongLivedJsiRuntime> jsiRuntimeHolder) noexcept;
|
|
18
20
|
void WithResultArgs(Mso::Functor<void(facebook::jsi::Runtime &rt, facebook::jsi::Value const *args, size_t argCount)>
|
|
19
21
|
handler) noexcept;
|
|
20
22
|
|
|
@@ -35,7 +37,7 @@ struct JSDispatcherWriter : winrt::implements<JSDispatcherWriter, IJSValueWriter
|
|
|
35
37
|
|
|
36
38
|
private:
|
|
37
39
|
IReactDispatcher m_jsDispatcher;
|
|
38
|
-
|
|
40
|
+
std::weak_ptr<LongLivedJsiRuntime> m_jsiRuntimeHolder;
|
|
39
41
|
winrt::com_ptr<DynamicWriter> m_dynamicWriter;
|
|
40
42
|
winrt::com_ptr<JsiWriter> m_jsiWriter;
|
|
41
43
|
IJSValueWriter m_writer;
|
|
@@ -132,7 +132,8 @@ struct BridgeUIBatchInstanceCallback final : public facebook::react::InstanceCal
|
|
|
132
132
|
virtual ~BridgeUIBatchInstanceCallback() = default;
|
|
133
133
|
void onBatchComplete() override {
|
|
134
134
|
if (auto instance = m_wkInstance.GetStrongPtr()) {
|
|
135
|
-
|
|
135
|
+
auto state = instance->State();
|
|
136
|
+
if (state != ReactInstanceState::HasError && state != ReactInstanceState::Unloaded) {
|
|
136
137
|
if (instance->UseWebDebugger()) {
|
|
137
138
|
// While using a CxxModule for UIManager (which we do when running under webdebugger)
|
|
138
139
|
// We need to post the batch complete to the NativeQueue to ensure that the UIManager
|
|
@@ -510,6 +511,7 @@ void ReactInstanceWin::Initialize() noexcept {
|
|
|
510
511
|
std::move(bundleRootPath), // bundleRootPath
|
|
511
512
|
std::move(cxxModules),
|
|
512
513
|
m_options.TurboModuleProvider,
|
|
514
|
+
m_options.TurboModuleProvider->LongLivedObjectCollection(),
|
|
513
515
|
std::make_unique<BridgeUIBatchInstanceCallback>(weakThis),
|
|
514
516
|
m_jsMessageThread.Load(),
|
|
515
517
|
m_nativeMessageThread.Load(),
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// Copyright (c) Microsoft Corporation.
|
|
2
2
|
// Licensed under the MIT License.
|
|
3
|
+
//
|
|
3
4
|
// IMPORTANT: Before updating this file
|
|
4
5
|
// please read react-native-windows repo:
|
|
5
6
|
// vnext/Microsoft.ReactNative.Cxx/README.md
|
|
@@ -21,6 +22,7 @@ using namespace winrt;
|
|
|
21
22
|
using namespace Windows::Foundation;
|
|
22
23
|
|
|
23
24
|
namespace winrt::Microsoft::ReactNative {
|
|
25
|
+
|
|
24
26
|
/*-------------------------------------------------------------------------------
|
|
25
27
|
TurboModuleBuilder
|
|
26
28
|
-------------------------------------------------------------------------------*/
|
|
@@ -56,10 +58,17 @@ struct TurboModuleBuilder : winrt::implements<TurboModuleBuilder, IReactModuleBu
|
|
|
56
58
|
}
|
|
57
59
|
|
|
58
60
|
public:
|
|
59
|
-
std::unordered_map<std::string, TurboModuleMethodInfo>
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
61
|
+
const std::unordered_map<std::string, TurboModuleMethodInfo> &Methods() const noexcept {
|
|
62
|
+
return m_methods;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const std::unordered_map<std::string, SyncMethodDelegate> &SyncMethods() const noexcept {
|
|
66
|
+
return m_syncMethods;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const std::vector<ConstantProviderDelegate> &ConstantProviders() const noexcept {
|
|
70
|
+
return m_constantProviders;
|
|
71
|
+
}
|
|
63
72
|
|
|
64
73
|
private:
|
|
65
74
|
void EnsureMemberNotSet(const std::string &key, bool checkingMethod) noexcept {
|
|
@@ -72,6 +81,10 @@ struct TurboModuleBuilder : winrt::implements<TurboModuleBuilder, IReactModuleBu
|
|
|
72
81
|
|
|
73
82
|
private:
|
|
74
83
|
IReactContext m_reactContext;
|
|
84
|
+
std::unordered_map<std::string, TurboModuleMethodInfo> m_methods;
|
|
85
|
+
std::unordered_map<std::string, SyncMethodDelegate> m_syncMethods;
|
|
86
|
+
std::vector<ConstantProviderDelegate> m_constantProviders;
|
|
87
|
+
bool m_constantsEvaluated{false};
|
|
75
88
|
};
|
|
76
89
|
|
|
77
90
|
/*-------------------------------------------------------------------------------
|
|
@@ -84,11 +97,13 @@ class TurboModuleImpl : public facebook::react::TurboModule {
|
|
|
84
97
|
const IReactContext &reactContext,
|
|
85
98
|
const std::string &name,
|
|
86
99
|
const std::shared_ptr<facebook::react::CallInvoker> &jsInvoker,
|
|
100
|
+
std::weak_ptr<facebook::react::LongLivedObjectCollection> longLivedObjectCollection,
|
|
87
101
|
const ReactModuleProvider &reactModuleProvider)
|
|
88
102
|
: facebook::react::TurboModule(name, jsInvoker),
|
|
89
103
|
m_reactContext(reactContext),
|
|
90
|
-
|
|
91
|
-
|
|
104
|
+
m_longLivedObjectCollection(std::move(longLivedObjectCollection)),
|
|
105
|
+
m_moduleBuilder(winrt::make_self<TurboModuleBuilder>(reactContext)),
|
|
106
|
+
m_providedModule(reactModuleProvider(m_moduleBuilder.as<IReactModuleBuilder>())) {
|
|
92
107
|
if (auto hostObject = m_providedModule.try_as<IJsiHostObject>()) {
|
|
93
108
|
m_hostObjectWrapper = std::make_shared<implementation::HostObjectWrapper>(hostObject);
|
|
94
109
|
}
|
|
@@ -99,12 +114,23 @@ class TurboModuleImpl : public facebook::react::TurboModule {
|
|
|
99
114
|
return m_hostObjectWrapper->getPropertyNames(rt);
|
|
100
115
|
}
|
|
101
116
|
|
|
102
|
-
auto turboModuleBuilder = m_moduleBuilder.as<TurboModuleBuilder>();
|
|
103
117
|
std::vector<facebook::jsi::PropNameID> propertyNames;
|
|
104
|
-
propertyNames.reserve(
|
|
105
|
-
|
|
118
|
+
propertyNames.reserve(
|
|
119
|
+
m_moduleBuilder->Methods().size() + m_moduleBuilder->SyncMethods().size() +
|
|
120
|
+
(m_moduleBuilder->ConstantProviders().empty() ? 0 : 1));
|
|
121
|
+
|
|
122
|
+
for (auto &methodInfo : m_moduleBuilder->Methods()) {
|
|
106
123
|
propertyNames.push_back(facebook::jsi::PropNameID::forAscii(rt, methodInfo.first));
|
|
107
124
|
}
|
|
125
|
+
|
|
126
|
+
for (auto &syncMethodInfo : m_moduleBuilder->SyncMethods()) {
|
|
127
|
+
propertyNames.push_back(facebook::jsi::PropNameID::forAscii(rt, syncMethodInfo.first));
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
if (!m_moduleBuilder->ConstantProviders().empty()) {
|
|
131
|
+
propertyNames.push_back(facebook::jsi::PropNameID::forAscii(rt, "getConstants"));
|
|
132
|
+
}
|
|
133
|
+
|
|
108
134
|
return propertyNames;
|
|
109
135
|
};
|
|
110
136
|
|
|
@@ -114,24 +140,23 @@ class TurboModuleImpl : public facebook::react::TurboModule {
|
|
|
114
140
|
}
|
|
115
141
|
|
|
116
142
|
// it is not safe to assume that "runtime" never changes, so members are not cached here
|
|
117
|
-
auto moduleBuilder = m_moduleBuilder.as<TurboModuleBuilder>();
|
|
118
143
|
std::string key = propName.utf8(runtime);
|
|
119
144
|
|
|
120
|
-
if (key == "getConstants" && !
|
|
145
|
+
if (key == "getConstants" && !m_moduleBuilder->ConstantProviders().empty()) {
|
|
121
146
|
// try to find getConstants if there is any constant
|
|
122
147
|
return facebook::jsi::Function::createFromHostFunction(
|
|
123
148
|
runtime,
|
|
124
149
|
propName,
|
|
125
150
|
0,
|
|
126
|
-
[moduleBuilder](
|
|
151
|
+
[moduleBuilder = m_moduleBuilder](
|
|
127
152
|
facebook::jsi::Runtime &rt,
|
|
128
|
-
const facebook::jsi::Value &thisVal
|
|
129
|
-
const facebook::jsi::Value *args
|
|
130
|
-
size_t count) {
|
|
153
|
+
const facebook::jsi::Value & /*thisVal*/,
|
|
154
|
+
const facebook::jsi::Value * /*args*/,
|
|
155
|
+
size_t /*count*/) {
|
|
131
156
|
// collect all constants to an object
|
|
132
157
|
auto writer = winrt::make<JsiWriter>(rt);
|
|
133
158
|
writer.WriteObjectBegin();
|
|
134
|
-
for (auto constantProvider : moduleBuilder->
|
|
159
|
+
for (auto const &constantProvider : moduleBuilder->ConstantProviders()) {
|
|
135
160
|
constantProvider(writer);
|
|
136
161
|
}
|
|
137
162
|
writer.WriteObjectEnd();
|
|
@@ -141,21 +166,21 @@ class TurboModuleImpl : public facebook::react::TurboModule {
|
|
|
141
166
|
|
|
142
167
|
{
|
|
143
168
|
// try to find a Method
|
|
144
|
-
auto it =
|
|
145
|
-
if (it !=
|
|
146
|
-
TurboModuleMethodInfo methodInfo = it->second;
|
|
169
|
+
auto it = m_moduleBuilder->Methods().find(key);
|
|
170
|
+
if (it != m_moduleBuilder->Methods().end()) {
|
|
171
|
+
TurboModuleMethodInfo const &methodInfo = it->second;
|
|
147
172
|
switch (methodInfo.ReturnType) {
|
|
148
173
|
case MethodReturnType::Void:
|
|
149
174
|
return facebook::jsi::Function::createFromHostFunction(
|
|
150
175
|
runtime,
|
|
151
176
|
propName,
|
|
152
177
|
0,
|
|
153
|
-
[methodInfo](
|
|
178
|
+
[method = methodInfo.Method](
|
|
154
179
|
facebook::jsi::Runtime &rt,
|
|
155
180
|
const facebook::jsi::Value & /*thisVal*/,
|
|
156
181
|
const facebook::jsi::Value *args,
|
|
157
182
|
size_t argCount) {
|
|
158
|
-
|
|
183
|
+
method(winrt::make<JsiReader>(rt, args, argCount), nullptr, nullptr, nullptr);
|
|
159
184
|
return facebook::jsi::Value::undefined();
|
|
160
185
|
});
|
|
161
186
|
case MethodReturnType::Callback:
|
|
@@ -163,17 +188,22 @@ class TurboModuleImpl : public facebook::react::TurboModule {
|
|
|
163
188
|
runtime,
|
|
164
189
|
propName,
|
|
165
190
|
0,
|
|
166
|
-
[jsDispatcher = m_reactContext.JSDispatcher(),
|
|
191
|
+
[jsDispatcher = m_reactContext.JSDispatcher(),
|
|
192
|
+
method = methodInfo.Method,
|
|
193
|
+
longLivedObjectCollection = m_longLivedObjectCollection](
|
|
167
194
|
facebook::jsi::Runtime &rt,
|
|
168
195
|
const facebook::jsi::Value & /*thisVal*/,
|
|
169
196
|
const facebook::jsi::Value *args,
|
|
170
197
|
size_t argCount) {
|
|
171
198
|
VerifyElseCrash(argCount > 0);
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
199
|
+
if (auto strongLongLivedObjectCollection = longLivedObjectCollection.lock()) {
|
|
200
|
+
auto jsiRuntimeHolder = LongLivedJsiRuntime::CreateWeak(strongLongLivedObjectCollection, rt);
|
|
201
|
+
method(
|
|
202
|
+
winrt::make<JsiReader>(rt, args, argCount - 1),
|
|
203
|
+
winrt::make<JSDispatcherWriter>(jsDispatcher, jsiRuntimeHolder),
|
|
204
|
+
MakeCallback(rt, strongLongLivedObjectCollection, args[argCount - 1]),
|
|
205
|
+
nullptr);
|
|
206
|
+
}
|
|
177
207
|
return facebook::jsi::Value::undefined();
|
|
178
208
|
});
|
|
179
209
|
case MethodReturnType::TwoCallbacks:
|
|
@@ -181,17 +211,22 @@ class TurboModuleImpl : public facebook::react::TurboModule {
|
|
|
181
211
|
runtime,
|
|
182
212
|
propName,
|
|
183
213
|
0,
|
|
184
|
-
[jsDispatcher = m_reactContext.JSDispatcher(),
|
|
214
|
+
[jsDispatcher = m_reactContext.JSDispatcher(),
|
|
215
|
+
method = methodInfo.Method,
|
|
216
|
+
longLivedObjectCollection = m_longLivedObjectCollection](
|
|
185
217
|
facebook::jsi::Runtime &rt,
|
|
186
218
|
const facebook::jsi::Value & /*thisVal*/,
|
|
187
219
|
const facebook::jsi::Value *args,
|
|
188
220
|
size_t argCount) {
|
|
189
221
|
VerifyElseCrash(argCount > 1);
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
222
|
+
if (auto strongLongLivedObjectCollection = longLivedObjectCollection.lock()) {
|
|
223
|
+
auto jsiRuntimeHolder = LongLivedJsiRuntime::CreateWeak(strongLongLivedObjectCollection, rt);
|
|
224
|
+
method(
|
|
225
|
+
winrt::make<JsiReader>(rt, args, argCount - 2),
|
|
226
|
+
winrt::make<JSDispatcherWriter>(jsDispatcher, jsiRuntimeHolder),
|
|
227
|
+
MakeCallback(rt, strongLongLivedObjectCollection, args[argCount - 2]),
|
|
228
|
+
MakeCallback(rt, strongLongLivedObjectCollection, args[argCount - 1]));
|
|
229
|
+
}
|
|
195
230
|
return facebook::jsi::Value::undefined();
|
|
196
231
|
});
|
|
197
232
|
case MethodReturnType::Promise:
|
|
@@ -199,52 +234,66 @@ class TurboModuleImpl : public facebook::react::TurboModule {
|
|
|
199
234
|
runtime,
|
|
200
235
|
propName,
|
|
201
236
|
0,
|
|
202
|
-
[jsDispatcher = m_reactContext.JSDispatcher(),
|
|
237
|
+
[jsDispatcher = m_reactContext.JSDispatcher(),
|
|
238
|
+
method = methodInfo.Method,
|
|
239
|
+
longLivedObjectCollection = m_longLivedObjectCollection](
|
|
203
240
|
facebook::jsi::Runtime &rt,
|
|
204
241
|
const facebook::jsi::Value & /*thisVal*/,
|
|
205
242
|
const facebook::jsi::Value *args,
|
|
206
243
|
size_t count) {
|
|
207
|
-
auto
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
244
|
+
if (auto strongLongLivedObjectCollection = longLivedObjectCollection.lock()) {
|
|
245
|
+
auto jsiRuntimeHolder = LongLivedJsiRuntime::CreateWeak(strongLongLivedObjectCollection, rt);
|
|
246
|
+
auto argReader = winrt::make<JsiReader>(rt, args, count);
|
|
247
|
+
auto argWriter = winrt::make<JSDispatcherWriter>(jsDispatcher, jsiRuntimeHolder);
|
|
248
|
+
return facebook::react::createPromiseAsJSIValue(
|
|
249
|
+
rt,
|
|
250
|
+
[method, argReader, argWriter, strongLongLivedObjectCollection](
|
|
251
|
+
facebook::jsi::Runtime &runtime, std::shared_ptr<facebook::react::Promise> promise) {
|
|
252
|
+
method(
|
|
253
|
+
argReader,
|
|
254
|
+
argWriter,
|
|
255
|
+
[weakResolve = LongLivedJsiFunction::CreateWeak(
|
|
256
|
+
strongLongLivedObjectCollection, runtime, std::move(promise->resolve_))](
|
|
257
|
+
const IJSValueWriter &writer) {
|
|
258
|
+
writer.as<JSDispatcherWriter>()->WithResultArgs([weakResolve](
|
|
259
|
+
facebook::jsi::Runtime &runtime,
|
|
260
|
+
facebook::jsi::Value const *args,
|
|
261
|
+
size_t argCount) {
|
|
262
|
+
VerifyElseCrash(argCount == 1);
|
|
263
|
+
if (auto resolveHolder = weakResolve.lock()) {
|
|
264
|
+
resolveHolder->Value().call(runtime, args[0]);
|
|
265
|
+
}
|
|
266
|
+
});
|
|
267
|
+
},
|
|
268
|
+
[weakReject = LongLivedJsiFunction::CreateWeak(
|
|
269
|
+
strongLongLivedObjectCollection, runtime, std::move(promise->reject_))](
|
|
270
|
+
const IJSValueWriter &writer) {
|
|
271
|
+
writer.as<JSDispatcherWriter>()->WithResultArgs([weakReject](
|
|
272
|
+
facebook::jsi::Runtime &runtime,
|
|
273
|
+
facebook::jsi::Value const *args,
|
|
274
|
+
size_t argCount) {
|
|
275
|
+
VerifyElseCrash(argCount == 1);
|
|
276
|
+
if (auto rejectHolder = weakReject.lock()) {
|
|
277
|
+
// To match the Android and iOS TurboModule behavior we create the Error object for
|
|
278
|
+
// the Promise rejection the same way as in updateErrorWithErrorData method.
|
|
279
|
+
// See react-native/Libraries/BatchedBridge/NativeModules.js for details.
|
|
280
|
+
auto error = runtime.global()
|
|
281
|
+
.getPropertyAsFunction(runtime, "Error")
|
|
282
|
+
.callAsConstructor(runtime, {});
|
|
283
|
+
auto &errorData = args[0];
|
|
284
|
+
if (errorData.isObject()) {
|
|
285
|
+
runtime.global()
|
|
286
|
+
.getPropertyAsObject(runtime, "Object")
|
|
287
|
+
.getPropertyAsFunction(runtime, "assign")
|
|
288
|
+
.call(runtime, error, errorData.getObject(runtime));
|
|
289
|
+
}
|
|
290
|
+
rejectHolder->Value().call(runtime, args[0]);
|
|
291
|
+
}
|
|
292
|
+
});
|
|
223
293
|
});
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
facebook::jsi::Runtime &runtime,
|
|
228
|
-
facebook::jsi::Value const *args,
|
|
229
|
-
size_t argCount) {
|
|
230
|
-
VerifyElseCrash(argCount == 1);
|
|
231
|
-
// To match the Android and iOS TurboModule behavior we create the Error object for
|
|
232
|
-
// the Promise rejection the same way as in updateErrorWithErrorData method.
|
|
233
|
-
// See react-native/Libraries/BatchedBridge/NativeModules.js for details.
|
|
234
|
-
auto error = runtime.global()
|
|
235
|
-
.getPropertyAsFunction(runtime, "Error")
|
|
236
|
-
.callAsConstructor(runtime, {});
|
|
237
|
-
auto &errorData = args[0];
|
|
238
|
-
if (errorData.isObject()) {
|
|
239
|
-
runtime.global()
|
|
240
|
-
.getPropertyAsObject(runtime, "Object")
|
|
241
|
-
.getPropertyAsFunction(runtime, "assign")
|
|
242
|
-
.call(runtime, error, errorData.getObject(runtime));
|
|
243
|
-
}
|
|
244
|
-
promise->reject_.call(runtime, error);
|
|
245
|
-
});
|
|
246
|
-
});
|
|
247
|
-
});
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
return facebook::jsi::Value::undefined();
|
|
248
297
|
});
|
|
249
298
|
default:
|
|
250
299
|
VerifyElseCrash(false);
|
|
@@ -254,8 +303,8 @@ class TurboModuleImpl : public facebook::react::TurboModule {
|
|
|
254
303
|
|
|
255
304
|
{
|
|
256
305
|
// try to find a SyncMethod
|
|
257
|
-
auto it =
|
|
258
|
-
if (it !=
|
|
306
|
+
auto it = m_moduleBuilder->SyncMethods().find(key);
|
|
307
|
+
if (it != m_moduleBuilder->SyncMethods().end()) {
|
|
259
308
|
return facebook::jsi::Function::createFromHostFunction(
|
|
260
309
|
runtime,
|
|
261
310
|
propName,
|
|
@@ -287,27 +336,34 @@ class TurboModuleImpl : public facebook::react::TurboModule {
|
|
|
287
336
|
}
|
|
288
337
|
|
|
289
338
|
private:
|
|
290
|
-
static MethodResultCallback MakeCallback(
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
339
|
+
static MethodResultCallback MakeCallback(
|
|
340
|
+
facebook::jsi::Runtime &rt,
|
|
341
|
+
const std::shared_ptr<facebook::react::LongLivedObjectCollection> &longLivedObjectCollection,
|
|
342
|
+
const facebook::jsi::Value &callback) noexcept {
|
|
343
|
+
auto weakCallback =
|
|
344
|
+
LongLivedJsiFunction::CreateWeak(longLivedObjectCollection, rt, callback.getObject(rt).getFunction(rt));
|
|
345
|
+
return [weakCallback = std::move(weakCallback)](const IJSValueWriter &writer) noexcept {
|
|
294
346
|
writer.as<JSDispatcherWriter>()->WithResultArgs(
|
|
295
|
-
[
|
|
296
|
-
|
|
347
|
+
[weakCallback](facebook::jsi::Runtime &rt, facebook::jsi::Value const *args, size_t count) {
|
|
348
|
+
if (auto callback = weakCallback.lock()) {
|
|
349
|
+
callback->Value().call(rt, args, count);
|
|
350
|
+
}
|
|
297
351
|
});
|
|
298
352
|
};
|
|
299
353
|
}
|
|
300
354
|
|
|
301
355
|
private:
|
|
302
356
|
IReactContext m_reactContext;
|
|
303
|
-
|
|
357
|
+
winrt::com_ptr<TurboModuleBuilder> m_moduleBuilder;
|
|
304
358
|
IInspectable m_providedModule;
|
|
305
359
|
std::shared_ptr<implementation::HostObjectWrapper> m_hostObjectWrapper;
|
|
360
|
+
std::weak_ptr<facebook::react::LongLivedObjectCollection> m_longLivedObjectCollection;
|
|
306
361
|
};
|
|
307
362
|
|
|
308
363
|
/*-------------------------------------------------------------------------------
|
|
309
364
|
TurboModulesProvider
|
|
310
365
|
-------------------------------------------------------------------------------*/
|
|
366
|
+
|
|
311
367
|
std::shared_ptr<facebook::react::TurboModule> TurboModulesProvider::getModule(
|
|
312
368
|
const std::string &moduleName,
|
|
313
369
|
const std::shared_ptr<facebook::react::CallInvoker> &callInvoker) noexcept {
|
|
@@ -317,7 +373,8 @@ std::shared_ptr<facebook::react::TurboModule> TurboModulesProvider::getModule(
|
|
|
317
373
|
return nullptr;
|
|
318
374
|
}
|
|
319
375
|
|
|
320
|
-
auto tm = std::make_shared<TurboModuleImpl>(
|
|
376
|
+
auto tm = std::make_shared<TurboModuleImpl>(
|
|
377
|
+
m_reactContext, moduleName, callInvoker, m_longLivedObjectCollection, /*reactModuleProvider*/ it->second);
|
|
321
378
|
return tm;
|
|
322
379
|
}
|
|
323
380
|
|
|
@@ -348,4 +405,9 @@ void TurboModulesProvider::AddModuleProvider(
|
|
|
348
405
|
}
|
|
349
406
|
}
|
|
350
407
|
|
|
408
|
+
std::shared_ptr<facebook::react::LongLivedObjectCollection> const &
|
|
409
|
+
TurboModulesProvider::LongLivedObjectCollection() noexcept {
|
|
410
|
+
return m_longLivedObjectCollection;
|
|
411
|
+
}
|
|
412
|
+
|
|
351
413
|
} // namespace winrt::Microsoft::ReactNative
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
#pragma once
|
|
8
8
|
|
|
9
|
+
#include <ReactCommon/LongLivedObject.h>
|
|
9
10
|
#include <TurboModuleRegistry.h>
|
|
10
11
|
#include "Base/FollyIncludes.h"
|
|
11
12
|
#include "winrt/Microsoft.ReactNative.h"
|
|
@@ -25,8 +26,12 @@ class TurboModulesProvider final : public facebook::react::TurboModuleRegistry {
|
|
|
25
26
|
winrt::hstring const &moduleName,
|
|
26
27
|
ReactModuleProvider const &moduleProvider,
|
|
27
28
|
bool overwriteExisting) noexcept;
|
|
29
|
+
std::shared_ptr<facebook::react::LongLivedObjectCollection> const &LongLivedObjectCollection() noexcept;
|
|
28
30
|
|
|
29
31
|
private:
|
|
32
|
+
// To keep a list of deferred asynchronous callbacks and promises.
|
|
33
|
+
std::shared_ptr<facebook::react::LongLivedObjectCollection> m_longLivedObjectCollection{
|
|
34
|
+
std::make_shared<facebook::react::LongLivedObjectCollection>()};
|
|
30
35
|
std::unordered_map<std::string, ReactModuleProvider> m_moduleProviders;
|
|
31
36
|
IReactContext m_reactContext;
|
|
32
37
|
};
|
|
@@ -265,9 +265,11 @@ bool ViewManagerBase::UpdateProperty(
|
|
|
265
265
|
const auto iter = pointerEventsMap.find(propertyValue.AsString());
|
|
266
266
|
if (iter != pointerEventsMap.end()) {
|
|
267
267
|
nodeToUpdate->m_pointerEvents = iter->second;
|
|
268
|
-
if (nodeToUpdate->
|
|
269
|
-
if (
|
|
268
|
+
if (const auto uiElement = nodeToUpdate->GetView().try_as<xaml::UIElement>()) {
|
|
269
|
+
if (nodeToUpdate->m_pointerEvents == PointerEventsKind::None) {
|
|
270
270
|
uiElement.IsHitTestVisible(false);
|
|
271
|
+
} else {
|
|
272
|
+
uiElement.ClearValue(xaml::UIElement::IsHitTestVisibleProperty());
|
|
271
273
|
}
|
|
272
274
|
}
|
|
273
275
|
} else {
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation.
|
|
2
|
+
// Licensed under the MIT License.
|
|
3
|
+
#pragma once
|
|
4
|
+
#ifndef MICROSOFT_REACTNATIVE_JSI_LONGLIVEDJSIVALUE_
|
|
5
|
+
#define MICROSOFT_REACTNATIVE_JSI_LONGLIVEDJSIVALUE_
|
|
6
|
+
|
|
7
|
+
#include <ReactCommon/LongLivedObject.h>
|
|
8
|
+
#include <jsi/jsi.h>
|
|
9
|
+
|
|
10
|
+
namespace winrt::Microsoft::ReactNative {
|
|
11
|
+
|
|
12
|
+
// Wrap up JSI Runtime into a LongLivedObject
|
|
13
|
+
struct LongLivedJsiRuntime : facebook::react::LongLivedObject {
|
|
14
|
+
static std::weak_ptr<LongLivedJsiRuntime> CreateWeak(
|
|
15
|
+
std::shared_ptr<facebook::react::LongLivedObjectCollection> const &longLivedObjectCollection,
|
|
16
|
+
facebook::jsi::Runtime &runtime) noexcept {
|
|
17
|
+
auto value = std::shared_ptr<LongLivedJsiRuntime>(new LongLivedJsiRuntime(longLivedObjectCollection, runtime));
|
|
18
|
+
longLivedObjectCollection->add(value);
|
|
19
|
+
return value;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
facebook::jsi::Runtime &Runtime() {
|
|
23
|
+
return runtime_;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
public: // LongLivedObject overrides
|
|
27
|
+
void allowRelease() override {
|
|
28
|
+
if (auto longLivedObjectCollection = longLivedObjectCollection_.lock()) {
|
|
29
|
+
if (longLivedObjectCollection != nullptr) {
|
|
30
|
+
longLivedObjectCollection->remove(this);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
LongLivedObject::allowRelease();
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
protected:
|
|
38
|
+
LongLivedJsiRuntime(
|
|
39
|
+
std::shared_ptr<facebook::react::LongLivedObjectCollection> const &longLivedObjectCollection,
|
|
40
|
+
facebook::jsi::Runtime &runtime)
|
|
41
|
+
: longLivedObjectCollection_(longLivedObjectCollection), runtime_(runtime) {}
|
|
42
|
+
|
|
43
|
+
LongLivedJsiRuntime(LongLivedJsiRuntime const &) = delete;
|
|
44
|
+
|
|
45
|
+
private:
|
|
46
|
+
// Use a weak reference to the collection to avoid reference loops
|
|
47
|
+
std::weak_ptr<facebook::react::LongLivedObjectCollection> longLivedObjectCollection_;
|
|
48
|
+
facebook::jsi::Runtime &runtime_;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
// Wrap up a JSI Value into a LongLivedObject.
|
|
52
|
+
template <typename TValue>
|
|
53
|
+
struct LongLivedJsiValue : LongLivedJsiRuntime {
|
|
54
|
+
static std::weak_ptr<LongLivedJsiValue<TValue>> CreateWeak(
|
|
55
|
+
std::shared_ptr<facebook::react::LongLivedObjectCollection> const &longLivedObjectCollection,
|
|
56
|
+
facebook::jsi::Runtime &runtime,
|
|
57
|
+
TValue &&value) noexcept {
|
|
58
|
+
auto valueWrapper = std::shared_ptr<LongLivedJsiValue<TValue>>(
|
|
59
|
+
new LongLivedJsiValue<TValue>(longLivedObjectCollection, runtime, std::forward<TValue>(value)));
|
|
60
|
+
longLivedObjectCollection->add(valueWrapper);
|
|
61
|
+
return valueWrapper;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
TValue &Value() {
|
|
65
|
+
return value_;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
protected:
|
|
69
|
+
template <typename TValue2>
|
|
70
|
+
LongLivedJsiValue(
|
|
71
|
+
std::shared_ptr<facebook::react::LongLivedObjectCollection> const &longLivedObjectCollection,
|
|
72
|
+
facebook::jsi::Runtime &runtime,
|
|
73
|
+
TValue2 &&value)
|
|
74
|
+
: LongLivedJsiRuntime(longLivedObjectCollection, runtime), value_(std::forward<TValue2>(value)) {}
|
|
75
|
+
|
|
76
|
+
private:
|
|
77
|
+
TValue value_;
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
using LongLivedJsiFunction = LongLivedJsiValue<facebook::jsi::Function>;
|
|
81
|
+
|
|
82
|
+
} // namespace winrt::Microsoft::ReactNative
|
|
83
|
+
|
|
84
|
+
#endif // MICROSOFT_REACTNATIVE_JSI_LONGLIVEDJSIVALUE_
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
<ClInclude Include="$(JSI_SourcePath)\jsi\jsi-inl.h" />
|
|
39
39
|
<ClInclude Include="$(JSI_SourcePath)\jsi\jsi.h" />
|
|
40
40
|
<ClInclude Include="$(MSBuildThisFileDirectory)DesktopWindowBridge.h" />
|
|
41
|
+
<ClInclude Include="$(MSBuildThisFileDirectory)JSI\LongLivedJsiValue.h" />
|
|
41
42
|
<ClInclude Include="$(MSBuildThisFileDirectory)JSI\NodeApiJsiRuntime.h" />
|
|
42
43
|
<ClInclude Include="$(MSBuildThisFileDirectory)TurboModuleProvider.h" />
|
|
43
44
|
<ClInclude Include="$(CallInvoker_SourcePath)\ReactCommon\CallInvoker.h" />
|
|
@@ -151,6 +151,9 @@
|
|
|
151
151
|
<Filter>JSI</Filter>
|
|
152
152
|
</ClInclude>
|
|
153
153
|
<ClInclude Include="$(Bridging_SourcePath)\CallbackWrapper.h" />
|
|
154
|
+
<ClInclude Include="$(MSBuildThisFileDirectory)JSI\LongLivedJsiValue.h">
|
|
155
|
+
<Filter>TurboModule</Filter>
|
|
156
|
+
</ClInclude>
|
|
154
157
|
</ItemGroup>
|
|
155
158
|
<ItemGroup>
|
|
156
159
|
<Filter Include="JSI">
|
|
@@ -289,7 +289,12 @@ void UISchedulerWinRT::AwaitTermination() noexcept {
|
|
|
289
289
|
return queue;
|
|
290
290
|
}
|
|
291
291
|
|
|
292
|
-
|
|
292
|
+
decltype(DispatcherQueue::GetForCurrentThread()) dispatcher{nullptr};
|
|
293
|
+
try {
|
|
294
|
+
dispatcher = DispatcherQueue::GetForCurrentThread();
|
|
295
|
+
} catch (winrt::hresult_error const &) {
|
|
296
|
+
}
|
|
297
|
+
|
|
293
298
|
if (!dispatcher) {
|
|
294
299
|
return queue;
|
|
295
300
|
}
|
|
@@ -10,10 +10,10 @@
|
|
|
10
10
|
-->
|
|
11
11
|
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
12
12
|
<PropertyGroup>
|
|
13
|
-
<ReactNativeWindowsVersion>0.69.
|
|
13
|
+
<ReactNativeWindowsVersion>0.69.7</ReactNativeWindowsVersion>
|
|
14
14
|
<ReactNativeWindowsMajor>0</ReactNativeWindowsMajor>
|
|
15
15
|
<ReactNativeWindowsMinor>69</ReactNativeWindowsMinor>
|
|
16
|
-
<ReactNativeWindowsPatch>
|
|
16
|
+
<ReactNativeWindowsPatch>7</ReactNativeWindowsPatch>
|
|
17
17
|
<ReactNativeWindowsCanary>false</ReactNativeWindowsCanary>
|
|
18
18
|
</PropertyGroup>
|
|
19
19
|
</Project>
|
|
@@ -41,6 +41,35 @@ std::shared_ptr<InstanceWrapper> CreateReactInstance(
|
|
|
41
41
|
std::move(jsBundleBasePath),
|
|
42
42
|
std::move(cxxModules),
|
|
43
43
|
std::move(turboModuleRegistry),
|
|
44
|
+
nullptr,
|
|
45
|
+
std::move(callback),
|
|
46
|
+
std::move(jsQueue),
|
|
47
|
+
std::move(nativeQueue),
|
|
48
|
+
std::move(devSettings),
|
|
49
|
+
GetSharedDevManager());
|
|
50
|
+
|
|
51
|
+
return inner;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
std::shared_ptr<InstanceWrapper> CreateReactInstance(
|
|
55
|
+
std::shared_ptr<Instance> &&instance,
|
|
56
|
+
std::string &&jsBundleBasePath,
|
|
57
|
+
std::vector<
|
|
58
|
+
std::tuple<std::string, facebook::xplat::module::CxxModule::Provider, std::shared_ptr<MessageQueueThread>>>
|
|
59
|
+
&&cxxModules,
|
|
60
|
+
std::shared_ptr<TurboModuleRegistry> turboModuleRegistry,
|
|
61
|
+
std::shared_ptr<facebook::react::LongLivedObjectCollection> longLivedObjectCollection,
|
|
62
|
+
std::unique_ptr<InstanceCallback> &&callback,
|
|
63
|
+
std::shared_ptr<MessageQueueThread> jsQueue,
|
|
64
|
+
std::shared_ptr<MessageQueueThread> nativeQueue,
|
|
65
|
+
std::shared_ptr<DevSettings> devSettings) noexcept {
|
|
66
|
+
// Now create the instance
|
|
67
|
+
std::shared_ptr<InstanceWrapper> inner = InstanceImpl::MakeNoBundle(
|
|
68
|
+
std::move(instance),
|
|
69
|
+
std::move(jsBundleBasePath),
|
|
70
|
+
std::move(cxxModules),
|
|
71
|
+
std::move(turboModuleRegistry),
|
|
72
|
+
std::move(longLivedObjectCollection),
|
|
44
73
|
std::move(callback),
|
|
45
74
|
std::move(jsQueue),
|
|
46
75
|
std::move(nativeQueue),
|
package/Shared/InstanceManager.h
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
#pragma once
|
|
5
5
|
|
|
6
6
|
#include <Logging.h>
|
|
7
|
+
#include <ReactCommon/LongLivedObject.h>
|
|
7
8
|
#include <cxxreact/CxxModule.h>
|
|
8
9
|
#include <cxxreact/JSBigString.h>
|
|
9
10
|
#include <map>
|
|
@@ -51,6 +52,19 @@ std::shared_ptr<InstanceWrapper> CreateReactInstance(
|
|
|
51
52
|
std::shared_ptr<MessageQueueThread> nativeQueue,
|
|
52
53
|
std::shared_ptr<DevSettings> devSettings) noexcept;
|
|
53
54
|
|
|
55
|
+
std::shared_ptr<InstanceWrapper> CreateReactInstance(
|
|
56
|
+
std::shared_ptr<Instance> &&instance,
|
|
57
|
+
std::string &&jsBundleRelativePath,
|
|
58
|
+
std::vector<
|
|
59
|
+
std::tuple<std::string, facebook::xplat::module::CxxModule::Provider, std::shared_ptr<MessageQueueThread>>>
|
|
60
|
+
&&cxxModules,
|
|
61
|
+
std::shared_ptr<TurboModuleRegistry> turboModuleRegistry,
|
|
62
|
+
std::shared_ptr<facebook::react::LongLivedObjectCollection> longLivedObjectCollection,
|
|
63
|
+
std::unique_ptr<InstanceCallback> &&callback,
|
|
64
|
+
std::shared_ptr<MessageQueueThread> jsQueue,
|
|
65
|
+
std::shared_ptr<MessageQueueThread> nativeQueue,
|
|
66
|
+
std::shared_ptr<DevSettings> devSettings) noexcept;
|
|
67
|
+
|
|
54
68
|
std::shared_ptr<InstanceWrapper> CreateReactInstance(
|
|
55
69
|
std::shared_ptr<Instance> &&instance,
|
|
56
70
|
std::string &&jsBundleBasePath,
|
package/Shared/OInstance.cpp
CHANGED
|
@@ -106,11 +106,13 @@ class OJSIExecutorFactory : public JSExecutorFactory {
|
|
|
106
106
|
auto turboModuleManager = std::make_shared<TurboModuleManager>(turboModuleRegistry_, jsCallInvoker_);
|
|
107
107
|
|
|
108
108
|
// TODO: The binding here should also add the proxys that convert cxxmodules into turbomodules
|
|
109
|
+
// [vmoroz] Note, that we must not use the RN TurboCxxModule.h code because it uses global LongLivedObjectCollection
|
|
110
|
+
// instance that prevents us from using multiple RN instance in the same process.
|
|
109
111
|
auto binding = [turboModuleManager](const std::string &name) -> std::shared_ptr<TurboModule> {
|
|
110
112
|
return turboModuleManager->getModule(name);
|
|
111
113
|
};
|
|
112
114
|
|
|
113
|
-
TurboModuleBinding::install(*runtimeHolder_->getRuntime(), std::function(binding));
|
|
115
|
+
TurboModuleBinding::install(*runtimeHolder_->getRuntime(), std::function(binding), longLivedObjectCollection_);
|
|
114
116
|
|
|
115
117
|
// init TurboModule
|
|
116
118
|
for (const auto &moduleName : turboModuleManager->getEagerInitModuleNames()) {
|
|
@@ -132,17 +134,20 @@ class OJSIExecutorFactory : public JSExecutorFactory {
|
|
|
132
134
|
std::shared_ptr<Microsoft::JSI::RuntimeHolderLazyInit> runtimeHolder,
|
|
133
135
|
NativeLoggingHook loggingHook,
|
|
134
136
|
std::shared_ptr<TurboModuleRegistry> turboModuleRegistry,
|
|
137
|
+
std::shared_ptr<LongLivedObjectCollection> longLivedObjectCollection,
|
|
135
138
|
bool isProfilingEnabled,
|
|
136
139
|
std::shared_ptr<CallInvoker> jsCallInvoker) noexcept
|
|
137
140
|
: runtimeHolder_{std::move(runtimeHolder)},
|
|
138
141
|
loggingHook_{std::move(loggingHook)},
|
|
139
142
|
turboModuleRegistry_{std::move(turboModuleRegistry)},
|
|
143
|
+
longLivedObjectCollection_{std::move(longLivedObjectCollection)},
|
|
140
144
|
jsCallInvoker_{std::move(jsCallInvoker)},
|
|
141
145
|
isProfilingEnabled_{isProfilingEnabled} {}
|
|
142
146
|
|
|
143
147
|
private:
|
|
144
148
|
std::shared_ptr<Microsoft::JSI::RuntimeHolderLazyInit> runtimeHolder_;
|
|
145
149
|
std::shared_ptr<TurboModuleRegistry> turboModuleRegistry_;
|
|
150
|
+
std::shared_ptr<LongLivedObjectCollection> longLivedObjectCollection_;
|
|
146
151
|
std::shared_ptr<CallInvoker> jsCallInvoker_;
|
|
147
152
|
NativeLoggingHook loggingHook_;
|
|
148
153
|
bool isProfilingEnabled_;
|
|
@@ -159,6 +164,7 @@ void logMarker(const facebook::react::ReactMarker::ReactMarkerId /*id*/, const c
|
|
|
159
164
|
std::tuple<std::string, facebook::xplat::module::CxxModule::Provider, std::shared_ptr<MessageQueueThread>>>
|
|
160
165
|
&&cxxModules,
|
|
161
166
|
std::shared_ptr<TurboModuleRegistry> turboModuleRegistry,
|
|
167
|
+
std::shared_ptr<facebook::react::LongLivedObjectCollection> longLivedObjectCollection,
|
|
162
168
|
std::unique_ptr<InstanceCallback> &&callback,
|
|
163
169
|
std::shared_ptr<MessageQueueThread> jsQueue,
|
|
164
170
|
std::shared_ptr<MessageQueueThread> nativeQueue,
|
|
@@ -169,6 +175,7 @@ void logMarker(const facebook::react::ReactMarker::ReactMarkerId /*id*/, const c
|
|
|
169
175
|
std::move(jsBundleBasePath),
|
|
170
176
|
std::move(cxxModules),
|
|
171
177
|
std::move(turboModuleRegistry),
|
|
178
|
+
std::move(longLivedObjectCollection),
|
|
172
179
|
std::move(callback),
|
|
173
180
|
std::move(jsQueue),
|
|
174
181
|
std::move(nativeQueue),
|
|
@@ -198,6 +205,7 @@ void logMarker(const facebook::react::ReactMarker::ReactMarkerId /*id*/, const c
|
|
|
198
205
|
std::move(jsBundleBasePath),
|
|
199
206
|
std::move(cxxModules),
|
|
200
207
|
std::move(turboModuleRegistry),
|
|
208
|
+
nullptr,
|
|
201
209
|
std::move(callback),
|
|
202
210
|
std::move(jsQueue),
|
|
203
211
|
std::move(nativeQueue),
|
|
@@ -235,12 +243,14 @@ InstanceImpl::InstanceImpl(
|
|
|
235
243
|
std::tuple<std::string, facebook::xplat::module::CxxModule::Provider, std::shared_ptr<MessageQueueThread>>>
|
|
236
244
|
&&cxxModules,
|
|
237
245
|
std::shared_ptr<TurboModuleRegistry> turboModuleRegistry,
|
|
246
|
+
std::shared_ptr<facebook::react::LongLivedObjectCollection> longLivedObjectCollection,
|
|
238
247
|
std::unique_ptr<InstanceCallback> &&callback,
|
|
239
248
|
std::shared_ptr<MessageQueueThread> jsQueue,
|
|
240
249
|
std::shared_ptr<MessageQueueThread> nativeQueue,
|
|
241
250
|
std::shared_ptr<DevSettings> devSettings,
|
|
242
251
|
std::shared_ptr<IDevSupportManager> devManager)
|
|
243
252
|
: m_turboModuleRegistry(std::move(turboModuleRegistry)),
|
|
253
|
+
m_longLivedObjectCollection(std::move(longLivedObjectCollection)),
|
|
244
254
|
m_jsThread(std::move(jsQueue)),
|
|
245
255
|
m_nativeQueue(nativeQueue),
|
|
246
256
|
m_jsBundleBasePath(std::move(jsBundleBasePath)),
|
|
@@ -301,6 +311,7 @@ InstanceImpl::InstanceImpl(
|
|
|
301
311
|
m_devSettings->jsiRuntimeHolder,
|
|
302
312
|
m_devSettings->loggingCallback,
|
|
303
313
|
m_turboModuleRegistry,
|
|
314
|
+
m_longLivedObjectCollection,
|
|
304
315
|
!m_devSettings->useFastRefresh,
|
|
305
316
|
m_innerInstance->getJSCallInvoker());
|
|
306
317
|
} else {
|
|
@@ -365,6 +376,7 @@ InstanceImpl::InstanceImpl(
|
|
|
365
376
|
m_devSettings->jsiRuntimeHolder,
|
|
366
377
|
m_devSettings->loggingCallback,
|
|
367
378
|
m_turboModuleRegistry,
|
|
379
|
+
m_longLivedObjectCollection,
|
|
368
380
|
!m_devSettings->useFastRefresh,
|
|
369
381
|
m_innerInstance->getJSCallInvoker());
|
|
370
382
|
}
|
package/Shared/OInstance.h
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
#include "InstanceManager.h"
|
|
11
11
|
|
|
12
12
|
// React Native
|
|
13
|
+
#include <ReactCommon/LongLivedObject.h>
|
|
13
14
|
#include <cxxreact/Instance.h>
|
|
14
15
|
|
|
15
16
|
// Standard Libriary
|
|
@@ -32,6 +33,7 @@ class InstanceImpl final : public InstanceWrapper, private ::std::enable_shared_
|
|
|
32
33
|
std::tuple<std::string, facebook::xplat::module::CxxModule::Provider, std::shared_ptr<MessageQueueThread>>>
|
|
33
34
|
&&cxxModules,
|
|
34
35
|
std::shared_ptr<TurboModuleRegistry> turboModuleRegistry,
|
|
36
|
+
std::shared_ptr<facebook::react::LongLivedObjectCollection> longLivedObjectCollection,
|
|
35
37
|
std::unique_ptr<InstanceCallback> &&callback,
|
|
36
38
|
std::shared_ptr<MessageQueueThread> jsQueue,
|
|
37
39
|
std::shared_ptr<MessageQueueThread> nativeQueue,
|
|
@@ -72,19 +74,7 @@ class InstanceImpl final : public InstanceWrapper, private ::std::enable_shared_
|
|
|
72
74
|
std::tuple<std::string, facebook::xplat::module::CxxModule::Provider, std::shared_ptr<MessageQueueThread>>>
|
|
73
75
|
&&cxxModules,
|
|
74
76
|
std::shared_ptr<TurboModuleRegistry> turboModuleRegistry,
|
|
75
|
-
std::
|
|
76
|
-
std::shared_ptr<MessageQueueThread> jsQueue,
|
|
77
|
-
std::shared_ptr<MessageQueueThread> nativeQueue,
|
|
78
|
-
std::shared_ptr<DevSettings> devSettings,
|
|
79
|
-
std::shared_ptr<IDevSupportManager> devManager);
|
|
80
|
-
|
|
81
|
-
InstanceImpl(
|
|
82
|
-
std::shared_ptr<Instance> &&instance,
|
|
83
|
-
std::string &&jsBundleBasePath,
|
|
84
|
-
std::string &&jsBundleRelativePath,
|
|
85
|
-
std::vector<
|
|
86
|
-
std::tuple<std::string, facebook::xplat::module::CxxModule::Provider, std::shared_ptr<MessageQueueThread>>>
|
|
87
|
-
&&cxxModules,
|
|
77
|
+
std::shared_ptr<facebook::react::LongLivedObjectCollection> longLivedObjectCollection,
|
|
88
78
|
std::unique_ptr<InstanceCallback> &&callback,
|
|
89
79
|
std::shared_ptr<MessageQueueThread> jsQueue,
|
|
90
80
|
std::shared_ptr<MessageQueueThread> nativeQueue,
|
|
@@ -102,6 +92,7 @@ class InstanceImpl final : public InstanceWrapper, private ::std::enable_shared_
|
|
|
102
92
|
std::string m_jsBundleBasePath;
|
|
103
93
|
std::shared_ptr<facebook::react::ModuleRegistry> m_moduleRegistry;
|
|
104
94
|
std::shared_ptr<TurboModuleRegistry> m_turboModuleRegistry;
|
|
95
|
+
std::shared_ptr<facebook::react::LongLivedObjectCollection> m_longLivedObjectCollection;
|
|
105
96
|
std::shared_ptr<MessageQueueThread> m_jsThread;
|
|
106
97
|
std::shared_ptr<MessageQueueThread> m_nativeQueue;
|
|
107
98
|
|
|
@@ -69,19 +69,25 @@ BatchingQueueThread::BatchingQueueThread(
|
|
|
69
69
|
void BatchingQueueThread::decoratedNativeCallInvokerReady(
|
|
70
70
|
std::weak_ptr<facebook::react::Instance> wkInstance) noexcept {
|
|
71
71
|
std::scoped_lock lck(m_mutex);
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
72
|
+
if (auto instance = wkInstance.lock()) {
|
|
73
|
+
// When items were queued in the undecoratedNativeCallInvoker it will not have called
|
|
74
|
+
// recordTurboModuleAsyncMethodCall. Calling invokeAsync on the decoratedNativeCallInvoker
|
|
75
|
+
// ensures that the queue is properly flushed, on the next batch complete
|
|
76
|
+
auto decoratedCallInvoker = instance->getDecoratedNativeCallInvoker(m_callInvoker);
|
|
77
|
+
decoratedCallInvoker->invokeAsync([decoratedCallInvoker, wkInstance, this] {
|
|
78
|
+
if (auto instance = wkInstance.lock()) {
|
|
79
|
+
std::scoped_lock lckQuitting(m_mutexQuitting);
|
|
80
|
+
|
|
81
|
+
// If we are shutting down, then then the mutex is being held in quitSynchronous
|
|
82
|
+
// Which is waiting for this task to complete, so we cannot take the mutex if quitSynchronous
|
|
83
|
+
// is running. -- and since we are shutting down anyway, we can just skip this work.
|
|
84
|
+
if (!m_quitting) {
|
|
85
|
+
std::scoped_lock lck(m_mutex);
|
|
86
|
+
m_callInvoker = decoratedCallInvoker;
|
|
87
|
+
}
|
|
82
88
|
}
|
|
83
|
-
}
|
|
84
|
-
}
|
|
89
|
+
});
|
|
90
|
+
}
|
|
85
91
|
}
|
|
86
92
|
|
|
87
93
|
BatchingQueueThread::~BatchingQueueThread() noexcept {}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-windows",
|
|
3
|
-
"version": "0.69.
|
|
3
|
+
"version": "0.69.7",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -26,8 +26,8 @@
|
|
|
26
26
|
"@react-native-community/cli": "^8.0.0",
|
|
27
27
|
"@react-native-community/cli-platform-android": "^8.0.0",
|
|
28
28
|
"@react-native-community/cli-platform-ios": "^8.0.0",
|
|
29
|
-
"@react-native-windows/cli": "0.69.
|
|
30
|
-
"@react-native-windows/virtualized-list": "0.69.
|
|
29
|
+
"@react-native-windows/cli": "0.69.3",
|
|
30
|
+
"@react-native-windows/virtualized-list": "0.69.1",
|
|
31
31
|
"@react-native/assets": "1.0.0",
|
|
32
32
|
"@react-native/normalize-color": "2.0.0",
|
|
33
33
|
"@react-native/polyfills": "2.0.0",
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
"ws": "^6.1.4"
|
|
62
62
|
},
|
|
63
63
|
"devDependencies": {
|
|
64
|
-
"@react-native-windows/codegen": "0.69.
|
|
64
|
+
"@react-native-windows/codegen": "0.69.1",
|
|
65
65
|
"@rnw-scripts/eslint-config": "1.1.12",
|
|
66
66
|
"@rnw-scripts/jest-out-of-tree-snapshot-resolver": "^1.0.6",
|
|
67
67
|
"@rnw-scripts/metro-dev-config": "0.0.0",
|
|
@@ -88,7 +88,7 @@
|
|
|
88
88
|
"react-native": "^0.69.0"
|
|
89
89
|
},
|
|
90
90
|
"beachball": {
|
|
91
|
-
"defaultNpmTag": "
|
|
91
|
+
"defaultNpmTag": "v0.69-stable",
|
|
92
92
|
"gitTags": true,
|
|
93
93
|
"disallowedChangeTypes": [
|
|
94
94
|
"major",
|