Skip to content

Commit 2cccbe1

Browse files
committed
Address PR feedback
1 parent b707a8c commit 2cccbe1

File tree

13 files changed

+197
-149
lines changed

13 files changed

+197
-149
lines changed

vnext/Microsoft.ReactNative.Cxx.UnitTests/Microsoft.ReactNative.Cxx.UnitTests.vcxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,10 +144,14 @@
144144
<Midl Include="$(ReactNativeWindowsDir)Microsoft.ReactNative\IReactNonAbiValue.idl" />
145145
<Midl Include="$(ReactNativeWindowsDir)Microsoft.ReactNative\IReactNotificationService.idl" />
146146
<Midl Include="$(ReactNativeWindowsDir)Microsoft.ReactNative\IReactPackageBuilder.idl" />
147+
<Midl Include="$(ReactNativeWindowsDir)Microsoft.ReactNative\IReactPackageProvider.idl" />
147148
<Midl Include="$(ReactNativeWindowsDir)Microsoft.ReactNative\IReactPropertyBag.idl" />
148149
<Midl Include="$(ReactNativeWindowsDir)Microsoft.ReactNative\IViewManager.idl" />
149150
<Midl Include="$(ReactNativeWindowsDir)Microsoft.ReactNative\IViewManagerCore.idl" />
150151
<Midl Include="$(ReactNativeWindowsDir)Microsoft.ReactNative\JsiApi.idl" />
152+
<Midl Include="$(ReactNativeWindowsDir)Microsoft.ReactNative\ReactInstanceSettings.idl" />
153+
<Midl Include="$(ReactNativeWindowsDir)Microsoft.ReactNative\ReactNativeHost.idl" />
154+
<Midl Include="$(ReactNativeWindowsDir)Microsoft.ReactNative\RedBoxHandler.idl" />
151155
</ItemGroup>
152156
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
153157
<ImportGroup Label="ExtensionTargets">

vnext/Microsoft.ReactNative.Cxx.UnitTests/ReactModuleBuilderMock.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,4 +160,23 @@ void ReactContextMock::EmitJSEvent(
160160
m_builderMock->EmitJSEvent(eventEmitterName, eventName, paramsArgWriter);
161161
}
162162

163+
Microsoft::ReactNative::IReactPropertyNamespace ReactPropertyBagHelper::GlobalNamespace() {
164+
VerifyElseCrashSz(false, "Not implemented");
165+
}
166+
167+
Microsoft::ReactNative::IReactPropertyNamespace ReactPropertyBagHelper::GetNamespace(
168+
param::hstring const & /*namespaceName*/) {
169+
VerifyElseCrashSz(false, "Not implemented");
170+
}
171+
172+
Microsoft::ReactNative::IReactPropertyName ReactPropertyBagHelper::GetName(
173+
Microsoft::ReactNative::IReactPropertyNamespace const & /*ns*/,
174+
param::hstring const & /*localName*/) {
175+
VerifyElseCrashSz(false, "Not implemented");
176+
}
177+
178+
Microsoft::ReactNative::IReactPropertyBag ReactPropertyBagHelper::CreatePropertyBag() {
179+
VerifyElseCrashSz(false, "Not implemented");
180+
}
181+
163182
} // namespace winrt::Microsoft::ReactNative
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT License.
3+
4+
#include "pch.h"
5+
#include "JsiApiContext.h"
6+
7+
// Use __ImageBase to get current DLL handle.
8+
// http://blogs.msdn.com/oldnewthing/archive/2004/10/25/247180.aspx
9+
extern "C" IMAGE_DOS_HEADER __ImageBase;
10+
11+
namespace winrt::Microsoft::ReactNative {
12+
13+
// Get JSI Runtime from the current JS dispatcher thread.
14+
// If it is not found, then create it and store it in the context.Properties().
15+
// Make sure that the JSI runtime holder is removed when the instance is unloaded.
16+
facebook::jsi::Runtime &GetOrCreateContextRuntime(ReactContext const &context) noexcept {
17+
ReactDispatcher jsDispatcher = context.JSDispatcher();
18+
VerifyElseCrashSz(jsDispatcher.HasThreadAccess(), "Must be in JS thread");
19+
20+
// The JSI runtime is not available if we do Web debugging when JS is running in web browser.
21+
JsiRuntime abiJsiRuntime = context.Handle().JSRuntime().as<JsiRuntime>();
22+
VerifyElseCrashSz(abiJsiRuntime, "JSI runtime is not available");
23+
24+
// See if the JSI runtime was previously created.
25+
JsiAbiRuntime *runtime = JsiAbiRuntime::GetFromJsiRuntime(abiJsiRuntime);
26+
if (!runtime) {
27+
// Create the runtime
28+
std::unique_ptr<JsiAbiRuntime> runtimeHolder = std::make_unique<JsiAbiRuntime>(abiJsiRuntime);
29+
runtime = runtimeHolder.get();
30+
31+
// We want to keep the JSI runtime while current instance is alive.
32+
// The JSI runtime object must be local to our DLL.
33+
// We create a property name based on the current DLL handle.
34+
HMODULE currentDllHanlde = reinterpret_cast<HMODULE>(&__ImageBase);
35+
std::wstring jsiRuntimeLocalName = L"jsiRuntime_" + std::to_wstring(reinterpret_cast<uintptr_t>(currentDllHanlde));
36+
using ValueType = ReactNonAbiValue<std::unique_ptr<JsiAbiRuntime>>;
37+
ReactPropertyId<ValueType> jsiRuntimeProperty{L"ReactNative.InstanceData", jsiRuntimeLocalName.c_str()};
38+
ValueType runtimeValue{std::in_place, std::move(runtimeHolder)};
39+
context.Properties().Set(jsiRuntimeProperty, runtimeValue);
40+
41+
// We remove the JSI runtime from properties when React instance is destroyed.
42+
auto destroyInstanceNotificationId{
43+
ReactNotificationId<InstanceDestroyedEventArgs>{L"ReactNative.InstanceSettings", L"InstanceDestroyed"}};
44+
context.Notifications().Subscribe(
45+
destroyInstanceNotificationId,
46+
jsDispatcher,
47+
[context, jsiRuntimeProperty](
48+
winrt::Windows::Foundation::IInspectable const & /*sender*/,
49+
ReactNotificationArgs<InstanceDestroyedEventArgs> const &args) noexcept {
50+
context.Properties().Remove(jsiRuntimeProperty);
51+
args.Subscription().Unsubscribe(); // Unsubscribe after we handle the notification.
52+
});
53+
}
54+
55+
return *runtime;
56+
}
57+
58+
} // namespace winrt::Microsoft::ReactNative

