react-native-windows 0.82.1 → 0.82.3

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.
Files changed (32) hide show
  1. package/Microsoft.ReactNative/Base/CxxReactIncludes.h +11 -0
  2. package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.cpp +52 -2
  3. package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.cpp +70 -49
  4. package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.h +4 -1
  5. package/Microsoft.ReactNative/Fabric/platform/react/renderer/textlayoutmanager/WindowsTextLayoutManager.cpp +7 -2
  6. package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj +1 -1
  7. package/Microsoft.ReactNative/Pch/pch.h +2 -0
  8. package/Microsoft.ReactNative/ReactHost/CrashManager.cpp +5 -0
  9. package/Microsoft.ReactNative/ReactHost/ReactNativeHeaders.h +1 -0
  10. package/PropertySheets/External/Microsoft.ReactNative.Composition.CppLib.props +10 -0
  11. package/PropertySheets/External/Microsoft.ReactNative.Uwp.CppLib.props +10 -0
  12. package/PropertySheets/Generated/PackageVersion.g.props +3 -3
  13. package/ReactCommon/ReactCommon.vcxproj +10 -10
  14. package/ReactCommon/TEMP_UntilReactCommonUpdate/cxxreact/Instance.cpp +379 -0
  15. package/ReactCommon/TEMP_UntilReactCommonUpdate/cxxreact/JSExecutor.cpp +47 -0
  16. package/ReactCommon/TEMP_UntilReactCommonUpdate/cxxreact/JSIndexedRAMBundle.cpp +143 -0
  17. package/ReactCommon/TEMP_UntilReactCommonUpdate/cxxreact/MethodCall.cpp +98 -0
  18. package/ReactCommon/TEMP_UntilReactCommonUpdate/cxxreact/ModuleRegistry.cpp +254 -0
  19. package/ReactCommon/TEMP_UntilReactCommonUpdate/cxxreact/NativeToJsBridge.cpp +9 -0
  20. package/ReactCommon/TEMP_UntilReactCommonUpdate/cxxreact/RAMBundleRegistry.cpp +91 -0
  21. package/ReactCommon/TEMP_UntilReactCommonUpdate/cxxreact/ReactMarker.cpp +147 -0
  22. package/ReactCommon/TEMP_UntilReactCommonUpdate/jsiexecutor/jsireact/JSIExecutor.cpp +622 -0
  23. package/ReactCommon/TEMP_UntilReactCommonUpdate/jsiexecutor/jsireact/JSINativeModules.cpp +121 -0
  24. package/ReactCommon/TEMP_UntilReactCommonUpdate/react/nativemodule/webperformance/NativePerformance.cpp +409 -0
  25. package/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/BaseViewProps.cpp +628 -0
  26. package/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/core/EventDispatcher.cpp +79 -0
  27. package/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/core/EventQueueProcessor.cpp +138 -0
  28. package/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/uimanager/UIManager.cpp +732 -0
  29. package/ReactCommon/TEMP_UntilReactCommonUpdate/react/runtime/ReactInstance.cpp +687 -0
  30. package/Shared/Shared.vcxitems +9 -9
  31. package/package.json +1 -1
  32. package/templates/cpp-app/windows/MyApp/MyApp.vcxproj +2 -0
