react-native-windows 0.0.0-canary.485 → 0.0.0-canary.486
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/.flowconfig +1 -1
- package/Libraries/Animated/nodes/AnimatedInterpolation.js +17 -20
- package/Libraries/Components/View/ViewPropTypes.js +24 -17
- package/Libraries/Components/View/ViewPropTypes.windows.js +24 -17
- package/Libraries/Core/ReactNativeVersion.js +1 -1
- package/Libraries/NativeComponent/PlatformBaseViewConfig.js +26 -0
- package/Libraries/Text/TextProps.js +9 -0
- package/Libraries/Utilities/Appearance.js +0 -8
- package/Libraries/Utilities/HMRClient.js +1 -1
- package/Mso/src/dispatchQueue/threadPoolScheduler_win.cpp +96 -4
- package/PropertySheets/Generated/PackageVersion.g.props +1 -1
- package/Shared/DevSupportManager.cpp +21 -25
- package/Shared/DevSupportManager.h +1 -2
- package/Shared/HermesRuntimeHolder.cpp +23 -14
- package/Shared/HermesRuntimeHolder.h +8 -2
- package/Shared/IDevSupportManager.h +1 -2
- package/Shared/JSI/RuntimeHolder.h +2 -0
- package/Shared/OInstance.cpp +3 -3
- package/jest/preprocessor_DO_NOT_USE.js +3 -3
- package/package.json +10 -10
package/.flowconfig
CHANGED
|
@@ -46,20 +46,23 @@ function createInterpolation(
|
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
const outputRange: Array<number> = (config.outputRange: any);
|
|
49
|
-
checkInfiniteRange('outputRange', outputRange);
|
|
50
49
|
|
|
51
50
|
const inputRange = config.inputRange;
|
|
52
|
-
checkInfiniteRange('inputRange', inputRange);
|
|
53
|
-
checkValidInputRange(inputRange);
|
|
54
51
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
'inputRange
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
52
|
+
if (__DEV__) {
|
|
53
|
+
checkInfiniteRange('outputRange', outputRange);
|
|
54
|
+
checkInfiniteRange('inputRange', inputRange);
|
|
55
|
+
checkValidInputRange(inputRange);
|
|
56
|
+
|
|
57
|
+
invariant(
|
|
58
|
+
inputRange.length === outputRange.length,
|
|
59
|
+
'inputRange (' +
|
|
60
|
+
inputRange.length +
|
|
61
|
+
') and outputRange (' +
|
|
62
|
+
outputRange.length +
|
|
63
|
+
') must have the same length',
|
|
64
|
+
);
|
|
65
|
+
}
|
|
63
66
|
|
|
64
67
|
const easing = config.easing || linear;
|
|
65
68
|
|
|
@@ -276,16 +279,10 @@ function findRange(input: number, inputRange: $ReadOnlyArray<number>) {
|
|
|
276
279
|
|
|
277
280
|
function checkValidInputRange(arr: $ReadOnlyArray<number>) {
|
|
278
281
|
invariant(arr.length >= 2, 'inputRange must have at least 2 elements');
|
|
282
|
+
const message =
|
|
283
|
+
'inputRange must be monotonically non-decreasing ' + String(arr);
|
|
279
284
|
for (let i = 1; i < arr.length; ++i) {
|
|
280
|
-
invariant(
|
|
281
|
-
arr[i] >= arr[i - 1],
|
|
282
|
-
/* $FlowFixMe[incompatible-type] (>=0.13.0) - In the addition expression
|
|
283
|
-
* below this comment, one or both of the operands may be something that
|
|
284
|
-
* doesn't cleanly convert to a string, like undefined, null, and object,
|
|
285
|
-
* etc. If you really mean this implicit string conversion, you can do
|
|
286
|
-
* something like String(myThing) */
|
|
287
|
-
'inputRange must be monotonically non-decreasing ' + arr,
|
|
288
|
-
);
|
|
285
|
+
invariant(arr[i] >= arr[i - 1], message);
|
|
289
286
|
}
|
|
290
287
|
}
|
|
291
288
|
|
|
@@ -14,6 +14,7 @@ import type {
|
|
|
14
14
|
BlurEvent,
|
|
15
15
|
FocusEvent,
|
|
16
16
|
MouseEvent,
|
|
17
|
+
PointerEvent,
|
|
17
18
|
PressEvent,
|
|
18
19
|
Layout,
|
|
19
20
|
LayoutEvent,
|
|
@@ -84,8 +85,28 @@ type DirectEventProps = $ReadOnly<{|
|
|
|
84
85
|
|}>;
|
|
85
86
|
|
|
86
87
|
type MouseEventProps = $ReadOnly<{|
|
|
87
|
-
onMouseEnter?: (event: MouseEvent) => void,
|
|
88
|
-
onMouseLeave?: (event: MouseEvent) => void,
|
|
88
|
+
onMouseEnter?: ?(event: MouseEvent) => void,
|
|
89
|
+
onMouseLeave?: ?(event: MouseEvent) => void,
|
|
90
|
+
|}>;
|
|
91
|
+
|
|
92
|
+
type PointerEventProps = $ReadOnly<{|
|
|
93
|
+
onPointerEnter?: ?(event: PointerEvent) => void,
|
|
94
|
+
onPointerLeave?: ?(event: PointerEvent) => void,
|
|
95
|
+
onPointerMove?: ?(event: PointerEvent) => void,
|
|
96
|
+
onPointerCancel?: ?(e: PointerEvent) => void,
|
|
97
|
+
onPointerCancelCapture?: ?(e: PointerEvent) => void,
|
|
98
|
+
onPointerDown?: ?(e: PointerEvent) => void,
|
|
99
|
+
onPointerDownCapture?: ?(e: PointerEvent) => void,
|
|
100
|
+
onPointerUp?: ?(e: PointerEvent) => void,
|
|
101
|
+
onPointerUpCapture?: ?(e: PointerEvent) => void,
|
|
102
|
+
|
|
103
|
+
// FIXME: these events are temporary while we converge pointer event handling
|
|
104
|
+
onPointerEnter2?: ?(e: PointerEvent) => void,
|
|
105
|
+
onPointerEnter2Capture?: ?(e: PointerEvent) => void,
|
|
106
|
+
onPointerLeave2?: ?(e: PointerEvent) => void,
|
|
107
|
+
onPointerLeave2Capture?: ?(e: PointerEvent) => void,
|
|
108
|
+
onPointerMove2?: ?(e: PointerEvent) => void,
|
|
109
|
+
onPointerMove2Capture?: ?(e: PointerEvent) => void,
|
|
89
110
|
|}>;
|
|
90
111
|
|
|
91
112
|
type TouchEventProps = $ReadOnly<{|
|
|
@@ -99,20 +120,6 @@ type TouchEventProps = $ReadOnly<{|
|
|
|
99
120
|
onTouchStartCapture?: ?(e: PressEvent) => void,
|
|
100
121
|
|}>;
|
|
101
122
|
|
|
102
|
-
type PointerEventCallbackProps = $ReadOnly<{|
|
|
103
|
-
onPointerCancel?: ?(e: PointerEvent) => void,
|
|
104
|
-
onPointerCancelCapture?: ?(e: PointerEvent) => void,
|
|
105
|
-
onPointerDown?: ?(e: PointerEvent) => void,
|
|
106
|
-
onPointerDownCapture?: ?(e: PointerEvent) => void,
|
|
107
|
-
onPointerEnter2?: ?(e: PointerEvent) => void,
|
|
108
|
-
onPointerLeave2?: ?(e: PointerEvent) => void,
|
|
109
|
-
onPointerEnter2Capture?: ?(e: PointerEvent) => void,
|
|
110
|
-
onPointerLeave2Capture?: ?(e: PointerEvent) => void,
|
|
111
|
-
onPointerMove2Capture?: ?(e: PointerEvent) => void,
|
|
112
|
-
onPointerUp?: ?(e: PointerEvent) => void,
|
|
113
|
-
onPointerUpCapture?: ?(e: PointerEvent) => void,
|
|
114
|
-
|}>;
|
|
115
|
-
|
|
116
123
|
/**
|
|
117
124
|
* For most touch interactions, you'll simply want to wrap your component in
|
|
118
125
|
* `TouchableHighlight` or `TouchableOpacity`. Check out `Touchable.js`,
|
|
@@ -395,8 +402,8 @@ export type ViewProps = $ReadOnly<{|
|
|
|
395
402
|
...DirectEventProps,
|
|
396
403
|
...GestureResponderEventProps,
|
|
397
404
|
...MouseEventProps,
|
|
405
|
+
...PointerEventProps,
|
|
398
406
|
...TouchEventProps,
|
|
399
|
-
...PointerEventCallbackProps,
|
|
400
407
|
...AndroidViewProps,
|
|
401
408
|
...IOSViewProps,
|
|
402
409
|
|
|
@@ -14,6 +14,7 @@ import type {
|
|
|
14
14
|
BlurEvent,
|
|
15
15
|
FocusEvent,
|
|
16
16
|
MouseEvent,
|
|
17
|
+
PointerEvent,
|
|
17
18
|
PressEvent,
|
|
18
19
|
Layout,
|
|
19
20
|
LayoutEvent,
|
|
@@ -85,8 +86,28 @@ type DirectEventProps = $ReadOnly<{|
|
|
|
85
86
|
|}>;
|
|
86
87
|
|
|
87
88
|
type MouseEventProps = $ReadOnly<{|
|
|
88
|
-
onMouseEnter?: (event: MouseEvent) => void,
|
|
89
|
-
onMouseLeave?: (event: MouseEvent) => void,
|
|
89
|
+
onMouseEnter?: ?(event: MouseEvent) => void,
|
|
90
|
+
onMouseLeave?: ?(event: MouseEvent) => void,
|
|
91
|
+
|}>;
|
|
92
|
+
|
|
93
|
+
type PointerEventProps = $ReadOnly<{|
|
|
94
|
+
onPointerEnter?: ?(event: PointerEvent) => void,
|
|
95
|
+
onPointerLeave?: ?(event: PointerEvent) => void,
|
|
96
|
+
onPointerMove?: ?(event: PointerEvent) => void,
|
|
97
|
+
onPointerCancel?: ?(e: PointerEvent) => void,
|
|
98
|
+
onPointerCancelCapture?: ?(e: PointerEvent) => void,
|
|
99
|
+
onPointerDown?: ?(e: PointerEvent) => void,
|
|
100
|
+
onPointerDownCapture?: ?(e: PointerEvent) => void,
|
|
101
|
+
onPointerUp?: ?(e: PointerEvent) => void,
|
|
102
|
+
onPointerUpCapture?: ?(e: PointerEvent) => void,
|
|
103
|
+
|
|
104
|
+
// FIXME: these events are temporary while we converge pointer event handling
|
|
105
|
+
onPointerEnter2?: ?(e: PointerEvent) => void,
|
|
106
|
+
onPointerEnter2Capture?: ?(e: PointerEvent) => void,
|
|
107
|
+
onPointerLeave2?: ?(e: PointerEvent) => void,
|
|
108
|
+
onPointerLeave2Capture?: ?(e: PointerEvent) => void,
|
|
109
|
+
onPointerMove2?: ?(e: PointerEvent) => void,
|
|
110
|
+
onPointerMove2Capture?: ?(e: PointerEvent) => void,
|
|
90
111
|
|}>;
|
|
91
112
|
|
|
92
113
|
type TouchEventProps = $ReadOnly<{|
|
|
@@ -100,20 +121,6 @@ type TouchEventProps = $ReadOnly<{|
|
|
|
100
121
|
onTouchStartCapture?: ?(e: PressEvent) => void,
|
|
101
122
|
|}>;
|
|
102
123
|
|
|
103
|
-
type PointerEventCallbackProps = $ReadOnly<{|
|
|
104
|
-
onPointerCancel?: ?(e: PointerEvent) => void,
|
|
105
|
-
onPointerCancelCapture?: ?(e: PointerEvent) => void,
|
|
106
|
-
onPointerDown?: ?(e: PointerEvent) => void,
|
|
107
|
-
onPointerDownCapture?: ?(e: PointerEvent) => void,
|
|
108
|
-
onPointerEnter2?: ?(e: PointerEvent) => void,
|
|
109
|
-
onPointerLeave2?: ?(e: PointerEvent) => void,
|
|
110
|
-
onPointerEnter2Capture?: ?(e: PointerEvent) => void,
|
|
111
|
-
onPointerLeave2Capture?: ?(e: PointerEvent) => void,
|
|
112
|
-
onPointerMove2Capture?: ?(e: PointerEvent) => void,
|
|
113
|
-
onPointerUp?: ?(e: PointerEvent) => void,
|
|
114
|
-
onPointerUpCapture?: ?(e: PointerEvent) => void,
|
|
115
|
-
|}>;
|
|
116
|
-
|
|
117
124
|
/**
|
|
118
125
|
* For most touch interactions, you'll simply want to wrap your component in
|
|
119
126
|
* `TouchableHighlight` or `TouchableOpacity`. Check out `Touchable.js`,
|
|
@@ -443,8 +450,8 @@ export type ViewProps = $ReadOnly<{|
|
|
|
443
450
|
...DirectEventProps,
|
|
444
451
|
...GestureResponderEventProps,
|
|
445
452
|
...MouseEventProps,
|
|
453
|
+
...PointerEventProps,
|
|
446
454
|
...TouchEventProps,
|
|
447
|
-
...PointerEventCallbackProps,
|
|
448
455
|
...AndroidViewProps,
|
|
449
456
|
...IOSViewProps,
|
|
450
457
|
...WindowsViewProps, // [Windows]
|
|
@@ -363,6 +363,32 @@ const PlatformBaseViewConfig: PartialViewConfigWithoutName =
|
|
|
363
363
|
captured: 'onTouchEndCapture',
|
|
364
364
|
},
|
|
365
365
|
},
|
|
366
|
+
|
|
367
|
+
// Pointer Events
|
|
368
|
+
topPointerCancel: {
|
|
369
|
+
phasedRegistrationNames: {
|
|
370
|
+
captured: 'onPointerCancelCapture',
|
|
371
|
+
bubbled: 'onPointerCancel',
|
|
372
|
+
},
|
|
373
|
+
},
|
|
374
|
+
topPointerDown: {
|
|
375
|
+
phasedRegistrationNames: {
|
|
376
|
+
captured: 'onPointerDownCapture',
|
|
377
|
+
bubbled: 'onPointerDown',
|
|
378
|
+
},
|
|
379
|
+
},
|
|
380
|
+
topPointerMove2: {
|
|
381
|
+
phasedRegistrationNames: {
|
|
382
|
+
captured: 'onPointerMove2Capture',
|
|
383
|
+
bubbled: 'onPointerMove2',
|
|
384
|
+
},
|
|
385
|
+
},
|
|
386
|
+
topPointerUp: {
|
|
387
|
+
phasedRegistrationNames: {
|
|
388
|
+
captured: 'onPointerUpCapture',
|
|
389
|
+
bubbled: 'onPointerUp',
|
|
390
|
+
},
|
|
391
|
+
},
|
|
366
392
|
},
|
|
367
393
|
directEventTypes: {
|
|
368
394
|
topAccessibilityAction: {
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
|
|
13
13
|
import type {
|
|
14
14
|
LayoutEvent,
|
|
15
|
+
PointerEvent,
|
|
15
16
|
PressEvent,
|
|
16
17
|
TextLayoutEvent,
|
|
17
18
|
} from '../Types/CoreEventTypes';
|
|
@@ -31,10 +32,18 @@ export type PressRetentionOffset = $ReadOnly<{|
|
|
|
31
32
|
right: number,
|
|
32
33
|
|}>;
|
|
33
34
|
|
|
35
|
+
type PointerEventProps = $ReadOnly<{|
|
|
36
|
+
onPointerEnter?: (event: PointerEvent) => void,
|
|
37
|
+
onPointerLeave?: (event: PointerEvent) => void,
|
|
38
|
+
onPointerMove?: (event: PointerEvent) => void,
|
|
39
|
+
|}>;
|
|
40
|
+
|
|
34
41
|
/**
|
|
35
42
|
* @see https://reactnative.dev/docs/text#reference
|
|
36
43
|
*/
|
|
37
44
|
export type TextProps = $ReadOnly<{|
|
|
45
|
+
...PointerEventProps,
|
|
46
|
+
|
|
38
47
|
/**
|
|
39
48
|
* Indicates whether the view is an accessibility element.
|
|
40
49
|
*
|
|
@@ -91,12 +91,4 @@ module.exports = {
|
|
|
91
91
|
addChangeListener(listener: AppearanceListener): EventSubscription {
|
|
92
92
|
return eventEmitter.addListener('change', listener);
|
|
93
93
|
},
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* @deprecated Use `remove` on the EventSubscription from `addEventListener`.
|
|
97
|
-
*/
|
|
98
|
-
removeChangeListener(listener: AppearanceListener): void {
|
|
99
|
-
// NOTE: This will report a deprecation notice via `console.error`.
|
|
100
|
-
eventEmitter.removeListener('change', listener);
|
|
101
|
-
},
|
|
102
94
|
};
|
|
@@ -292,7 +292,7 @@ function registerBundleEntryPoints(client) {
|
|
|
292
292
|
|
|
293
293
|
function flushEarlyLogs(client) {
|
|
294
294
|
try {
|
|
295
|
-
pendingLogs.forEach(([level
|
|
295
|
+
pendingLogs.forEach(([level, data]) => {
|
|
296
296
|
HMRClient.log(level, data);
|
|
297
297
|
});
|
|
298
298
|
} finally {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// Copyright (c) Microsoft Corporation.
|
|
2
2
|
// Licensed under the MIT license.
|
|
3
3
|
|
|
4
|
+
#include <utility>
|
|
4
5
|
#include "dispatchQueue/dispatchQueue.h"
|
|
5
6
|
#include "queueService.h"
|
|
6
7
|
|
|
@@ -29,6 +30,13 @@ struct ThreadPoolSchedulerWin : Mso::UnknownObject<IDispatchQueueScheduler> {
|
|
|
29
30
|
void Shutdown() noexcept override;
|
|
30
31
|
void AwaitTermination() noexcept override;
|
|
31
32
|
|
|
33
|
+
public: // Used by test APIs
|
|
34
|
+
static void EnableThreadPoolWorkTracking(bool enable) noexcept;
|
|
35
|
+
static void WaitForThreadPoolWorkCompletion() noexcept;
|
|
36
|
+
|
|
37
|
+
private: // Used by test APIs
|
|
38
|
+
static void TrackThreadPoolWork(const std::shared_ptr<TP_WORK> &work) noexcept;
|
|
39
|
+
|
|
32
40
|
private:
|
|
33
41
|
struct ThreadAccessGuard {
|
|
34
42
|
ThreadAccessGuard(ThreadPoolSchedulerWin *scheduler) noexcept;
|
|
@@ -42,12 +50,29 @@ struct ThreadPoolSchedulerWin : Mso::UnknownObject<IDispatchQueueScheduler> {
|
|
|
42
50
|
};
|
|
43
51
|
|
|
44
52
|
private:
|
|
45
|
-
std::
|
|
53
|
+
std::shared_ptr<TP_WORK> m_threadPoolWork;
|
|
46
54
|
Mso::WeakPtr<IDispatchQueueService> m_queue;
|
|
47
55
|
const uint32_t m_maxThreads{1};
|
|
48
56
|
std::atomic<uint32_t> m_usedThreads{0};
|
|
49
57
|
|
|
50
58
|
constexpr static uint32_t MaxConcurrentThreads{64};
|
|
59
|
+
|
|
60
|
+
private:
|
|
61
|
+
static std::mutex s_threadPoolWorkMutex;
|
|
62
|
+
static bool s_enableThreadPoolWorkTracking;
|
|
63
|
+
static std::vector<std::shared_ptr<TP_WORK>> s_trackedThreadPoolWork;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
// Track the ThreadPoolSchedulerWin instance used by current thread.
|
|
67
|
+
// We use it to avoid a deadlock on queue shutdown.
|
|
68
|
+
struct ThreadPoolSchedulerWinContext {
|
|
69
|
+
ThreadPoolSchedulerWinContext(ThreadPoolSchedulerWin *scheduler) noexcept;
|
|
70
|
+
~ThreadPoolSchedulerWinContext() noexcept;
|
|
71
|
+
static ThreadPoolSchedulerWin *CurrentScheduler() noexcept;
|
|
72
|
+
|
|
73
|
+
private:
|
|
74
|
+
static thread_local ThreadPoolSchedulerWin *tls_scheduler;
|
|
75
|
+
ThreadPoolSchedulerWin *m_prevScheduler{nullptr};
|
|
51
76
|
};
|
|
52
77
|
|
|
53
78
|
//=============================================================================
|
|
@@ -64,9 +89,15 @@ void ThreadPoolWorkDeleter::operator()(TP_WORK *tpWork) noexcept {
|
|
|
64
89
|
// ThreadPoolSchedulerWin implementation
|
|
65
90
|
//=============================================================================
|
|
66
91
|
|
|
92
|
+
std::mutex ThreadPoolSchedulerWin::s_threadPoolWorkMutex;
|
|
93
|
+
bool ThreadPoolSchedulerWin::s_enableThreadPoolWorkTracking{false};
|
|
94
|
+
std::vector<std::shared_ptr<TP_WORK>> ThreadPoolSchedulerWin::s_trackedThreadPoolWork;
|
|
95
|
+
|
|
67
96
|
ThreadPoolSchedulerWin::ThreadPoolSchedulerWin(uint32_t maxThreads) noexcept
|
|
68
|
-
: m_threadPoolWork{::CreateThreadpoolWork(WorkCallback, this, nullptr)},
|
|
69
|
-
m_maxThreads{maxThreads == 0 ? MaxConcurrentThreads : maxThreads} {
|
|
97
|
+
: m_threadPoolWork{::CreateThreadpoolWork(WorkCallback, this, nullptr), ThreadPoolWorkDeleter{}},
|
|
98
|
+
m_maxThreads{maxThreads == 0 ? MaxConcurrentThreads : maxThreads} {
|
|
99
|
+
TrackThreadPoolWork(m_threadPoolWork);
|
|
100
|
+
}
|
|
70
101
|
|
|
71
102
|
ThreadPoolSchedulerWin::~ThreadPoolSchedulerWin() noexcept {
|
|
72
103
|
AwaitTermination();
|
|
@@ -78,6 +109,7 @@ ThreadPoolSchedulerWin::~ThreadPoolSchedulerWin() noexcept {
|
|
|
78
109
|
_Inout_ PTP_WORK /*work*/) {
|
|
79
110
|
// The ThreadPoolSchedulerWin is alive here because m_threadPoolWork must be completed before it is destroyed.
|
|
80
111
|
ThreadPoolSchedulerWin *self = static_cast<ThreadPoolSchedulerWin *>(context);
|
|
112
|
+
ThreadPoolSchedulerWinContext schedulerContext(self);
|
|
81
113
|
|
|
82
114
|
if (auto queue = self->m_queue.GetStrongPtr()) {
|
|
83
115
|
auto endTime = std::chrono::steady_clock::now() + 100ms;
|
|
@@ -129,7 +161,38 @@ void ThreadPoolSchedulerWin::Shutdown() noexcept {
|
|
|
129
161
|
}
|
|
130
162
|
|
|
131
163
|
void ThreadPoolSchedulerWin::AwaitTermination() noexcept {
|
|
132
|
-
|
|
164
|
+
// Avoid deadlock when the dispatch queue and ThreadPoolSchedulerWin are released from inside of a task.
|
|
165
|
+
if (ThreadPoolSchedulerWinContext::CurrentScheduler() != this) {
|
|
166
|
+
::WaitForThreadpoolWorkCallbacks(m_threadPoolWork.get(), false);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
void ThreadPoolSchedulerWin::EnableThreadPoolWorkTracking(bool enable) noexcept {
|
|
171
|
+
std::vector<std::shared_ptr<TP_WORK>> tpWorkToStopTracking;
|
|
172
|
+
{
|
|
173
|
+
std::scoped_lock lock{s_threadPoolWorkMutex};
|
|
174
|
+
s_enableThreadPoolWorkTracking = enable;
|
|
175
|
+
// Reset all previously tracked work
|
|
176
|
+
tpWorkToStopTracking = std::move(s_trackedThreadPoolWork);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
void ThreadPoolSchedulerWin::WaitForThreadPoolWorkCompletion() noexcept {
|
|
181
|
+
std::vector<std::shared_ptr<TP_WORK>> tpWorkToTrack;
|
|
182
|
+
{
|
|
183
|
+
std::scoped_lock lock{s_threadPoolWorkMutex};
|
|
184
|
+
tpWorkToTrack = std::move(s_trackedThreadPoolWork);
|
|
185
|
+
}
|
|
186
|
+
for (std::shared_ptr<TP_WORK> &tpWork : tpWorkToTrack) {
|
|
187
|
+
::WaitForThreadpoolWorkCallbacks(tpWork.get(), false);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
void ThreadPoolSchedulerWin::TrackThreadPoolWork(const std::shared_ptr<TP_WORK> &tpWork) noexcept {
|
|
192
|
+
std::scoped_lock lock{s_threadPoolWorkMutex};
|
|
193
|
+
if (s_enableThreadPoolWorkTracking) {
|
|
194
|
+
s_trackedThreadPoolWork.push_back(tpWork);
|
|
195
|
+
}
|
|
133
196
|
}
|
|
134
197
|
|
|
135
198
|
//=============================================================================
|
|
@@ -151,6 +214,23 @@ ThreadPoolSchedulerWin::ThreadAccessGuard::~ThreadAccessGuard() noexcept {
|
|
|
151
214
|
return tls_scheduler == scheduler;
|
|
152
215
|
}
|
|
153
216
|
|
|
217
|
+
//=============================================================================
|
|
218
|
+
// ThreadPoolSchedulerWinContext implementation
|
|
219
|
+
//=============================================================================
|
|
220
|
+
|
|
221
|
+
thread_local ThreadPoolSchedulerWin *ThreadPoolSchedulerWinContext::tls_scheduler{nullptr};
|
|
222
|
+
|
|
223
|
+
ThreadPoolSchedulerWinContext::ThreadPoolSchedulerWinContext(ThreadPoolSchedulerWin *scheduler) noexcept
|
|
224
|
+
: m_prevScheduler(std::exchange(tls_scheduler, scheduler)) {}
|
|
225
|
+
|
|
226
|
+
ThreadPoolSchedulerWinContext::~ThreadPoolSchedulerWinContext() noexcept {
|
|
227
|
+
std::exchange(tls_scheduler, m_prevScheduler);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
ThreadPoolSchedulerWin *ThreadPoolSchedulerWinContext::CurrentScheduler() noexcept {
|
|
231
|
+
return tls_scheduler;
|
|
232
|
+
}
|
|
233
|
+
|
|
154
234
|
//=============================================================================
|
|
155
235
|
// DispatchQueueStatic::MakeThreadPoolScheduler implementation
|
|
156
236
|
//=============================================================================
|
|
@@ -160,4 +240,16 @@ ThreadPoolSchedulerWin::ThreadAccessGuard::~ThreadAccessGuard() noexcept {
|
|
|
160
240
|
return Mso::Make<ThreadPoolSchedulerWin, IDispatchQueueScheduler>(maxThreads);
|
|
161
241
|
}
|
|
162
242
|
|
|
243
|
+
//=============================================================================
|
|
244
|
+
// Test specific functions
|
|
245
|
+
//=============================================================================
|
|
246
|
+
|
|
247
|
+
void Test_ThreadPoolSchedulerWin_EnableThreadPoolWorkTracking(bool enable) noexcept {
|
|
248
|
+
ThreadPoolSchedulerWin::EnableThreadPoolWorkTracking(enable);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
void Test_ThreadPoolSchedulerWin_WaitForThreadPoolWorkCompletion() noexcept {
|
|
252
|
+
ThreadPoolSchedulerWin::WaitForThreadPoolWorkCompletion();
|
|
253
|
+
}
|
|
254
|
+
|
|
163
255
|
} // namespace Mso
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
-->
|
|
11
11
|
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
12
12
|
<PropertyGroup>
|
|
13
|
-
<ReactNativeWindowsVersion>0.0.0-canary.
|
|
13
|
+
<ReactNativeWindowsVersion>0.0.0-canary.486</ReactNativeWindowsVersion>
|
|
14
14
|
<ReactNativeWindowsMajor>0</ReactNativeWindowsMajor>
|
|
15
15
|
<ReactNativeWindowsMinor>0</ReactNativeWindowsMinor>
|
|
16
16
|
<ReactNativeWindowsPatch>0</ReactNativeWindowsPatch>
|
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
#pragma warning(pop)
|
|
34
34
|
|
|
35
35
|
#include <future>
|
|
36
|
+
#include <mutex>
|
|
36
37
|
|
|
37
38
|
#include <AppModel.h>
|
|
38
39
|
|
|
@@ -239,37 +240,32 @@ void DevSupportManager::StopPollingLiveReload() {
|
|
|
239
240
|
m_cancellation_token = true;
|
|
240
241
|
}
|
|
241
242
|
|
|
242
|
-
void DevSupportManager::
|
|
243
|
+
void DevSupportManager::EnsureHermesInspector(
|
|
243
244
|
[[maybe_unused]] const std::string &packagerHost,
|
|
244
245
|
[[maybe_unused]] const uint16_t packagerPort) noexcept {
|
|
245
246
|
#ifdef HERMES_ENABLE_DEBUGGER
|
|
246
|
-
std::
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
247
|
+
static std::once_flag once;
|
|
248
|
+
std::call_once(once, [this, &packagerHost, packagerPort]() {
|
|
249
|
+
std::string packageName("RNW");
|
|
250
|
+
wchar_t fullName[PACKAGE_FULL_NAME_MAX_LENGTH]{};
|
|
251
|
+
UINT32 size = ARRAYSIZE(fullName);
|
|
252
|
+
if (SUCCEEDED(GetCurrentPackageFullName(&size, fullName))) {
|
|
253
|
+
// we are in an unpackaged app
|
|
254
|
+
packageName = winrt::to_string(fullName);
|
|
255
|
+
}
|
|
253
256
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
257
|
+
std::string deviceName("RNWHost");
|
|
258
|
+
auto hostNames = winrt::Windows::Networking::Connectivity::NetworkInformation::GetHostNames();
|
|
259
|
+
if (hostNames && hostNames.First() && hostNames.First().Current()) {
|
|
260
|
+
deviceName = winrt::to_string(hostNames.First().Current().DisplayName());
|
|
261
|
+
}
|
|
259
262
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
}
|
|
263
|
+
m_inspectorPackagerConnection = std::make_shared<InspectorPackagerConnection>(
|
|
264
|
+
facebook::react::DevServerHelper::get_InspectorDeviceUrl(packagerHost, packagerPort, deviceName, packageName),
|
|
265
|
+
m_BundleStatusProvider);
|
|
266
|
+
m_inspectorPackagerConnection->connectAsync();
|
|
267
|
+
});
|
|
266
268
|
|
|
267
|
-
void DevSupportManager::StopInspector() noexcept {
|
|
268
|
-
#ifdef HERMES_ENABLE_DEBUGGER
|
|
269
|
-
if (m_inspectorPackagerConnection) {
|
|
270
|
-
m_inspectorPackagerConnection->disconnectAsync();
|
|
271
|
-
m_inspectorPackagerConnection = nullptr;
|
|
272
|
-
}
|
|
273
269
|
#endif
|
|
274
270
|
}
|
|
275
271
|
|
|
@@ -50,8 +50,7 @@ class DevSupportManager final : public facebook::react::IDevSupportManager {
|
|
|
50
50
|
std::function<void()> onChangeCallback) override;
|
|
51
51
|
virtual void StopPollingLiveReload() override;
|
|
52
52
|
|
|
53
|
-
virtual void
|
|
54
|
-
virtual void StopInspector() noexcept override;
|
|
53
|
+
virtual void EnsureHermesInspector(const std::string &packagerHost, const uint16_t packagerPort) noexcept override;
|
|
55
54
|
virtual void UpdateBundleStatus(bool isLastDownloadSucess, int64_t updateTimestamp) noexcept override;
|
|
56
55
|
|
|
57
56
|
private:
|
|
@@ -74,7 +74,15 @@ class HermesExecutorRuntimeAdapter final : public facebook::hermes::inspector::R
|
|
|
74
74
|
} // namespace
|
|
75
75
|
|
|
76
76
|
void HermesRuntimeHolder::crashHandler(int fileDescriptor) noexcept {
|
|
77
|
-
HermesShim::hermesCrashHandler(
|
|
77
|
+
HermesShim::hermesCrashHandler(*m_hermesRuntime, fileDescriptor);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
void HermesRuntimeHolder::teardown() noexcept {
|
|
81
|
+
#ifdef HERMES_ENABLE_DEBUGGER
|
|
82
|
+
if (auto devSettings = m_weakDevSettings.lock(); devSettings && devSettings->useDirectDebugger) {
|
|
83
|
+
facebook::hermes::inspector::chrome::disableDebugging(*m_hermesRuntime);
|
|
84
|
+
}
|
|
85
|
+
#endif
|
|
78
86
|
}
|
|
79
87
|
|
|
80
88
|
facebook::react::JSIEngineOverride HermesRuntimeHolder::getRuntimeType() noexcept {
|
|
@@ -84,43 +92,44 @@ facebook::react::JSIEngineOverride HermesRuntimeHolder::getRuntimeType() noexcep
|
|
|
84
92
|
std::shared_ptr<jsi::Runtime> HermesRuntimeHolder::getRuntime() noexcept {
|
|
85
93
|
std::call_once(m_once_flag, [this]() { initRuntime(); });
|
|
86
94
|
|
|
87
|
-
if (!
|
|
95
|
+
if (!m_hermesRuntime)
|
|
88
96
|
std::terminate();
|
|
89
97
|
|
|
90
98
|
// Make sure that the runtime instance is not consumed from multiple threads.
|
|
91
99
|
if (m_own_thread_id != std::this_thread::get_id())
|
|
92
100
|
std::terminate();
|
|
93
101
|
|
|
94
|
-
return
|
|
102
|
+
return m_hermesRuntime;
|
|
95
103
|
}
|
|
96
104
|
|
|
97
105
|
HermesRuntimeHolder::HermesRuntimeHolder(
|
|
98
106
|
std::shared_ptr<facebook::react::DevSettings> devSettings,
|
|
99
107
|
std::shared_ptr<facebook::react::MessageQueueThread> jsQueue) noexcept
|
|
100
|
-
:
|
|
108
|
+
: m_weakDevSettings(devSettings), m_jsQueue(std::move(jsQueue)) {}
|
|
101
109
|
|
|
102
110
|
void HermesRuntimeHolder::initRuntime() noexcept {
|
|
103
|
-
auto
|
|
104
|
-
|
|
105
|
-
|
|
111
|
+
auto devSettings = m_weakDevSettings.lock();
|
|
112
|
+
if (!devSettings)
|
|
113
|
+
std::terminate();
|
|
106
114
|
|
|
107
|
-
|
|
115
|
+
m_hermesRuntime = makeHermesRuntimeSystraced(devSettings->enableDefaultCrashHandler);
|
|
108
116
|
m_own_thread_id = std::this_thread::get_id();
|
|
109
117
|
|
|
110
118
|
#ifdef HERMES_ENABLE_DEBUGGER
|
|
111
|
-
if (
|
|
112
|
-
auto adapter = std::make_unique<HermesExecutorRuntimeAdapter>(
|
|
119
|
+
if (devSettings->useDirectDebugger) {
|
|
120
|
+
auto adapter = std::make_unique<HermesExecutorRuntimeAdapter>(m_hermesRuntime, *m_hermesRuntime, m_jsQueue);
|
|
113
121
|
facebook::hermes::inspector::chrome::enableDebugging(
|
|
114
122
|
std::move(adapter),
|
|
115
|
-
|
|
123
|
+
devSettings->debuggerRuntimeName.empty() ? "Hermes React Native" : devSettings->debuggerRuntimeName);
|
|
116
124
|
}
|
|
117
125
|
#endif
|
|
118
126
|
|
|
119
127
|
// Add js engine information to Error.prototype so in error reporting we
|
|
120
128
|
// can send this information.
|
|
121
|
-
auto errorPrototype =
|
|
122
|
-
|
|
123
|
-
|
|
129
|
+
auto errorPrototype = m_hermesRuntime->global()
|
|
130
|
+
.getPropertyAsObject(*m_hermesRuntime, "Error")
|
|
131
|
+
.getPropertyAsObject(*m_hermesRuntime, "prototype");
|
|
132
|
+
errorPrototype.setProperty(*m_hermesRuntime, "jsEngine", "hermes");
|
|
124
133
|
}
|
|
125
134
|
|
|
126
135
|
} // namespace react
|
|
@@ -9,6 +9,10 @@
|
|
|
9
9
|
|
|
10
10
|
#include <DevSettings.h>
|
|
11
11
|
|
|
12
|
+
namespace facebook::hermes {
|
|
13
|
+
class HermesRuntime;
|
|
14
|
+
}
|
|
15
|
+
|
|
12
16
|
namespace facebook {
|
|
13
17
|
namespace react {
|
|
14
18
|
|
|
@@ -19,18 +23,20 @@ class HermesRuntimeHolder : public Microsoft::JSI::RuntimeHolderLazyInit {
|
|
|
19
23
|
|
|
20
24
|
void crashHandler(int fileDescriptor) noexcept override;
|
|
21
25
|
|
|
26
|
+
void teardown() noexcept override;
|
|
27
|
+
|
|
22
28
|
HermesRuntimeHolder(
|
|
23
29
|
std::shared_ptr<facebook::react::DevSettings> devSettings,
|
|
24
30
|
std::shared_ptr<facebook::react::MessageQueueThread> jsQueue) noexcept;
|
|
25
31
|
|
|
26
32
|
private:
|
|
27
33
|
void initRuntime() noexcept;
|
|
28
|
-
std::shared_ptr<facebook::
|
|
34
|
+
std::shared_ptr<facebook::hermes::HermesRuntime> m_hermesRuntime;
|
|
29
35
|
|
|
30
36
|
std::once_flag m_once_flag;
|
|
31
37
|
std::thread::id m_own_thread_id;
|
|
32
38
|
|
|
33
|
-
std::
|
|
39
|
+
std::weak_ptr<facebook::react::DevSettings> m_weakDevSettings;
|
|
34
40
|
std::shared_ptr<facebook::react::MessageQueueThread> m_jsQueue;
|
|
35
41
|
};
|
|
36
42
|
|
|
@@ -22,8 +22,7 @@ struct IDevSupportManager {
|
|
|
22
22
|
std::function<void()> onChangeCallback) = 0;
|
|
23
23
|
virtual void StopPollingLiveReload() = 0;
|
|
24
24
|
|
|
25
|
-
virtual void
|
|
26
|
-
virtual void StopInspector() noexcept = 0;
|
|
25
|
+
virtual void EnsureHermesInspector(const std::string &packagerHost, const uint16_t packagerPort) noexcept = 0;
|
|
27
26
|
virtual void UpdateBundleStatus(bool isLastDownloadSucess, int64_t updateTimestamp) noexcept = 0;
|
|
28
27
|
};
|
|
29
28
|
|
|
@@ -18,6 +18,8 @@ struct RuntimeHolderLazyInit {
|
|
|
18
18
|
virtual std::shared_ptr<facebook::jsi::Runtime> getRuntime() noexcept = 0;
|
|
19
19
|
virtual facebook::react::JSIEngineOverride getRuntimeType() noexcept = 0;
|
|
20
20
|
|
|
21
|
+
virtual void teardown() noexcept {};
|
|
22
|
+
|
|
21
23
|
// You can call this when a crash happens to attempt recording additional data
|
|
22
24
|
// The fd supplied is a raw file stream an implementation might write JSON to
|
|
23
25
|
virtual void crashHandler(int fileDescriptor) noexcept {};
|
package/Shared/OInstance.cpp
CHANGED
|
@@ -254,7 +254,7 @@ InstanceImpl::InstanceImpl(
|
|
|
254
254
|
#endif
|
|
255
255
|
|
|
256
256
|
if (shouldStartHermesInspector(*m_devSettings)) {
|
|
257
|
-
m_devManager->
|
|
257
|
+
m_devManager->EnsureHermesInspector(m_devSettings->sourceBundleHost, m_devSettings->sourceBundlePort);
|
|
258
258
|
}
|
|
259
259
|
|
|
260
260
|
// Default (common) NativeModules
|
|
@@ -532,8 +532,8 @@ void InstanceImpl::loadBundleInternal(std::string &&jsBundleRelativePath, bool s
|
|
|
532
532
|
}
|
|
533
533
|
|
|
534
534
|
InstanceImpl::~InstanceImpl() {
|
|
535
|
-
if (shouldStartHermesInspector(*m_devSettings)) {
|
|
536
|
-
|
|
535
|
+
if (shouldStartHermesInspector(*m_devSettings) && m_devSettings->jsiRuntimeHolder) {
|
|
536
|
+
m_devSettings->jsiRuntimeHolder->teardown();
|
|
537
537
|
}
|
|
538
538
|
m_nativeQueue->quitSynchronous();
|
|
539
539
|
}
|
|
@@ -30,7 +30,7 @@ babelRegisterOnly([]);
|
|
|
30
30
|
|
|
31
31
|
const transformer = require('metro-react-native-babel-transformer');
|
|
32
32
|
module.exports = {
|
|
33
|
-
process(src /*: string */, file /*: string */) /*: string */ {
|
|
33
|
+
process(src /*: string */, file /*: string */) /*: {code: string, ...} */ {
|
|
34
34
|
if (nodeFiles.test(file)) {
|
|
35
35
|
// node specific transforms only
|
|
36
36
|
return babelTransformSync(src, {
|
|
@@ -38,7 +38,7 @@ module.exports = {
|
|
|
38
38
|
sourceType: 'script',
|
|
39
39
|
...nodeOptions,
|
|
40
40
|
ast: false,
|
|
41
|
-
})
|
|
41
|
+
});
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
const {ast} = transformer.transform({
|
|
@@ -111,7 +111,7 @@ module.exports = {
|
|
|
111
111
|
sourceMaps: true,
|
|
112
112
|
},
|
|
113
113
|
src,
|
|
114
|
-
)
|
|
114
|
+
);
|
|
115
115
|
},
|
|
116
116
|
|
|
117
117
|
getCacheKey: (createCacheKeyFunction([
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-windows",
|
|
3
|
-
"version": "0.0.0-canary.
|
|
3
|
+
"version": "0.0.0-canary.486",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"@react-native-community/cli-platform-android": "^7.0.1",
|
|
28
28
|
"@react-native-community/cli-platform-ios": "^7.0.1",
|
|
29
29
|
"@react-native-windows/cli": "0.0.0-canary.125",
|
|
30
|
-
"@react-native-windows/virtualized-list": "0.0.0-canary.
|
|
30
|
+
"@react-native-windows/virtualized-list": "0.0.0-canary.39",
|
|
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",
|
|
@@ -39,22 +39,22 @@
|
|
|
39
39
|
"invariant": "^2.2.4",
|
|
40
40
|
"jsc-android": "^250230.2.1",
|
|
41
41
|
"memoize-one": "^5.0.0",
|
|
42
|
-
"metro-react-native-babel-transformer": "0.70.
|
|
43
|
-
"metro-runtime": "0.70.
|
|
44
|
-
"metro-source-map": "0.70.
|
|
42
|
+
"metro-react-native-babel-transformer": "0.70.1",
|
|
43
|
+
"metro-runtime": "0.70.1",
|
|
44
|
+
"metro-source-map": "0.70.1",
|
|
45
45
|
"nullthrows": "^1.1.1",
|
|
46
46
|
"pretty-format": "^26.5.2",
|
|
47
47
|
"promise": "^8.0.3",
|
|
48
48
|
"react-devtools-core": "4.24.0",
|
|
49
49
|
"react-native-codegen": "^0.0.14",
|
|
50
|
-
"react-native-gradle-plugin": "^0.0.
|
|
50
|
+
"react-native-gradle-plugin": "^0.0.6",
|
|
51
51
|
"react-refresh": "^0.4.0",
|
|
52
52
|
"react-shallow-renderer": "16.14.1",
|
|
53
53
|
"regenerator-runtime": "^0.13.2",
|
|
54
54
|
"scheduler": "^0.20.2",
|
|
55
55
|
"source-map-support": "^0.5.19",
|
|
56
56
|
"stacktrace-parser": "^0.1.3",
|
|
57
|
-
"use-subscription": "
|
|
57
|
+
"use-subscription": ">=1.0.0 <1.6.0",
|
|
58
58
|
"whatwg-fetch": "^3.0.0",
|
|
59
59
|
"ws": "^6.1.4"
|
|
60
60
|
},
|
|
@@ -69,13 +69,13 @@
|
|
|
69
69
|
"@types/react-native": "^0.66.17",
|
|
70
70
|
"eslint": "^7.32.0",
|
|
71
71
|
"eslint-plugin-prettier": "^4.0.0",
|
|
72
|
-
"flow-bin": "^0.175.
|
|
72
|
+
"flow-bin": "^0.175.1",
|
|
73
73
|
"jscodeshift": "^0.13.1",
|
|
74
74
|
"just-scripts": "^1.3.3",
|
|
75
75
|
"metro-config": "^0.67.0",
|
|
76
76
|
"prettier": "^2.4.1",
|
|
77
77
|
"react": "17.0.2",
|
|
78
|
-
"react-native": "0.0.0-
|
|
78
|
+
"react-native": "0.0.0-20220411-2010-f503b2120",
|
|
79
79
|
"react-native-platform-override": "^1.6.9",
|
|
80
80
|
"react-refresh": "^0.4.0",
|
|
81
81
|
"react-shallow-renderer": "16.14.1",
|
|
@@ -83,7 +83,7 @@
|
|
|
83
83
|
},
|
|
84
84
|
"peerDependencies": {
|
|
85
85
|
"react": "17.0.2",
|
|
86
|
-
"react-native": "0.0.0-
|
|
86
|
+
"react-native": "0.0.0-20220411-2010-f503b2120"
|
|
87
87
|
},
|
|
88
88
|
"beachball": {
|
|
89
89
|
"defaultNpmTag": "canary",
|