react-native-windows 0.80.1 → 0.80.6
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/Directory.Build.props +1 -1
- package/Microsoft.ReactNative/Fabric/Composition/DebuggerUIIsland.cpp +169 -0
- package/Microsoft.ReactNative/Fabric/Composition/DebuggerUIIsland.h +42 -0
- package/Microsoft.ReactNative/Fabric/Composition/DebuggingOverlayComponentView.cpp +1 -1
- package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.cpp +60 -33
- package/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.cpp +68 -1
- package/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.h +9 -0
- package/Microsoft.ReactNative/Fabric/Composition/UriImageManager.cpp +5 -3
- package/Microsoft.ReactNative/Fabric/FabricUIManagerModule.cpp +6 -1
- package/Microsoft.ReactNative/Fabric/WindowsImageManager.cpp +14 -1
- package/Microsoft.ReactNative/Fabric/platform/react/threading/TaskDispatchThread.cpp +75 -24
- package/Microsoft.ReactNative/Fabric/platform/react/threading/TaskDispatchThread.h +4 -25
- package/Microsoft.ReactNative/JsiApi.cpp +1 -1
- package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj +1 -0
- package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj.filters +3 -0
- package/Microsoft.ReactNative/ReactHost/DebuggerNotifications.h +54 -0
- package/Microsoft.ReactNative/ReactHost/React.h +11 -4
- package/Microsoft.ReactNative/ReactHost/ReactHost.cpp +195 -29
- package/Microsoft.ReactNative/ReactHost/ReactHost.h +22 -4
- package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp +24 -5
- package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.h +1 -1
- package/Microsoft.ReactNative/ReactRootView.cpp +108 -0
- package/Microsoft.ReactNative/ReactRootView.h +6 -0
- package/Microsoft.ReactNative/Views/DevMenu.cpp +1 -1
- package/Microsoft.ReactNative.Cxx/JSI/decorator.h +41 -0
- package/Microsoft.ReactNative.Cxx/JSI/jsi-inl.h +16 -0
- package/Microsoft.ReactNative.Cxx/JSI/jsi.cpp +125 -0
- package/Microsoft.ReactNative.Cxx/JSI/jsi.h +167 -1
- package/Microsoft.ReactNative.Cxx/Microsoft.ReactNative.Cxx.vcxitems +1 -1
- package/Microsoft.ReactNative.Cxx/NodeApiJsiRuntime.cpp +110 -38
- package/Microsoft.ReactNative.Cxx/node-api/js_native_api.h +44 -31
- package/Microsoft.ReactNative.Cxx/node-api/js_native_api_types.h +13 -14
- package/Microsoft.ReactNative.Cxx/node-api/js_runtime_api.h +19 -4
- package/Microsoft.ReactNative.Cxx/node-api/node_api.h +270 -0
- package/Microsoft.ReactNative.Cxx/node-api/node_api_types.h +52 -0
- package/PropertySheets/Generated/PackageVersion.g.props +3 -3
- package/PropertySheets/JSEngine.props +1 -1
- package/PropertySheets/React.Cpp.props +2 -2
- package/ReactCommon/ReactCommon.vcxproj +18 -1
- package/ReactCommon/TEMP_UntilReactCommonUpdate/cxxreact/NativeToJsBridge.cpp +1 -1
- package/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/test/testlib.cpp +4 -4
- package/ReactCommon/TEMP_UntilReactCommonUpdate/jsinspector-modern/NetworkIOAgent.cpp +23 -9
- package/ReactCommon/TEMP_UntilReactCommonUpdate/jsinspector-modern/NetworkIOAgent.h +16 -0
- package/ReactCommon/cgmanifest.json +1 -1
- package/Scripts/Tfs/Layout-MSRN-Headers.ps1 +2 -0
- package/Shared/DevServerHelper.h +13 -3
- package/Shared/DevSettings.h +7 -0
- package/Shared/DevSupportManager.cpp +79 -20
- package/Shared/DevSupportManager.h +7 -19
- package/Shared/Hermes/HermesRuntimeAgentDelegate.cpp +99 -0
- package/Shared/Hermes/HermesRuntimeAgentDelegate.h +81 -0
- package/Shared/Hermes/HermesRuntimeTargetDelegate.cpp +263 -0
- package/Shared/Hermes/HermesRuntimeTargetDelegate.h +77 -0
- package/Shared/HermesRuntimeHolder.cpp +29 -111
- package/Shared/HermesRuntimeHolder.h +214 -32
- package/Shared/IDevSupportManager.h +5 -2
- package/Shared/Inspector/ReactInspectorPackagerConnectionDelegate.cpp +108 -0
- package/Shared/Inspector/ReactInspectorPackagerConnectionDelegate.h +19 -0
- package/Shared/Inspector/ReactInspectorThread.h +18 -0
- package/Shared/JSI/RuntimeHolder.h +5 -2
- package/Shared/OInstance.cpp +44 -27
- package/Shared/Shared.vcxitems +27 -17
- package/Shared/Shared.vcxitems.filters +33 -15
- package/package.json +5 -5
- package/ReactCommon/TEMP_UntilReactCommonUpdate/cxxreact/JSExecutor.cpp +0 -78
- package/ReactCommon/TEMP_UntilReactCommonUpdate/cxxreact/JSExecutor.h +0 -196
- package/ReactCommon/TEMP_UntilReactCommonUpdate/jserrorhandler/JsErrorHandler.cpp +0 -429
- package/ReactCommon/TEMP_UntilReactCommonUpdate/jsitooling/react/runtime/JSRuntimeFactory.cpp +0 -45
- package/ReactCommon/TEMP_UntilReactCommonUpdate/jsitooling/react/runtime/JSRuntimeFactory.h +0 -91
- package/ReactCommon/TEMP_UntilReactCommonUpdate/react/runtime/ReactInstance.cpp +0 -670
- package/Shared/InspectorPackagerConnection.cpp +0 -232
- package/Shared/InspectorPackagerConnection.h +0 -61
- /package/Shared/{HermesSamplingProfiler.cpp → Hermes/HermesSamplingProfiler.cpp} +0 -0
- /package/Shared/{HermesSamplingProfiler.h → Hermes/HermesSamplingProfiler.h} +0 -0
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
#pragma once
|
|
5
5
|
|
|
6
|
+
#include <jsinspector-modern/HostTarget.h>
|
|
6
7
|
#include <mutex>
|
|
7
8
|
#include <unordered_map>
|
|
8
9
|
#include "AsyncActionQueue.h"
|
|
@@ -15,6 +16,7 @@
|
|
|
15
16
|
|
|
16
17
|
namespace Mso::React {
|
|
17
18
|
|
|
19
|
+
class ReactInspectorHostTargetDelegate;
|
|
18
20
|
class ReactViewHost;
|
|
19
21
|
|
|
20
22
|
//! ReactHost manages lifetime of ReactNative instance.
|
|
@@ -52,9 +54,6 @@ class ReactHost final : public Mso::ActiveObject<IReactHost> {
|
|
|
52
54
|
|
|
53
55
|
Mso::CntPtr<AsyncActionQueue> ActionQueue() const noexcept;
|
|
54
56
|
|
|
55
|
-
Mso::Future<void> LoadInQueue(ReactOptions &&options) noexcept;
|
|
56
|
-
Mso::Future<void> UnloadInQueue(size_t unloadActionId) noexcept;
|
|
57
|
-
|
|
58
57
|
void Close() noexcept;
|
|
59
58
|
bool IsClosed() const noexcept;
|
|
60
59
|
|
|
@@ -64,6 +63,12 @@ class ReactHost final : public Mso::ActiveObject<IReactHost> {
|
|
|
64
63
|
template <class TCallback>
|
|
65
64
|
Mso::Future<void> PostInQueue(TCallback &&callback) noexcept;
|
|
66
65
|
|
|
66
|
+
private:
|
|
67
|
+
enum class UnloadReason {
|
|
68
|
+
Unload,
|
|
69
|
+
CloseHost,
|
|
70
|
+
};
|
|
71
|
+
|
|
67
72
|
private:
|
|
68
73
|
friend MakePolicy;
|
|
69
74
|
ReactHost(Mso::DispatchQueue const &queue) noexcept;
|
|
@@ -75,9 +80,18 @@ class ReactHost final : public Mso::ActiveObject<IReactHost> {
|
|
|
75
80
|
void ForEachViewHost(const Mso::FunctorRef<void(ReactViewHost &)> &action) noexcept;
|
|
76
81
|
|
|
77
82
|
AsyncAction MakeLoadInstanceAction(ReactOptions &&options) noexcept;
|
|
78
|
-
AsyncAction MakeUnloadInstanceAction() noexcept;
|
|
83
|
+
AsyncAction MakeUnloadInstanceAction(UnloadReason reason) noexcept;
|
|
84
|
+
|
|
85
|
+
Mso::Future<void> LoadInQueue(ReactOptions &&options) noexcept;
|
|
86
|
+
Mso::Future<void> UnloadInQueue(UnloadReason reason, size_t unloadActionId) noexcept;
|
|
87
|
+
|
|
88
|
+
void OnDebuggerResume() noexcept;
|
|
89
|
+
bool IsInspectable() noexcept;
|
|
90
|
+
void AddInspectorPage() noexcept;
|
|
91
|
+
void RemoveInspectorPage() noexcept;
|
|
79
92
|
|
|
80
93
|
private:
|
|
94
|
+
friend class ReactInspectorHostTargetDelegate;
|
|
81
95
|
mutable std::mutex m_mutex;
|
|
82
96
|
const Mso::InvokeElsePostExecutor m_executor{Queue()};
|
|
83
97
|
const Mso::ActiveReadableField<Mso::CntPtr<AsyncActionQueue>> m_actionQueue{
|
|
@@ -92,6 +106,10 @@ class ReactHost final : public Mso::ActiveObject<IReactHost> {
|
|
|
92
106
|
size_t m_pendingUnloadActionId{0};
|
|
93
107
|
size_t m_nextUnloadActionId{0};
|
|
94
108
|
const Mso::ActiveField<bool> m_isInstanceUnloading{false, Queue()};
|
|
109
|
+
|
|
110
|
+
const std::shared_ptr<facebook::react::jsinspector_modern::HostTargetDelegate> m_inspectorHostTargetDelegate;
|
|
111
|
+
const std::shared_ptr<facebook::react::jsinspector_modern::HostTarget> m_inspectorHostTarget;
|
|
112
|
+
const Mso::ActiveField<std::optional<int32_t>> m_inspectorPageId{Queue()};
|
|
95
113
|
};
|
|
96
114
|
|
|
97
115
|
//! Implements a cross-platform host for a React view
|
|
@@ -66,6 +66,7 @@
|
|
|
66
66
|
#include <react/runtime/PlatformTimerRegistry.h>
|
|
67
67
|
#include <react/runtime/TimerManager.h>
|
|
68
68
|
#include <react/threading/MessageQueueThreadImpl.h>
|
|
69
|
+
#include "Inspector/ReactInspectorThread.h"
|
|
69
70
|
#endif
|
|
70
71
|
|
|
71
72
|
#if !defined(CORE_ABI) && !defined(USE_FABRIC)
|
|
@@ -553,6 +554,8 @@ std::shared_ptr<facebook::react::DevSettings> ReactInstanceWin::CreateDevSetting
|
|
|
553
554
|
|
|
554
555
|
devSettings->useRuntimeScheduler = useRuntimeScheduler;
|
|
555
556
|
|
|
557
|
+
devSettings->inspectorHostTarget = m_options.InspectorHostTarget;
|
|
558
|
+
|
|
556
559
|
return devSettings;
|
|
557
560
|
}
|
|
558
561
|
|
|
@@ -664,16 +667,21 @@ void ReactInstanceWin::InitializeBridgeless() noexcept {
|
|
|
664
667
|
};
|
|
665
668
|
|
|
666
669
|
if (devSettings->useDirectDebugger) {
|
|
667
|
-
::Microsoft::ReactNative::GetSharedDevManager()->
|
|
668
|
-
devSettings->sourceBundleHost, devSettings->sourceBundlePort);
|
|
670
|
+
::Microsoft::ReactNative::GetSharedDevManager()->EnsureInspectorPackagerConnection(
|
|
671
|
+
devSettings->sourceBundleHost, devSettings->sourceBundlePort, devSettings->bundleAppId);
|
|
669
672
|
}
|
|
670
673
|
|
|
671
674
|
m_jsiRuntimeHolder = std::make_shared<Microsoft::ReactNative::HermesRuntimeHolder>(
|
|
672
675
|
devSettings, jsMessageThread, CreatePreparedScriptStore());
|
|
673
676
|
auto jsRuntime = std::make_unique<Microsoft::ReactNative::HermesJSRuntime>(m_jsiRuntimeHolder);
|
|
674
677
|
jsRuntime->getRuntime();
|
|
675
|
-
|
|
676
|
-
|
|
678
|
+
|
|
679
|
+
m_bridgelessReactInstance = std::make_shared<facebook::react::ReactInstance>(
|
|
680
|
+
std::move(jsRuntime),
|
|
681
|
+
jsMessageThread,
|
|
682
|
+
timerManager,
|
|
683
|
+
jsErrorHandlingFunc,
|
|
684
|
+
m_options.InspectorHostTarget);
|
|
677
685
|
|
|
678
686
|
auto bufferedRuntimeExecutor = m_bridgelessReactInstance->getBufferedRuntimeExecutor();
|
|
679
687
|
timerManager->setRuntimeExecutor(bufferedRuntimeExecutor);
|
|
@@ -695,6 +703,7 @@ void ReactInstanceWin::InitializeBridgeless() noexcept {
|
|
|
695
703
|
winrt::make<implementation::ReactContext>(Mso::Copy(m_reactContext)));
|
|
696
704
|
|
|
697
705
|
facebook::react::ReactInstance::JSRuntimeFlags options;
|
|
706
|
+
|
|
698
707
|
m_bridgelessReactInstance->initializeRuntime(
|
|
699
708
|
options,
|
|
700
709
|
[=, onCreated = m_options.OnInstanceCreated, reactContext = m_reactContext](
|
|
@@ -748,7 +757,6 @@ void ReactInstanceWin::InitializeBridgeless() noexcept {
|
|
|
748
757
|
|
|
749
758
|
LoadJSBundlesBridgeless(devSettings);
|
|
750
759
|
SetupHMRClient();
|
|
751
|
-
|
|
752
760
|
} catch (std::exception &e) {
|
|
753
761
|
OnErrorWithMessage(e.what());
|
|
754
762
|
OnErrorWithMessage("ReactInstanceWin: Failed to create React Instance.");
|
|
@@ -1092,6 +1100,17 @@ Mso::Future<void> ReactInstanceWin::Destroy() noexcept {
|
|
|
1092
1100
|
if (m_bridgelessReactInstance) {
|
|
1093
1101
|
if (auto jsMessageThread = m_jsMessageThread.Exchange(nullptr)) {
|
|
1094
1102
|
jsMessageThread->runOnQueueSync([&]() noexcept {
|
|
1103
|
+
// Unregister from inspector BEFORE shutting down JS thread
|
|
1104
|
+
if (m_bridgelessReactInstance && m_options.InspectorHostTarget) {
|
|
1105
|
+
Mso::React::MessageDispatchQueue messageDispatchQueue{
|
|
1106
|
+
::Microsoft::ReactNative::ReactInspectorThread::Instance(), nullptr};
|
|
1107
|
+
messageDispatchQueue.runOnQueueSync(
|
|
1108
|
+
[weakBridgelessReactInstance = std::weak_ptr(m_bridgelessReactInstance)]() {
|
|
1109
|
+
if (auto bridgelessReactInstance = weakBridgelessReactInstance.lock()) {
|
|
1110
|
+
bridgelessReactInstance->unregisterFromInspector();
|
|
1111
|
+
}
|
|
1112
|
+
});
|
|
1113
|
+
}
|
|
1095
1114
|
{
|
|
1096
1115
|
// Release the JSI runtime
|
|
1097
1116
|
std::scoped_lock lock{m_mutex};
|
|
@@ -205,7 +205,7 @@ class ReactInstanceWin final : public Mso::ActiveObject<IReactInstanceInternal>
|
|
|
205
205
|
|
|
206
206
|
#ifdef USE_FABRIC
|
|
207
207
|
// Bridgeless
|
|
208
|
-
std::
|
|
208
|
+
std::shared_ptr<facebook::react::ReactInstance> m_bridgelessReactInstance;
|
|
209
209
|
#endif
|
|
210
210
|
|
|
211
211
|
std::atomic<ReactInstanceState> m_state{ReactInstanceState::Loading};
|
|
@@ -5,14 +5,19 @@
|
|
|
5
5
|
#include "ReactRootView.g.cpp"
|
|
6
6
|
|
|
7
7
|
#include <QuirkSettings.h>
|
|
8
|
+
#include <ReactHost/DebuggerNotifications.h>
|
|
8
9
|
#include <ReactHost/MsoUtils.h>
|
|
10
|
+
#include <UI.Text.h>
|
|
11
|
+
#include <UI.Xaml.Controls.Primitives.h>
|
|
9
12
|
#include <UI.Xaml.Input.h>
|
|
10
13
|
#include <UI.Xaml.Media.Media3D.h>
|
|
11
14
|
#include <Utils/Helpers.h>
|
|
12
15
|
#include <dispatchQueue/dispatchQueue.h>
|
|
13
16
|
#include <winrt/Windows.UI.Core.h>
|
|
17
|
+
#include "InstanceManager.h"
|
|
14
18
|
#include "ReactNativeHost.h"
|
|
15
19
|
#include "ReactViewInstance.h"
|
|
20
|
+
#include "Utils/KeyboardUtils.h"
|
|
16
21
|
#include "XamlUtils.h"
|
|
17
22
|
|
|
18
23
|
#include <winrt/Microsoft.UI.Xaml.Controls.h>
|
|
@@ -34,6 +39,7 @@ ReactRootView::ReactRootView() noexcept : m_uiQueue(Mso::DispatchQueue::GetCurre
|
|
|
34
39
|
UpdatePerspective();
|
|
35
40
|
Loaded([this](auto &&, auto &&) {
|
|
36
41
|
::Microsoft::ReactNative::SetCompositor(::Microsoft::ReactNative::GetCompositor(*this));
|
|
42
|
+
SetupDevToolsShortcut();
|
|
37
43
|
});
|
|
38
44
|
}
|
|
39
45
|
|
|
@@ -45,6 +51,20 @@ void ReactRootView::ReactNativeHost(ReactNative::ReactNativeHost const &value) n
|
|
|
45
51
|
if (m_reactNativeHost != value) {
|
|
46
52
|
ReactViewHost(nullptr);
|
|
47
53
|
m_reactNativeHost = value;
|
|
54
|
+
const auto weakThis = this->get_weak();
|
|
55
|
+
::Microsoft::ReactNative::DebuggerNotifications::SubscribeShowDebuggerPausedOverlay(
|
|
56
|
+
m_reactNativeHost.InstanceSettings().Notifications(),
|
|
57
|
+
m_reactNativeHost.InstanceSettings().UIDispatcher(),
|
|
58
|
+
[weakThis](std::string message, std::function<void()> onResume) {
|
|
59
|
+
if (auto strongThis = weakThis.get()) {
|
|
60
|
+
strongThis->ShowDebuggerPausedOverlay(message, onResume);
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
[weakThis]() {
|
|
64
|
+
if (auto strongThis = weakThis.get()) {
|
|
65
|
+
strongThis->HideDebuggerPausedOverlay();
|
|
66
|
+
}
|
|
67
|
+
});
|
|
48
68
|
ReloadView();
|
|
49
69
|
}
|
|
50
70
|
}
|
|
@@ -283,6 +303,65 @@ void ReactRootView::EnsureLoadingUI() noexcept {
|
|
|
283
303
|
}
|
|
284
304
|
}
|
|
285
305
|
|
|
306
|
+
void ReactRootView::HideDebuggerPausedOverlay() noexcept {
|
|
307
|
+
m_isDebuggerPausedOverlayOpen = false;
|
|
308
|
+
if (m_debuggerPausedFlyout) {
|
|
309
|
+
m_debuggerPausedFlyout.Hide();
|
|
310
|
+
m_debuggerPausedFlyout = nullptr;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
void ReactRootView::ShowDebuggerPausedOverlay(
|
|
315
|
+
const std::string &message,
|
|
316
|
+
const std::function<void()> &onResume) noexcept {
|
|
317
|
+
// Initialize content
|
|
318
|
+
const xaml::Controls::Grid contentGrid;
|
|
319
|
+
xaml::Controls::ColumnDefinition messageColumnDefinition;
|
|
320
|
+
xaml::Controls::ColumnDefinition buttonColumnDefinition;
|
|
321
|
+
messageColumnDefinition.MinWidth(60);
|
|
322
|
+
buttonColumnDefinition.MinWidth(36);
|
|
323
|
+
contentGrid.ColumnDefinitions().Append(messageColumnDefinition);
|
|
324
|
+
contentGrid.ColumnDefinitions().Append(buttonColumnDefinition);
|
|
325
|
+
xaml::Controls::TextBlock messageBlock;
|
|
326
|
+
messageBlock.Text(winrt::to_hstring(message));
|
|
327
|
+
messageBlock.FontWeight(winrt::Windows::UI::Text::FontWeights::SemiBold());
|
|
328
|
+
xaml::Controls::FontIcon resumeGlyph;
|
|
329
|
+
resumeGlyph.FontFamily(xaml::Media::FontFamily(L"Segoe MDL2 Assets"));
|
|
330
|
+
resumeGlyph.Foreground(xaml::Media::SolidColorBrush(winrt::Colors::Green()));
|
|
331
|
+
resumeGlyph.Glyph(L"\uF5B0");
|
|
332
|
+
resumeGlyph.HorizontalAlignment(xaml::HorizontalAlignment::Right);
|
|
333
|
+
resumeGlyph.PointerReleased([onResume](auto &&...) { onResume(); });
|
|
334
|
+
xaml::Controls::Grid::SetColumn(resumeGlyph, 1);
|
|
335
|
+
contentGrid.Children().Append(messageBlock);
|
|
336
|
+
contentGrid.Children().Append(resumeGlyph);
|
|
337
|
+
|
|
338
|
+
// Configure flyout
|
|
339
|
+
m_isDebuggerPausedOverlayOpen = true;
|
|
340
|
+
xaml::Style flyoutStyle(
|
|
341
|
+
{XAML_NAMESPACE_STR L".Controls.FlyoutPresenter", winrt::Windows::UI::Xaml::Interop::TypeKind::Metadata});
|
|
342
|
+
flyoutStyle.Setters().Append(winrt::Setter(
|
|
343
|
+
xaml::Controls::Control::CornerRadiusProperty(), winrt::box_value(xaml::CornerRadius{12, 12, 12, 12})));
|
|
344
|
+
flyoutStyle.Setters().Append(winrt::Setter(
|
|
345
|
+
xaml::Controls::Control::BackgroundProperty(),
|
|
346
|
+
winrt::box_value(xaml::Media::SolidColorBrush{FromArgb(255, 255, 255, 193)})));
|
|
347
|
+
flyoutStyle.Setters().Append(
|
|
348
|
+
winrt::Setter(xaml::FrameworkElement::MarginProperty(), winrt::box_value(xaml::Thickness{0, 12, 0, 0})));
|
|
349
|
+
m_debuggerPausedFlyout = xaml::Controls::Flyout{};
|
|
350
|
+
m_debuggerPausedFlyout.FlyoutPresenterStyle(flyoutStyle);
|
|
351
|
+
m_debuggerPausedFlyout.LightDismissOverlayMode(xaml::Controls::LightDismissOverlayMode::On);
|
|
352
|
+
m_debuggerPausedFlyout.Content(contentGrid);
|
|
353
|
+
|
|
354
|
+
// Disable light dismiss
|
|
355
|
+
m_debuggerPausedFlyout.Closing([weakThis = this->get_weak()](auto &&, const auto &args) {
|
|
356
|
+
if (auto strongThis = weakThis.get()) {
|
|
357
|
+
args.Cancel(strongThis->m_isDebuggerPausedOverlayOpen);
|
|
358
|
+
}
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
// Show flyout
|
|
362
|
+
m_debuggerPausedFlyout.ShowAt(*this);
|
|
363
|
+
}
|
|
364
|
+
|
|
286
365
|
void ReactRootView::ShowInstanceLoaded() noexcept {
|
|
287
366
|
if (m_xamlRootView) {
|
|
288
367
|
ClearLoadingUI();
|
|
@@ -481,4 +560,33 @@ void ReactRootView::RemoveChildAt(uint32_t index) {
|
|
|
481
560
|
Children().RemoveAt(RNIndexToXamlIndex(index));
|
|
482
561
|
}
|
|
483
562
|
|
|
563
|
+
bool IsCtrlShiftI(winrt::Windows::System::VirtualKey key) noexcept {
|
|
564
|
+
return (
|
|
565
|
+
key == winrt::Windows::System::VirtualKey::I &&
|
|
566
|
+
::Microsoft::ReactNative::IsModifiedKeyPressed(
|
|
567
|
+
winrt::CoreWindow::GetForCurrentThread(), winrt::Windows::System::VirtualKey::Shift) &&
|
|
568
|
+
::Microsoft::ReactNative::IsModifiedKeyPressed(
|
|
569
|
+
winrt::CoreWindow::GetForCurrentThread(), winrt::Windows::System::VirtualKey::Control));
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
void ReactRootView::SetupDevToolsShortcut() noexcept {
|
|
573
|
+
if (auto xamlRoot = XamlRoot()) {
|
|
574
|
+
if (std::find(m_subscribedDebuggerRoots.begin(), m_subscribedDebuggerRoots.end(), xamlRoot) ==
|
|
575
|
+
m_subscribedDebuggerRoots.end()) {
|
|
576
|
+
if (auto rootContent = xamlRoot.Content()) {
|
|
577
|
+
m_subscribedDebuggerRoots.push_back(xamlRoot);
|
|
578
|
+
rootContent.KeyDown(
|
|
579
|
+
[weakThis = this->get_weak()](const auto & /*sender*/, const xaml::Input::KeyRoutedEventArgs &args) {
|
|
580
|
+
if (const auto strongThis = weakThis.get()) {
|
|
581
|
+
if (IsCtrlShiftI(args.Key())) {
|
|
582
|
+
::Microsoft::ReactNative::GetSharedDevManager()->OpenDevTools(
|
|
583
|
+
winrt::to_string(strongThis->m_reactNativeHost.InstanceSettings().BundleAppId()));
|
|
584
|
+
}
|
|
585
|
+
};
|
|
586
|
+
});
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
|
|
484
592
|
} // namespace winrt::Microsoft::ReactNative::implementation
|
|
@@ -72,6 +72,7 @@ struct ReactRootView : ReactRootViewT<ReactRootView>, ::Microsoft::ReactNative::
|
|
|
72
72
|
bool m_isPerspectiveEnabled{true};
|
|
73
73
|
bool m_isInitialized{false};
|
|
74
74
|
bool m_isJSViewAttached{false};
|
|
75
|
+
bool m_isDebuggerPausedOverlayOpen{false};
|
|
75
76
|
Mso::DispatchQueue m_uiQueue;
|
|
76
77
|
int64_t m_rootTag{-1};
|
|
77
78
|
std::unique_ptr<Mso::React::ReactOptions> m_reactOptions;
|
|
@@ -84,9 +85,11 @@ struct ReactRootView : ReactRootViewT<ReactRootView>, ::Microsoft::ReactNative::
|
|
|
84
85
|
std::shared_ptr<::Microsoft::ReactNative::PreviewKeyboardEventHandlerOnRoot> m_previewKeyboardEventHandlerOnRoot;
|
|
85
86
|
xaml::Controls::ContentControl m_focusSafeHarbor{nullptr};
|
|
86
87
|
xaml::Controls::ContentControl::LosingFocus_revoker m_focusSafeHarborLosingFocusRevoker{};
|
|
88
|
+
xaml::Controls::Flyout m_debuggerPausedFlyout{nullptr};
|
|
87
89
|
winrt::Grid m_greenBoxGrid{nullptr};
|
|
88
90
|
winrt::TextBlock m_waitingTextBlock{nullptr};
|
|
89
91
|
winrt::SystemNavigationManager::BackRequested_revoker m_backRequestedRevoker{};
|
|
92
|
+
std::vector<xaml::XamlRoot> m_subscribedDebuggerRoots{};
|
|
90
93
|
|
|
91
94
|
// Visual tree to support safe harbor
|
|
92
95
|
// this
|
|
@@ -102,6 +105,8 @@ struct ReactRootView : ReactRootViewT<ReactRootView>, ::Microsoft::ReactNative::
|
|
|
102
105
|
void UpdateRootViewInternal() noexcept;
|
|
103
106
|
void ClearLoadingUI() noexcept;
|
|
104
107
|
void EnsureLoadingUI() noexcept;
|
|
108
|
+
void HideDebuggerPausedOverlay() noexcept;
|
|
109
|
+
void ShowDebuggerPausedOverlay(const std::string &message, const std::function<void()> &onResume) noexcept;
|
|
105
110
|
void ShowInstanceLoaded() noexcept;
|
|
106
111
|
void ShowInstanceError() noexcept;
|
|
107
112
|
void ShowInstanceWaiting() noexcept;
|
|
@@ -112,6 +117,7 @@ struct ReactRootView : ReactRootViewT<ReactRootView>, ::Microsoft::ReactNative::
|
|
|
112
117
|
bool OnBackRequested() noexcept;
|
|
113
118
|
Mso::React::IReactViewHost *ReactViewHost() noexcept;
|
|
114
119
|
void ReactViewHost(Mso::React::IReactViewHost *viewHost) noexcept;
|
|
120
|
+
void SetupDevToolsShortcut() noexcept;
|
|
115
121
|
};
|
|
116
122
|
|
|
117
123
|
} // namespace winrt::Microsoft::ReactNative::implementation
|
|
@@ -112,6 +112,12 @@ class RuntimeDecorator : public Base, private jsi::Instrumentation {
|
|
|
112
112
|
return plain_;
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
+
#if JSI_VERSION >= 20
|
|
116
|
+
ICast* castInterface(const UUID& interfaceUUID) override {
|
|
117
|
+
return plain().castInterface(interfaceUUID);
|
|
118
|
+
}
|
|
119
|
+
#endif
|
|
120
|
+
|
|
115
121
|
Value evaluateJavaScript(
|
|
116
122
|
const std::shared_ptr<const Buffer>& buffer,
|
|
117
123
|
const std::string& sourceURL) override {
|
|
@@ -423,6 +429,19 @@ class RuntimeDecorator : public Base, private jsi::Instrumentation {
|
|
|
423
429
|
return plain_.callAsConstructor(f, args, count);
|
|
424
430
|
};
|
|
425
431
|
|
|
432
|
+
#if JSI_VERSION >= 20
|
|
433
|
+
void setRuntimeDataImpl(
|
|
434
|
+
const UUID& uuid,
|
|
435
|
+
const void* data,
|
|
436
|
+
void (*deleter)(const void* data)) override {
|
|
437
|
+
return plain_.setRuntimeDataImpl(uuid, data, deleter);
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
const void* getRuntimeDataImpl(const UUID& uuid) override {
|
|
441
|
+
return plain_.getRuntimeDataImpl(uuid);
|
|
442
|
+
}
|
|
443
|
+
#endif
|
|
444
|
+
|
|
426
445
|
// Private data for managing scopes.
|
|
427
446
|
Runtime::ScopeState* pushScope() override {
|
|
428
447
|
return plain_.pushScope();
|
|
@@ -620,6 +639,13 @@ class WithRuntimeDecorator : public RuntimeDecorator<Plain, Base> {
|
|
|
620
639
|
// the derived class.
|
|
621
640
|
WithRuntimeDecorator(Plain& plain, With& with) : RD(plain), with_(with) {}
|
|
622
641
|
|
|
642
|
+
#if JSI_VERSION >= 20
|
|
643
|
+
ICast* castInterface(const UUID& interfaceUUID) override {
|
|
644
|
+
Around around{with_};
|
|
645
|
+
return RD::castInterface(interfaceUUID);
|
|
646
|
+
}
|
|
647
|
+
#endif
|
|
648
|
+
|
|
623
649
|
Value evaluateJavaScript(
|
|
624
650
|
const std::shared_ptr<const Buffer>& buffer,
|
|
625
651
|
const std::string& sourceURL) override {
|
|
@@ -1034,6 +1060,21 @@ class WithRuntimeDecorator : public RuntimeDecorator<Plain, Base> {
|
|
|
1034
1060
|
};
|
|
1035
1061
|
#endif
|
|
1036
1062
|
|
|
1063
|
+
#if JSI_VERSION >= 20
|
|
1064
|
+
void setRuntimeDataImpl(
|
|
1065
|
+
const UUID& uuid,
|
|
1066
|
+
const void* data,
|
|
1067
|
+
void (*deleter)(const void* data)) override {
|
|
1068
|
+
Around around{with_};
|
|
1069
|
+
RD::setRuntimeDataImpl(uuid, data, deleter);
|
|
1070
|
+
}
|
|
1071
|
+
|
|
1072
|
+
const void* getRuntimeDataImpl(const UUID& uuid) override {
|
|
1073
|
+
Around around{with_};
|
|
1074
|
+
return RD::getRuntimeDataImpl(uuid);
|
|
1075
|
+
}
|
|
1076
|
+
#endif
|
|
1077
|
+
|
|
1037
1078
|
private:
|
|
1038
1079
|
// Wrap an RAII type around With& to guarantee after always happens.
|
|
1039
1080
|
struct Around {
|
|
@@ -86,6 +86,22 @@ inline const Runtime::PointerValue* Runtime::getPointerValue(
|
|
|
86
86
|
return value.data_.pointer.ptr_;
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
+
#if JSI_VERSION >= 20
|
|
90
|
+
inline void Runtime::setRuntimeData(
|
|
91
|
+
const UUID& uuid,
|
|
92
|
+
const std::shared_ptr<void>& data) {
|
|
93
|
+
auto* dataPtr = new std::shared_ptr<void>(data);
|
|
94
|
+
setRuntimeDataImpl(uuid, dataPtr, [](const void* data) {
|
|
95
|
+
delete (const std::shared_ptr<void>*)data;
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
inline std::shared_ptr<void> Runtime::getRuntimeData(const UUID& uuid) {
|
|
100
|
+
auto* data = (const std::shared_ptr<void>*)getRuntimeDataImpl(uuid);
|
|
101
|
+
return data ? *data : nullptr;
|
|
102
|
+
}
|
|
103
|
+
#endif
|
|
104
|
+
|
|
89
105
|
#if JSI_VERSION >= 17
|
|
90
106
|
Value Object::getPrototype(Runtime& runtime) const {
|
|
91
107
|
return runtime.getPrototypeOf(*this);
|
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
#include <cassert>
|
|
9
9
|
#include <cmath>
|
|
10
10
|
#include <cstdlib>
|
|
11
|
+
#include <map>
|
|
12
|
+
#include <mutex>
|
|
11
13
|
#include <stdexcept>
|
|
12
14
|
|
|
13
15
|
#include <jsi/instrumentation.h>
|
|
@@ -18,6 +20,65 @@ namespace jsi {
|
|
|
18
20
|
|
|
19
21
|
namespace {
|
|
20
22
|
|
|
23
|
+
#if JSI_VERSION >= 20
|
|
24
|
+
/// A global map used to store custom runtime data for VMs that do not provide
|
|
25
|
+
/// their own default implementation of setRuntimeData and getRuntimeData.
|
|
26
|
+
struct RuntimeDataGlobal {
|
|
27
|
+
/// Mutex protecting the Runtime data map
|
|
28
|
+
std::mutex mutex_{};
|
|
29
|
+
/// Maps a runtime pointer to a map of its custom data. At destruction of the
|
|
30
|
+
/// runtime, its entry will be removed from the global map.
|
|
31
|
+
std::unordered_map<
|
|
32
|
+
Runtime*,
|
|
33
|
+
std::unordered_map<
|
|
34
|
+
UUID,
|
|
35
|
+
std::pair<const void*, void (*)(const void* data)>,
|
|
36
|
+
UUID::Hash>>
|
|
37
|
+
dataMap_;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
RuntimeDataGlobal& getRuntimeDataGlobal() {
|
|
41
|
+
static RuntimeDataGlobal runtimeData{};
|
|
42
|
+
return runtimeData;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/// A host object that, when destructed, will remove the runtime's custom data
|
|
46
|
+
/// entry from the global map of custom data.
|
|
47
|
+
class RemoveRuntimeDataHostObject : public jsi::HostObject {
|
|
48
|
+
public:
|
|
49
|
+
explicit RemoveRuntimeDataHostObject(Runtime* runtime) : runtime_(runtime) {}
|
|
50
|
+
|
|
51
|
+
RemoveRuntimeDataHostObject(const RemoveRuntimeDataHostObject&) = default;
|
|
52
|
+
RemoveRuntimeDataHostObject(RemoveRuntimeDataHostObject&&) = default;
|
|
53
|
+
RemoveRuntimeDataHostObject& operator=(const RemoveRuntimeDataHostObject&) =
|
|
54
|
+
default;
|
|
55
|
+
RemoveRuntimeDataHostObject& operator=(RemoveRuntimeDataHostObject&&) =
|
|
56
|
+
default;
|
|
57
|
+
|
|
58
|
+
~RemoveRuntimeDataHostObject() override {
|
|
59
|
+
auto& runtimeDataGlobal = getRuntimeDataGlobal();
|
|
60
|
+
std::lock_guard<std::mutex> lock(runtimeDataGlobal.mutex_);
|
|
61
|
+
auto runtimeMapIt = runtimeDataGlobal.dataMap_.find(runtime_);
|
|
62
|
+
// We install the RemoveRuntimeDataHostObject only when the first custom
|
|
63
|
+
// data for the runtime is added, and only this object is responsible for
|
|
64
|
+
// clearing runtime data. Thus, we should always be able to find the data
|
|
65
|
+
// entry.
|
|
66
|
+
assert(
|
|
67
|
+
runtimeMapIt != runtimeDataGlobal.dataMap_.end() &&
|
|
68
|
+
"Custom runtime data not found for this runtime");
|
|
69
|
+
|
|
70
|
+
for (auto [_, entry] : runtimeMapIt->second) {
|
|
71
|
+
auto* deleter = entry.second;
|
|
72
|
+
deleter(entry.first);
|
|
73
|
+
}
|
|
74
|
+
runtimeDataGlobal.dataMap_.erase(runtime_);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
private:
|
|
78
|
+
Runtime* runtime_;
|
|
79
|
+
};
|
|
80
|
+
#endif
|
|
81
|
+
|
|
21
82
|
// This is used for generating short exception strings.
|
|
22
83
|
std::string kindToString(const Value& v, Runtime* rt = nullptr) {
|
|
23
84
|
if (v.isUndefined()) {
|
|
@@ -237,6 +298,12 @@ NativeState::~NativeState() {}
|
|
|
237
298
|
|
|
238
299
|
Runtime::~Runtime() {}
|
|
239
300
|
|
|
301
|
+
#if JSI_VERSION >= 20
|
|
302
|
+
ICast* Runtime::castInterface(const UUID& /*interfaceUUID*/) {
|
|
303
|
+
return nullptr;
|
|
304
|
+
}
|
|
305
|
+
#endif
|
|
306
|
+
|
|
240
307
|
Instrumentation& Runtime::instrumentation() {
|
|
241
308
|
class NoInstrumentation : public Instrumentation {
|
|
242
309
|
std::string getRecordedGCStats() override {
|
|
@@ -398,6 +465,64 @@ Object Runtime::createObjectWithPrototype(const Value& prototype) {
|
|
|
398
465
|
}
|
|
399
466
|
#endif
|
|
400
467
|
|
|
468
|
+
#if JSI_VERSION >= 20
|
|
469
|
+
void Runtime::setRuntimeDataImpl(
|
|
470
|
+
const UUID& uuid,
|
|
471
|
+
const void* data,
|
|
472
|
+
void (*deleter)(const void* data)) {
|
|
473
|
+
auto& runtimeDataGlobal = getRuntimeDataGlobal();
|
|
474
|
+
std::lock_guard<std::mutex> lock(runtimeDataGlobal.mutex_);
|
|
475
|
+
if (auto it = runtimeDataGlobal.dataMap_.find(this);
|
|
476
|
+
it != runtimeDataGlobal.dataMap_.end()) {
|
|
477
|
+
auto& map = it->second;
|
|
478
|
+
if (auto entryIt = map.find(uuid); entryIt != map.end()) {
|
|
479
|
+
// Free the old data
|
|
480
|
+
auto oldData = entryIt->second.first;
|
|
481
|
+
auto oldDataDeleter = entryIt->second.second;
|
|
482
|
+
oldDataDeleter(oldData);
|
|
483
|
+
}
|
|
484
|
+
map[uuid] = {data, deleter};
|
|
485
|
+
return;
|
|
486
|
+
}
|
|
487
|
+
// No custom data entry exist for this runtime in the global map, so create
|
|
488
|
+
// one.
|
|
489
|
+
runtimeDataGlobal.dataMap_[this][uuid] = {data, deleter};
|
|
490
|
+
|
|
491
|
+
// The first time data is added for this runtime is added to the map, install
|
|
492
|
+
// a host object on the global object of the runtime. This host object is used
|
|
493
|
+
// to release the runtime's entry from the global custom data map when the
|
|
494
|
+
// runtime is destroyed.
|
|
495
|
+
// Also, try to protect the host object by making it non-configurable,
|
|
496
|
+
// non-enumerable, and non-writable. These JSI operations are purposely
|
|
497
|
+
// performed after runtime-specific data map is added and the host object is
|
|
498
|
+
// created to prevent data leaks if any operations fail.
|
|
499
|
+
Object ho = Object::createFromHostObject(
|
|
500
|
+
*this, std::make_shared<RemoveRuntimeDataHostObject>(this));
|
|
501
|
+
global().setProperty(*this, "_jsiRuntimeDataCleanUp", ho);
|
|
502
|
+
auto definePropertyFn = global()
|
|
503
|
+
.getPropertyAsObject(*this, "Object")
|
|
504
|
+
.getPropertyAsFunction(*this, "defineProperty");
|
|
505
|
+
auto desc = Object(*this);
|
|
506
|
+
desc.setProperty(*this, "configurable", Value(false));
|
|
507
|
+
desc.setProperty(*this, "enumerable", Value(false));
|
|
508
|
+
desc.setProperty(*this, "writable", Value(false));
|
|
509
|
+
definePropertyFn.call(*this, global(), "_jsiRuntimeDataCleanUp", desc);
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
const void* Runtime::getRuntimeDataImpl(const UUID& uuid) {
|
|
513
|
+
auto& runtimeDataGlobal = getRuntimeDataGlobal();
|
|
514
|
+
std::lock_guard<std::mutex> lock(runtimeDataGlobal.mutex_);
|
|
515
|
+
if (auto runtimeMapIt = runtimeDataGlobal.dataMap_.find(this);
|
|
516
|
+
runtimeMapIt != runtimeDataGlobal.dataMap_.end()) {
|
|
517
|
+
if (auto customDataIt = runtimeMapIt->second.find(uuid);
|
|
518
|
+
customDataIt != runtimeMapIt->second.end()) {
|
|
519
|
+
return customDataIt->second.first;
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
return nullptr;
|
|
523
|
+
}
|
|
524
|
+
#endif
|
|
525
|
+
|
|
401
526
|
Pointer& Pointer::operator=(Pointer&& other) JSI_NOEXCEPT_15 {
|
|
402
527
|
if (ptr_) {
|
|
403
528
|
ptr_->invalidate();
|