@@ -0,0 +1,732 @@
1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ #if _MSC_VER
9
+ #pragma warning(push)
10
+ #pragma warning(disable : 4996) // deprecated APIs
11
+ #endif
12
+ #include "UIManager.h"
13
+
14
+ #include <cxxreact/JSExecutor.h>
15
+ #include <cxxreact/TraceSection.h>
16
+ #include <react/debug/react_native_assert.h>
17
+ #include <react/featureflags/ReactNativeFeatureFlags.h>
18
+ #include <react/renderer/core/DynamicPropsUtilities.h>
19
+ #include <react/renderer/core/PropsParserContext.h>
20
+ #include <react/renderer/core/ShadowNodeFragment.h>
21
+ #include <react/renderer/uimanager/AppRegistryBinding.h>
22
+ #include <react/renderer/uimanager/UIManagerBinding.h>
23
+ #include <react/renderer/uimanager/UIManagerCommitHook.h>
24
+ #include <react/renderer/uimanager/UIManagerMountHook.h>
25
+
26
+ #include <glog/logging.h>
27
+
28
+ #include <utility>
29
+
30
+ namespace {
31
+ std::unique_ptr<facebook::react::LeakChecker> constructLeakCheckerIfNeeded(
32
+ const facebook::react::RuntimeExecutor& runtimeExecutor) {
33
+ #ifdef REACT_NATIVE_DEBUG
34
+ return std::make_unique<facebook::react::LeakChecker>(runtimeExecutor);
35
+ #else
36
+ return {};
37
+ #endif
38
+ }
39
+ } // namespace
40
+
41
+ namespace facebook::react {
42
+
43
+ // Explicitly define destructors here, as they have to exist in order to act as
44
+ // a "key function" for the ShadowNodeWrapper class -- this allows for RTTI to
45
+ // work properly across dynamic library boundaries (i.e. dynamic_cast that is
46
+ // used by getNativeState method)
47
+ ShadowNodeListWrapper::~ShadowNodeListWrapper() = default;
48
+
49
+ UIManager::UIManager(
50
+ const RuntimeExecutor& runtimeExecutor,
51
+ std::shared_ptr<const ContextContainer> contextContainer)
52
+ : runtimeExecutor_(runtimeExecutor),
53
+ shadowTreeRegistry_(),
54
+ contextContainer_(std::move(contextContainer)),
55
+ leakChecker_(constructLeakCheckerIfNeeded(runtimeExecutor)),
56
+ lazyShadowTreeRevisionConsistencyManager_(
57
+ std::make_unique<LazyShadowTreeRevisionConsistencyManager>(
58
+ shadowTreeRegistry_)) {}
59
+
60
+ UIManager::~UIManager() {
61
+ LOG(WARNING) << "UIManager::~UIManager() was called (address: " << this
62
+ << ").";
63
+ }
64
+
65
+ std::shared_ptr<ShadowNode> UIManager::createNode(
66
+ Tag tag,
67
+ const std::string& name,
68
+ SurfaceId surfaceId,
69
+ RawProps rawProps,
70
+ InstanceHandle::Shared instanceHandle) const {
71
+ TraceSection s("UIManager::createNode", "componentName", name);
72
+
73
+ auto& componentDescriptor = componentDescriptorRegistry_->at(name);
74
+ auto fallbackDescriptor =
75
+ componentDescriptorRegistry_->getFallbackComponentDescriptor();
76
+
77
+ PropsParserContext propsParserContext{surfaceId, *contextContainer_.get()};
78
+
79
+ auto family = componentDescriptor.createFamily(
80
+ {tag, surfaceId, std::move(instanceHandle)});
81
+ const auto props = componentDescriptor.cloneProps(
82
+ propsParserContext, nullptr, std::move(rawProps));
83
+ const auto state = componentDescriptor.createInitialState(props, family);
84
+
85
+ auto shadowNode = componentDescriptor.createShadowNode(
86
+ ShadowNodeFragment{
87
+ .props = fallbackDescriptor != nullptr &&
88
+ fallbackDescriptor->getComponentHandle() ==
89
+ componentDescriptor.getComponentHandle()
90
+ ? componentDescriptor.cloneProps(
91
+ propsParserContext,
92
+ props,
93
+ RawProps(folly::dynamic::object("name", name)))
94
+ : props,
95
+ .children = ShadowNodeFragment::childrenPlaceholder(),
96
+ .state = state,
97
+ },
98
+ family);
99
+
100
+ if (delegate_ != nullptr) {
101
+ delegate_->uiManagerDidCreateShadowNode(*shadowNode);
102
+ }
103
+ if (leakChecker_) {
104
+ leakChecker_->uiManagerDidCreateShadowNodeFamily(family);
105
+ }
106
+
107
+ return shadowNode;
108
+ }
109
+
110
+ std::shared_ptr<ShadowNode> UIManager::cloneNode(
111
+ const ShadowNode& shadowNode,
112
+ const ShadowNode::SharedListOfShared& children,
113
+ RawProps rawProps) const {
114
+ TraceSection s(
115
+ "UIManager::cloneNode", "componentName", shadowNode.getComponentName());
116
+
117
+ PropsParserContext propsParserContext{
118
+ shadowNode.getFamily().getSurfaceId(), *contextContainer_.get()};
119
+
120
+ auto& componentDescriptor = shadowNode.getComponentDescriptor();
121
+ auto& family = shadowNode.getFamily();
122
+ auto props = ShadowNodeFragment::propsPlaceholder();
123
+
124
+ if (!rawProps.isEmpty()) {
125
+ if (family.nativeProps_DEPRECATED != nullptr) {
126
+ // 1. update the nativeProps_DEPRECATED props.
127
+ //
128
+ // In this step, we want the most recent value for the props
129
+ // managed by setNativeProps.
130
+ // Values in `rawProps` patch (take precedence over)
131
+ // `nativeProps_DEPRECATED`. For example, if both
132
+ // `nativeProps_DEPRECATED` and `rawProps` contain key 'A'.
133
+ // Value from `rawProps` overrides what was previously in
134
+ // `nativeProps_DEPRECATED`. Notice that the `nativeProps_DEPRECATED`
135
+ // patch will not get more props from `rawProps`: if the key is not
136
+ // present in `nativeProps_DEPRECATED`, it will not be added.
137
+ //
138
+ // The result of this operation is the new `nativeProps_DEPRECATED`.
139
+ family.nativeProps_DEPRECATED =
140
+ std::make_unique<folly::dynamic>(mergeDynamicProps(
141
+ *family.nativeProps_DEPRECATED, // source
142
+ (folly::dynamic)rawProps, // patch
143
+ NullValueStrategy::Ignore));
144
+
145
+ // 2. Compute the final set of props.
146
+ //
147
+ // This step takes the new props handled by `setNativeProps` and
148
+ // merges them in the `rawProps` managed by React.
149
+ // The new props handled by `nativeProps` now takes precedence
150
+ // on the props handled by React, as we want to make sure that
151
+ // all the props are applied to the component.
152
+ // We use these finalProps as source of truth for the component.
153
+ auto finalProps = mergeDynamicProps(
154
+ (folly::dynamic)rawProps, // source
155
+ *family.nativeProps_DEPRECATED, // patch
156
+ NullValueStrategy::Override);
157
+
158
+ // 3. Clone the props by using finalProps.
159
+ props = componentDescriptor.cloneProps(
160
+ propsParserContext, shadowNode.getProps(), RawProps(finalProps));
161
+ } else {
162
+ props = componentDescriptor.cloneProps(
163
+ propsParserContext, shadowNode.getProps(), std::move(rawProps));
164
+ }
165
+ }
166
+
167
+ auto clonedShadowNode = componentDescriptor.cloneShadowNode(
168
+ shadowNode,
169
+ {
170
+ .props = props,
171
+ .children = children,
172
+ .runtimeShadowNodeReference = false,
173
+ });
174
+
175
+ return clonedShadowNode;
176
+ }
177
+
178
+ void UIManager::appendChild(
179
+ const std::shared_ptr<const ShadowNode>& parentShadowNode,
180
+ const std::shared_ptr<const ShadowNode>& childShadowNode) const {
181
+ TraceSection s("UIManager::appendChild");
182
+
183
+ auto& componentDescriptor = parentShadowNode->getComponentDescriptor();
184
+ componentDescriptor.appendChild(parentShadowNode, childShadowNode);
185
+ }
186
+
187
+ void UIManager::completeSurface(
188
+ SurfaceId surfaceId,
189
+ const ShadowNode::UnsharedListOfShared& rootChildren,
190
+ ShadowTree::CommitOptions commitOptions) {
191
+ TraceSection s("UIManager::completeSurface", "surfaceId", surfaceId);
192
+
193
+ shadowTreeRegistry_.visit(surfaceId, [&](const ShadowTree& shadowTree) {
194
+ auto result = shadowTree.commit(
195
+ [&](const RootShadowNode& oldRootShadowNode) {
196
+ return std::make_shared<RootShadowNode>(
197
+ oldRootShadowNode,
198
+ ShadowNodeFragment{
199
+ .props = ShadowNodeFragment::propsPlaceholder(),
200
+ .children = rootChildren,
201
+ });
202
+ },
203
+ commitOptions);
204
+
205
+ if (result == ShadowTree::CommitStatus::Succeeded) {
206
+ // It's safe to update the visible revision of the shadow tree immediately
207
+ // after we commit a specific one.
208
+ lazyShadowTreeRevisionConsistencyManager_->updateCurrentRevision(
209
+ surfaceId, shadowTree.getCurrentRevision().rootShadowNode);
210
+ }
211
+ });
212
+ }
213
+
214
+ void UIManager::setIsJSResponder(
215
+ const std::shared_ptr<const ShadowNode>& shadowNode,
216
+ bool isJSResponder,
217
+ bool blockNativeResponder) const {
218
+ if (delegate_ != nullptr) {
219
+ delegate_->uiManagerDidSetIsJSResponder(
220
+ shadowNode, isJSResponder, blockNativeResponder);
221
+ }
222
+ }
223
+
224
+ void UIManager::startSurface(
225
+ ShadowTree::Unique&& shadowTree,
226
+ const std::string& moduleName,
227
+ const folly::dynamic& props,
228
+ DisplayMode displayMode) const noexcept {
229
+ TraceSection s("UIManager::startSurface");
230
+
231
+ auto surfaceId = shadowTree->getSurfaceId();
232
+ shadowTreeRegistry_.add(std::move(shadowTree));
233
+
234
+ shadowTreeRegistry_.visit(
235
+ surfaceId, [delegate = delegate_](const ShadowTree& shadowTree) {
236
+ if (delegate != nullptr) {
237
+ delegate->uiManagerDidStartSurface(shadowTree);
238
+ }
239
+ });
240
+
241
+ runtimeExecutor_([=](jsi::Runtime& runtime) {
242
+ TraceSection s("UIManager::startSurface::onRuntime");
243
+ AppRegistryBinding::startSurface(
244
+ runtime, surfaceId, moduleName, props, displayMode);
245
+ });
246
+ }
247
+
248
+ void UIManager::startEmptySurface(
249
+ ShadowTree::Unique&& shadowTree) const noexcept {
250
+ TraceSection s("UIManager::startEmptySurface");
251
+ shadowTreeRegistry_.add(std::move(shadowTree));
252
+ }
253
+
254
+ void UIManager::setSurfaceProps(
255
+ SurfaceId surfaceId,
256
+ const std::string& moduleName,
257
+ const folly::dynamic& props,
258
+ DisplayMode displayMode) const noexcept {
259
+ TraceSection s("UIManager::setSurfaceProps");
260
+
261
+ runtimeExecutor_([=](jsi::Runtime& runtime) {
262
+ AppRegistryBinding::setSurfaceProps(
263
+ runtime, surfaceId, moduleName, props, displayMode);
264
+ });
265
+ }
266
+
267
+ ShadowTree::Unique UIManager::stopSurface(SurfaceId surfaceId) const {
268
+ TraceSection s("UIManager::stopSurface");
269
+
270
+ // Stop any ongoing animations.
271
+ stopSurfaceForAnimationDelegate(surfaceId);
272
+
273
+ // Waiting for all concurrent commits to be finished and unregistering the
274
+ // `ShadowTree`.
275
+ auto shadowTree = getShadowTreeRegistry().remove(surfaceId);
276
+ if (shadowTree) {
277
+ // We execute JavaScript/React part of the process at the very end to
278
+ // minimize any visible side-effects of stopping the Surface. Any possible
279
+ // commits from the JavaScript side will not be able to reference a
280
+ // `ShadowTree` and will fail silently.
281
+ runtimeExecutor_([=](jsi::Runtime& runtime) {
282
+ AppRegistryBinding::stopSurface(runtime, surfaceId);
283
+ });
284
+
285
+ if (leakChecker_) {
286
+ leakChecker_->stopSurface(surfaceId);
287
+ }
288
+ }
289
+ return shadowTree;
290
+ }
291
+
292
+ std::shared_ptr<const ShadowNode> UIManager::getNewestCloneOfShadowNode(
293
+ const ShadowNode& shadowNode) const {
294
+ auto ancestorShadowNode = std::shared_ptr<const ShadowNode>{};
295
+ shadowTreeRegistry_.visit(
296
+ shadowNode.getSurfaceId(), [&](const ShadowTree& shadowTree) {
297
+ ancestorShadowNode = shadowTree.getCurrentRevision().rootShadowNode;
298
+ });
299
+ return getShadowNodeInSubtree(shadowNode, ancestorShadowNode);
300
+ }
301
+
302
+ std::shared_ptr<const ShadowNode> UIManager::getShadowNodeInSubtree(
303
+ const ShadowNode& shadowNode,
304
+ const std::shared_ptr<const ShadowNode>& ancestorShadowNode) const {
305
+ if (!ancestorShadowNode) {
306
+ return nullptr;
307
+ }
308
+
309
+ // If the given shadow node is of the same family as the root shadow node,
310
+ // return the latest root shadow node
311
+ if (ShadowNode::sameFamily(*ancestorShadowNode, shadowNode)) {
312
+ return ancestorShadowNode;
313
+ }
314
+
315
+ auto ancestors = shadowNode.getFamily().getAncestors(*ancestorShadowNode);
316
+
317
+ if (ancestors.empty()) {
318
+ return nullptr;
319
+ }
320
+
321
+ auto pair = ancestors.rbegin();
322
+ return pair->first.get().getChildren().at(pair->second);
323
+ }
324
+
325
+ ShadowTreeRevisionConsistencyManager*
326
+ UIManager::getShadowTreeRevisionConsistencyManager() {
327
+ return lazyShadowTreeRevisionConsistencyManager_.get();
328
+ }
329
+
330
+ ShadowTreeRevisionProvider* UIManager::getShadowTreeRevisionProvider() {
331
+ return lazyShadowTreeRevisionConsistencyManager_.get();
332
+ }
333
+
334
+ std::shared_ptr<const ShadowNode> UIManager::findNodeAtPoint(
335
+ const std::shared_ptr<const ShadowNode>& node,
336
+ Point point) const {
337
+ return LayoutableShadowNode::findNodeAtPoint(
338
+ getNewestCloneOfShadowNode(*node), point);
339
+ }
340
+
341
+ LayoutMetrics UIManager::getRelativeLayoutMetrics(
342
+ const ShadowNode& shadowNode,
343
+ const ShadowNode* ancestorShadowNode,
344
+ LayoutableShadowNode::LayoutInspectingPolicy policy) const {
345
+ TraceSection s("UIManager::getRelativeLayoutMetrics");
346
+
347
+ // We might store here an owning pointer to `ancestorShadowNode` to ensure
348
+ // that the node is not deallocated during method execution lifetime.
349
+ auto owningAncestorShadowNode = std::shared_ptr<const ShadowNode>{};
350
+
351
+ if (ancestorShadowNode == nullptr) {
352
+ shadowTreeRegistry_.visit(
353
+ shadowNode.getSurfaceId(), [&](const ShadowTree& shadowTree) {
354
+ owningAncestorShadowNode =
355
+ shadowTree.getCurrentRevision().rootShadowNode;
356
+ ancestorShadowNode = owningAncestorShadowNode.get();
357
+ });
358
+ } else {
359
+ // It is possible for JavaScript (or other callers) to have a reference
360
+ // to a previous version of ShadowNodes, but we enforce that
361
+ // metrics are only calculated on most recently committed versions.
362
+ owningAncestorShadowNode = getNewestCloneOfShadowNode(*ancestorShadowNode);
363
+ ancestorShadowNode = owningAncestorShadowNode.get();
364
+ }
365
+
366
+ auto layoutableAncestorShadowNode =
367
+ dynamic_cast<const LayoutableShadowNode*>(ancestorShadowNode);
368
+
369
+ if (layoutableAncestorShadowNode == nullptr) {
370
+ return EmptyLayoutMetrics;
371
+ }
372
+
373
+ return LayoutableShadowNode::computeRelativeLayoutMetrics(
374
+ shadowNode.getFamily(), *layoutableAncestorShadowNode, policy);
375
+ }
376
+
377
+ void UIManager::updateState(const StateUpdate& stateUpdate) const {
378
+ TraceSection s(
379
+ "UIManager::updateState",
380
+ "componentName",
381
+ stateUpdate.family->getComponentName());
382
+ auto& callback = stateUpdate.callback;
383
+ auto& family = stateUpdate.family;
384
+ auto& componentDescriptor = family->getComponentDescriptor();
385
+
386
+ shadowTreeRegistry_.visit(
387
+ family->getSurfaceId(), [&](const ShadowTree& shadowTree) {
388
+ shadowTree.commit(
389
+ [&](const RootShadowNode& oldRootShadowNode) {
390
+ auto isValid = true;
391
+
392
+ auto rootNode = oldRootShadowNode.cloneTree(
393
+ *family, [&](const ShadowNode& oldShadowNode) {
394
+ auto newData =
395
+ callback(oldShadowNode.getState()->getDataPointer());
396
+
397
+ if (!newData) {
398
+ isValid = false;
399
+ // Just return something, we will discard it anyway.
400
+ return oldShadowNode.clone({});
401
+ }
402
+
403
+ auto newState =
404
+ componentDescriptor.createState(*family, newData);
405
+
406
+ return oldShadowNode.clone(
407
+ {.props = ShadowNodeFragment::propsPlaceholder(),
408
+ .children = ShadowNodeFragment::childrenPlaceholder(),
409
+ .state = newState});
410
+ });
411
+
412
+ return isValid
413
+ ? std::static_pointer_cast<RootShadowNode>(rootNode)
414
+ : nullptr;
415
+ },
416
+ {/* default commit options */});
417
+ });
418
+ }
419
+
420
+ void UIManager::dispatchCommand(
421
+ const std::shared_ptr<const ShadowNode>& shadowNode,
422
+ const std::string& commandName,
423
+ const folly::dynamic& args) const {
424
+ if (delegate_ != nullptr) {
425
+ delegate_->uiManagerDidDispatchCommand(shadowNode, commandName, args);
426
+ }
427
+ }
428
+
429
+ void UIManager::setNativeProps_DEPRECATED(
430
+ const std::shared_ptr<const ShadowNode>& shadowNode,
431
+ RawProps rawProps) const {
432
+ auto& family = shadowNode->getFamily();
433
+ if (family.nativeProps_DEPRECATED) {
434
+ // Values in `rawProps` patch (take precedence over)
435
+ // `nativeProps_DEPRECATED`. For example, if both `nativeProps_DEPRECATED`
436
+ // and `rawProps` contain key 'A'. Value from `rawProps` overrides what was
437
+ // previously in `nativeProps_DEPRECATED`.
438
+ family.nativeProps_DEPRECATED =
439
+ std::make_unique<folly::dynamic>(mergeDynamicProps(
440
+ *family.nativeProps_DEPRECATED,
441
+ (folly::dynamic)rawProps,
442
+ NullValueStrategy::Override));
443
+ } else {
444
+ family.nativeProps_DEPRECATED =
445
+ std::make_unique<folly::dynamic>((folly::dynamic)rawProps);
446
+ }
447
+
448
+ shadowTreeRegistry_.visit(
449
+ family.getSurfaceId(), [&](const ShadowTree& shadowTree) {
450
+ // The lambda passed to `commit` may be executed multiple times.
451
+ // We need to create fresh copy of the `RawProps` object each time.
452
+ auto ancestorShadowNode =
453
+ shadowTree.getCurrentRevision().rootShadowNode;
454
+ shadowTree.commit(
455
+ [&](const RootShadowNode& oldRootShadowNode) {
456
+ auto rootNode = oldRootShadowNode.cloneTree(
457
+ family, [&](const ShadowNode& oldShadowNode) {
458
+ auto& componentDescriptor =
459
+ componentDescriptorRegistry_->at(
460
+ shadowNode->getComponentHandle());
461
+ PropsParserContext propsParserContext{
462
+ family.getSurfaceId(), *contextContainer_.get()};
463
+ auto props = componentDescriptor.cloneProps(
464
+ propsParserContext,
465
+ getShadowNodeInSubtree(*shadowNode, ancestorShadowNode)
466
+ ->getProps(),
467
+ RawProps(rawProps));
468
+
469
+ return oldShadowNode.clone({/* .props = */ props});
470
+ });
471
+
472
+ return std::static_pointer_cast<RootShadowNode>(rootNode);
473
+ },
474
+ {/* default commit options */});
475
+ });
476
+ }
477
+
478
+ void UIManager::sendAccessibilityEvent(
479
+ const std::shared_ptr<const ShadowNode>& shadowNode,
480
+ const std::string& eventType) {
481
+ if (delegate_ != nullptr) {
482
+ delegate_->uiManagerDidSendAccessibilityEvent(shadowNode, eventType);
483
+ }
484
+ }
485
+
486
+ void UIManager::configureNextLayoutAnimation(
487
+ jsi::Runtime& runtime,
488
+ const RawValue& config,
489
+ const jsi::Value& successCallback,
490
+ const jsi::Value& failureCallback) const {
491
+ if (animationDelegate_ != nullptr) {
492
+ animationDelegate_->uiManagerDidConfigureNextLayoutAnimation(
493
+ runtime,
494
+ config,
495
+ std::move(successCallback),
496
+ std::move(failureCallback));
497
+ }
498
+ }
499
+
500
+ static std::shared_ptr<const ShadowNode> findShadowNodeByTagRecursively(
501
+ std::shared_ptr<const ShadowNode> parentShadowNode,
502
+ Tag tag) {
503
+ if (parentShadowNode->getTag() == tag) {
504
+ return parentShadowNode;
505
+ }
506
+
507
+ for (const std::shared_ptr<const ShadowNode>& shadowNode :
508
+ parentShadowNode->getChildren()) {
509
+ auto result = findShadowNodeByTagRecursively(shadowNode, tag);
510
+ if (result) {
511
+ return result;
512
+ }
513
+ }
514
+
515
+ return nullptr;
516
+ }
517
+
518
+ std::shared_ptr<const ShadowNode> UIManager::findShadowNodeByTag_DEPRECATED(
519
+ Tag tag) const {
520
+ auto shadowNode = std::shared_ptr<const ShadowNode>{};
521
+
522
+ shadowTreeRegistry_.enumerate([&](const ShadowTree& shadowTree, bool& stop) {
523
+ const RootShadowNode* rootShadowNode = nullptr;
524
+ // The public interface of `ShadowTree` discourages accessing a stored
525
+ // pointer to a root node because of the possible data race.
526
+ // To work around this, we ask for a commit and immediately cancel it
527
+ // returning `nullptr` instead of a new shadow tree.
528
+ // We don't want to add a way to access a stored pointer to a root node
529
+ // because this `findShadowNodeByTag` is deprecated. It is only added
530
+ // to make migration to the new architecture easier.
531
+ shadowTree.tryCommit(
532
+ [&](const RootShadowNode& oldRootShadowNode) {
533
+ rootShadowNode = &oldRootShadowNode;
534
+ return nullptr;
535
+ },
536
+ {/* default commit options */});
537
+
538
+ if (rootShadowNode != nullptr) {
539
+ const auto& children = rootShadowNode->getChildren();
540
+ if (!children.empty()) {
541
+ const auto& child = children.front();
542
+ shadowNode = findShadowNodeByTagRecursively(child, tag);
543
+ if (shadowNode) {
544
+ stop = true;
545
+ }
546
+ }
547
+ }
548
+ });
549
+
550
+ return shadowNode;
551
+ }
552
+
553
+ void UIManager::setComponentDescriptorRegistry(
554
+ const SharedComponentDescriptorRegistry& componentDescriptorRegistry) {
555
+ componentDescriptorRegistry_ = componentDescriptorRegistry;
556
+ }
557
+
558
+ void UIManager::setDelegate(UIManagerDelegate* delegate) {
559
+ delegate_ = delegate;
560
+ }
561
+
562
+ UIManagerDelegate* UIManager::getDelegate() {
563
+ return delegate_;
564
+ }
565
+
566
+ void UIManager::visitBinding(
567
+ const std::function<void(const UIManagerBinding& uiManagerBinding)>&
568
+ callback,
569
+ jsi::Runtime& runtime) const {
570
+ auto uiManagerBinding = UIManagerBinding::getBinding(runtime);
571
+ if (uiManagerBinding) {
572
+ callback(*uiManagerBinding);
573
+ }
574
+ }
575
+
576
+ const ShadowTreeRegistry& UIManager::getShadowTreeRegistry() const {
577
+ return shadowTreeRegistry_;
578
+ }
579
+
580
+ void UIManager::registerCommitHook(UIManagerCommitHook& commitHook) {
581
+ std::unique_lock lock(commitHookMutex_);
582
+ react_native_assert(
583
+ std::find(commitHooks_.begin(), commitHooks_.end(), &commitHook) ==
584
+ commitHooks_.end());
585
+ commitHook.commitHookWasRegistered(*this);
586
+ commitHooks_.push_back(&commitHook);
587
+ }
588
+
589
+ void UIManager::unregisterCommitHook(UIManagerCommitHook& commitHook) {
590
+ std::unique_lock lock(commitHookMutex_);
591
+ auto iterator =
592
+ std::find(commitHooks_.begin(), commitHooks_.end(), &commitHook);
593
+ react_native_assert(iterator != commitHooks_.end());
594
+ commitHooks_.erase(iterator);
595
+ commitHook.commitHookWasUnregistered(*this);
596
+ }
597
+
598
+ void UIManager::registerMountHook(UIManagerMountHook& mountHook) {
599
+ std::unique_lock lock(mountHookMutex_);
600
+ react_native_assert(
601
+ std::find(mountHooks_.begin(), mountHooks_.end(), &mountHook) ==
602
+ mountHooks_.end());
603
+ mountHooks_.push_back(&mountHook);
604
+ }
605
+
606
+ void UIManager::unregisterMountHook(UIManagerMountHook& mountHook) {
607
+ std::unique_lock lock(mountHookMutex_);
608
+ auto iterator = std::find(mountHooks_.begin(), mountHooks_.end(), &mountHook);
609
+ react_native_assert(iterator != mountHooks_.end());
610
+ mountHooks_.erase(iterator);
611
+ }
612
+
613
+ #pragma mark - ShadowTreeDelegate
614
+
615
+ RootShadowNode::Unshared UIManager::shadowTreeWillCommit(
616
+ const ShadowTree& shadowTree,
617
+ const RootShadowNode::Shared& oldRootShadowNode,
618
+ const RootShadowNode::Unshared& newRootShadowNode,
619
+ const ShadowTree::CommitOptions& commitOptions) const {
620
+ TraceSection s("UIManager::shadowTreeWillCommit");
621
+
622
+ std::shared_lock lock(commitHookMutex_);
623
+
624
+ auto resultRootShadowNode = newRootShadowNode;
625
+ for (auto* commitHook : commitHooks_) {
626
+ resultRootShadowNode = commitHook->shadowTreeWillCommit(
627
+ shadowTree, oldRootShadowNode, resultRootShadowNode, commitOptions);
628
+ }
629
+
630
+ return resultRootShadowNode;
631
+ }
632
+
633
+ void UIManager::shadowTreeDidFinishTransaction(
634
+ std::shared_ptr<const MountingCoordinator> mountingCoordinator,
635
+ bool mountSynchronously) const {
636
+ TraceSection s("UIManager::shadowTreeDidFinishTransaction");
637
+
638
+ if (delegate_ != nullptr) {
639
+ delegate_->uiManagerDidFinishTransaction(
640
+ std::move(mountingCoordinator), mountSynchronously);
641
+ }
642
+ }
643
+
644
+ void UIManager::reportMount(SurfaceId surfaceId) const {
645
+ TraceSection s("UIManager::reportMount");
646
+
647
+ auto time = HighResTimeStamp::now();
648
+
649
+ auto rootShadowNode = RootShadowNode::Shared{};
650
+ shadowTreeRegistry_.visit(surfaceId, [&](const ShadowTree& shadowTree) {
651
+ rootShadowNode =
652
+ shadowTree.getMountingCoordinator()->getBaseRevision().rootShadowNode;
653
+ });
654
+
655
+ {
656
+ std::shared_lock lock(mountHookMutex_);
657
+
658
+ for (auto* mountHook : mountHooks_) {
659
+ if (rootShadowNode) {
660
+ mountHook->shadowTreeDidMount(rootShadowNode, time);
661
+ } else {
662
+ mountHook->shadowTreeDidUnmount(surfaceId, time);
663
+ }
664
+ }
665
+ }
666
+ }
667
+
668
+ #pragma mark - UIManagerAnimationDelegate
669
+
670
+ void UIManager::setAnimationDelegate(UIManagerAnimationDelegate* delegate) {
671
+ animationDelegate_ = delegate;
672
+ }
673
+
674
+ void UIManager::stopSurfaceForAnimationDelegate(SurfaceId surfaceId) const {
675
+ if (animationDelegate_ != nullptr) {
676
+ animationDelegate_->stopSurface(surfaceId);
677
+ }
678
+ }
679
+
680
+ void UIManager::setNativeAnimatedDelegate(
681
+ std::weak_ptr<UIManagerNativeAnimatedDelegate> delegate) {
682
+ nativeAnimatedDelegate_ = delegate;
683
+ }
684
+
685
+ void UIManager::animationTick() const {
686
+ if (animationDelegate_ != nullptr &&
687
+ animationDelegate_->shouldAnimateFrame()) {
688
+ shadowTreeRegistry_.enumerate([](const ShadowTree& shadowTree, bool&) {
689
+ shadowTree.notifyDelegatesOfUpdates();
690
+ });
691
+ }
692
+
693
+ if (auto nativeAnimatedDelegate = nativeAnimatedDelegate_.lock()) {
694
+ nativeAnimatedDelegate->runAnimationFrame();
695
+ }
696
+ }
697
+
698
+ void UIManager::synchronouslyUpdateViewOnUIThread(
699
+ Tag tag,
700
+ const folly::dynamic& props) {
701
+ if (delegate_ != nullptr) {
702
+ delegate_->uiManagerShouldSynchronouslyUpdateViewOnUIThread(tag, props);
703
+ }
704
+ }
705
+
706
+ #pragma mark - Add & Remove event listener
707
+
708
+ void UIManager::addEventListener(
709
+ std::shared_ptr<const EventListener> listener) {
710
+ if (delegate_ != nullptr) {
711
+ delegate_->uiManagerShouldAddEventListener(listener);
712
+ }
713
+ }
714
+
715
+ void UIManager::removeEventListener(
716
+ const std::shared_ptr<const EventListener>& listener) {
717
+ if (delegate_ != nullptr) {
718
+ delegate_->uiManagerShouldRemoveEventListener(listener);
719
+ }
720
+ }
721
+
722
+ void UIManager::setOnSurfaceStartCallback(
723
+ UIManagerDelegate::OnSurfaceStartCallback&& callback) {
724
+ if (delegate_ != nullptr) {
725
+ delegate_->uiManagerShouldSetOnSurfaceStartCallback(std::move(callback));
726
+ }
727
+ }
728
+
729
+ } // namespace facebook::react
730
+ #if _MSC_VER
731
+ #pragma warning(pop)
732
+ #endif