vnext/Microsoft.ReactNative.Cxx/JSI/JsiApiContext.h

Lines changed: 2 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -8,62 +8,18 @@
88
#include "../ReactContext.h"
99
#include "JsiAbiApi.h"
1010

11-
// Use __ImageBase to get current DLL handle.
12-
// http://blogs.msdn.com/oldnewthing/archive/2004/10/25/247180.aspx
13-
extern "C" IMAGE_DOS_HEADER __ImageBase;
14-
1511
namespace winrt::Microsoft::ReactNative {
1612

1713
// Get JSI Runtime from the current JS dispatcher thread.
1814
// If it is not found, then create it and store it in the context.Properties().
1915
// Make sure that the JSI runtime holder is removed when the instance is unloaded.
20-
inline facebook::jsi::Runtime &GetOrCreateContextRuntime(ReactContext const &context) noexcept {
21-
ReactDispatcher jsDispatcher = context.JSDispatcher();
22-
VerifyElseCrashSz(jsDispatcher.HasThreadAccess(), "Must be in JS thread");
23-
24-
// The JSI runtime is not available if we do Web debugging when JS is running in web browser.
25-
JsiRuntime abiJsiRuntime = context.Handle().JSRuntime().as<JsiRuntime>();
26-
VerifyElseCrashSz(abiJsiRuntime, "JSI runtime is not available");
27-
28-
// See if the JSI runtime was previously created.
29-
JsiAbiRuntime *runtime = JsiAbiRuntime::GetFromJsiRuntime(abiJsiRuntime);
30-
if (!runtime) {
31-
// Create the runtime
32-
std::unique_ptr<JsiAbiRuntime> runtimeHolder = std::make_unique<JsiAbiRuntime>(abiJsiRuntime);
33-
runtime = runtimeHolder.get();
34-
35-
// We want to keep the JSI runtime while current instance is alive.
36-
// The JSI runtime object must be local to our DLL.
37-
// We create a property name based on the current DLL handle.
38-
HMODULE currentDllHanlde = reinterpret_cast<HMODULE>(&__ImageBase);
39-
std::wstring jsiRuntimeLocalName = L"jsiRuntime_" + std::to_wstring(reinterpret_cast<uintptr_t>(currentDllHanlde));
40-
using ValueType = ReactNonAbiValue<std::unique_ptr<JsiAbiRuntime>>;
41-
ReactPropertyId<ValueType> jsiRuntimeProperty{L"ReactNative.InstanceData", jsiRuntimeLocalName.c_str()};
42-
ValueType runtimeValue{std::in_place, std::move(runtimeHolder)};
43-
context.Properties().Set(jsiRuntimeProperty, runtimeValue);
44-
45-
// We remove the JSI runtime from properties when React instance is destroyed.
46-
auto destroyInstanceNotificationId{
47-
ReactNotificationId<InstanceDestroyedEventArgs>{L"ReactNative.InstanceSettings", L"InstanceDestroyed"}};
48-
context.Notifications().Subscribe(
49-
destroyInstanceNotificationId,
50-
jsDispatcher,
51-
[ context, jsiRuntimeProperty ](
52-
winrt::Windows::Foundation::IInspectable const & /*sender*/,
53-
ReactNotificationArgs<InstanceDestroyedEventArgs> const &args) noexcept {
54-
context.Properties().Remove(jsiRuntimeProperty);
55-
args.Subscription().Unsubscribe(); // Unsubscribe after we handle the notification.
56-
});
57-
}
58-
59-
return *runtime;
60-
}
16+
facebook::jsi::Runtime &GetOrCreateContextRuntime(ReactContext const &context) noexcept;
6117

6218
// Call provided lambda with the facebook::jsi::Runtime& parameter.
6319
// For example: ExecuteJsi(context, [](facebook::jsi::Runtime& runtime){...})
6420
// The code is executed synchronously if it is already in JSDispatcher, or asynchronously otherwise.
6521
template <class TCodeWithRuntime>
66-
inline void ExecuteJsi(ReactContext const &context, TCodeWithRuntime const &code) {
22+
void ExecuteJsi(ReactContext const &context, TCodeWithRuntime const &code) {
6723
ReactDispatcher jsDispatcher = context.JSDispatcher();
6824
if (jsDispatcher.HasThreadAccess()) {
6925
// Execute immediately if we are in JS thread.

vnext/Microsoft.ReactNative.Cxx/Microsoft.ReactNative.Cxx.vcxitems

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,12 +87,14 @@
8787
<ClCompile Include="$(JSI_SourcePath)\jsi\jsi.cpp">
8888
<PrecompiledHeader>NotUsing</PrecompiledHeader>
8989
</ClCompile>
90+
<ClCompile Include="$(MSBuildThisFileDirectory)JSI\JsiAbiApi.cpp" />
91+
<ClCompile Include="$(MSBuildThisFileDirectory)JSI\JsiApiContext.cpp" />
9092
<ClCompile Include="$(MSBuildThisFileDirectory)JSValue.cpp" />
9193
<ClCompile Include="$(MSBuildThisFileDirectory)JSValueTreeReader.cpp" />
9294
<ClCompile Include="$(MSBuildThisFileDirectory)JSValueTreeWriter.cpp" />
9395
<ClCompile Include="$(MSBuildThisFileDirectory)ModuleRegistration.cpp" />
9496
<ClCompile Include="$(MSBuildThisFileDirectory)ReactPromise.cpp" />
95-
<ClCompile Include="$(MSBuildThisFileDirectory)JSI\JsiAbiApi.cpp" />
97+
<ClCompile Include="$(MSBuildThisFileDirectory)TurboModuleProvider.cpp" />
9698
<ClCompile Include="$(TurboModule_SourcePath)\ReactCommon\LongLivedObject.cpp">
9799
<PrecompiledHeader>NotUsing</PrecompiledHeader>
98100
</ClCompile>

vnext/Microsoft.ReactNative.Cxx/Microsoft.ReactNative.Cxx.vcxitems.filters

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,21 @@
1212
<ClCompile Include="$(MSBuildThisFileDirectory)JSI\JsiAbiApi.cpp">
1313
<Filter>JSI</Filter>
1414
</ClCompile>
15-
<ClCompile Include="$(ReactNativeDir)\ReactCommon\react\nativemodule\core\ReactCommon\TurboModule.cpp">
15+
<ClCompile Include="$(MSBuildThisFileDirectory)ReactCommon\TurboModuleUtils.cpp">
1616
<Filter>TurboModule</Filter>
1717
</ClCompile>
18-
<ClCompile Include="$(ReactNativeDir)\ReactCommon\react\nativemodule\core\ReactCommon\LongLivedObject.cpp">
18+
<ClCompile Include="$(MSBuildThisFileDirectory)TurboModuleProvider.cpp">
1919
<Filter>TurboModule</Filter>
2020
</ClCompile>
21-
<ClCompile Include="$(MSBuildThisFileDirectory)ReactCommon\TurboModuleUtils.cpp">
21+
<ClCompile Include="$(TurboModule_SourcePath)\ReactCommon\TurboModule.cpp">
22+
<Filter>TurboModule</Filter>
23+
</ClCompile>
24+
<ClCompile Include="$(TurboModule_SourcePath)\ReactCommon\LongLivedObject.cpp">
2225
<Filter>TurboModule</Filter>
2326
</ClCompile>
27+
<ClCompile Include="$(MSBuildThisFileDirectory)JSI\JsiApiContext.cpp">
28+
<Filter>JSI</Filter>
29+
</ClCompile>
2430
</ItemGroup>
2531
<ItemGroup>
2632
<ClInclude Include="$(MSBuildThisFileDirectory)Crash.h" />
@@ -121,15 +127,6 @@
121127
<ClInclude Include="$(JSI_SourcePath)\jsi\instrumentation.h">
122128
<Filter>JSI</Filter>
123129
</ClInclude>
124-
<ClInclude Include="$(ReactNativeDir)\ReactCommon\react\nativemodule\core\ReactCommon\TurboModule.h">
125-
<Filter>TurboModule</Filter>
126-
</ClInclude>
127-
<ClInclude Include="$(ReactNativeDir)\ReactCommon\callinvoker\ReactCommon\CallInvoker.h">
128-
<Filter>TurboModule</Filter>
129-
</ClInclude>
130-
<ClInclude Include="$(ReactNativeDir)\ReactCommon\react\nativemodule\core\ReactCommon\LongLivedObject.h">
131-
<Filter>TurboModule</Filter>
132-
</ClInclude>
133130
<ClInclude Include="$(MSBuildThisFileDirectory)TurboModuleProvider.h">
134131
<Filter>TurboModule</Filter>
135132
</ClInclude>
@@ -139,6 +136,13 @@
139136
<ClInclude Include="$(MSBuildThisFileDirectory)JSI\JsiApiContext.h">
140137
<Filter>JSI</Filter>
141138
</ClInclude>
139+
<ClInclude Include="$(CallInvoker_SourcePath)\ReactCommon\CallInvoker.h" />
140+
<ClInclude Include="$(TurboModule_SourcePath)\ReactCommon\TurboModule.h">
141+
<Filter>TurboModule</Filter>
142+
</ClInclude>
143+
<ClInclude Include="$(TurboModule_SourcePath)\ReactCommon\LongLivedObject.h">
144+
<Filter>TurboModule</Filter>
145+
</ClInclude>
142146
</ItemGroup>
143147
<ItemGroup>
144148
<Filter Include="JSI">

vnext/Microsoft.ReactNative.Cxx/ReactCommon/TurboModuleUtils.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
#include <cassert>
1313
#include <string>
1414

15-
// RNW changes: commended out the unused include that creates unnecessary dependency on folly
15+
// RNW changes: commented out the unused include that creates unnecessary dependency on Folly.
1616
//#include <folly/Optional.h>
1717
#include <jsi/jsi.h>
1818

vnext/Microsoft.ReactNative.Cxx/ReactPropertyBag.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@
7171
//
7272

7373
#include <winrt/Microsoft.ReactNative.h>
74+
#include <winrt/Windows.Foundation.h>
7475
#include <optional>
7576
#include "ReactHandleHelper.h"
7677
#include "ReactNonAbiValue.h"
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT License.
3+
4+
#include "pch.h"
5+
#include "TurboModuleProvider.h"
6+
7+
namespace winrt::Microsoft::ReactNative {
8+
9+
// CallInvoker implementation based on JSDispatcher.
10+
struct AbiCallInvoker final : facebook::react::CallInvoker {
11+
AbiCallInvoker(IReactDispatcher const &jsDispatcher) : m_jsDispatcher(jsDispatcher) {}
12+
13+
void invokeAsync(std::function<void()> &&func) override {
14+
m_jsDispatcher.Post([func = std::move(func)]() { func(); });
15+
}
16+
17+
void invokeSync(std::function<void()> &&func) override {
18+
if (m_jsDispatcher.HasThreadAccess()) {
19+
func();
20+
} else {
21+
std::mutex mutex;
22+
std::condition_variable cv;
23+
bool completed{false};
24+
std::exception_ptr ex;
25+
26+
auto lock = std::unique_lock{mutex};
27+
28+
m_jsDispatcher.Post([&func, &mutex, &cv, &completed, &ex]() {
29+
// Since this method is synchronous, we catch all func exceptions and rethrow them in this thread.
30+
try {
31+
func();
32+
} catch (...) {
33+
ex = std::current_exception();
34+
}
35+
36+
auto lock = std::unique_lock{mutex};
37+
completed = true;
38+
cv.notify_all();
39+
});
40+
41+
cv.wait(lock, [&] { return completed; });
42+
43+
if (ex) {
44+
std::rethrow_exception(ex);
45+
}
46+
}
47+
48+
// Since func is passed as an r-value, we want to clean it up in this method as we would move the value.
49+
func = nullptr;
50+
}
51+
52+
private:
53+
IReactDispatcher m_jsDispatcher{nullptr};
54+
};
55+
56+
// Creates CallInvoker based on JSDispatcher.
57+
std::shared_ptr<facebook::react::CallInvoker> MakeAbiCallInvoker(IReactDispatcher const &jsDispatcher) noexcept {
58+
return std::make_shared<AbiCallInvoker>(jsDispatcher);
59+
}
60+
61+
} // namespace winrt::Microsoft::ReactNative

0 commit comments

Comments
 (0)