diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/Binding.cpp b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/Binding.cpp index f8419c8dacf..843a110d56f 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/Binding.cpp +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/Binding.cpp @@ -275,6 +275,7 @@ void Binding::startSurface( layoutContext.pointScaleFactor = pointScaleFactor_; auto surfaceHandler = SurfaceHandler{moduleName->toStdString(), surfaceId}; + surfaceHandler.setContextContainer(scheduler->getContextContainer()); surfaceHandler.setProps(initialProps->consume()); surfaceHandler.constraintLayout({}, layoutContext); @@ -336,6 +337,7 @@ void Binding::startSurfaceWithConstraints( isRTL ? LayoutDirection::RightToLeft : LayoutDirection::LeftToRight; auto surfaceHandler = SurfaceHandler{moduleName->toStdString(), surfaceId}; + surfaceHandler.setContextContainer(scheduler_->getContextContainer()); surfaceHandler.setProps(initialProps->consume()); surfaceHandler.constraintLayout(constraints, context); diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/CoreComponentsRegistry.cpp b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/CoreComponentsRegistry.cpp index f92c84d625c..477c819b58b 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/CoreComponentsRegistry.cpp +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/CoreComponentsRegistry.cpp @@ -87,9 +87,10 @@ CoreComponentsRegistry::initHybrid( [](EventDispatcher::Weak const &eventDispatcher, ContextContainer::Shared const &contextContainer) -> ComponentDescriptorRegistry::Shared { - auto registry = CoreComponentsRegistry::sharedProviderRegistry() - ->createComponentDescriptorRegistry( - {eventDispatcher, contextContainer}); + auto registry = + CoreComponentsRegistry::sharedProviderRegistry() + ->createComponentDescriptorRegistry( + {eventDispatcher, contextContainer}, contextContainer); auto mutableRegistry = std::const_pointer_cast(registry); mutableRegistry->setFallbackComponentDescriptor( diff --git a/ReactCommon/react/renderer/animations/LayoutAnimationKeyFrameManager.cpp b/ReactCommon/react/renderer/animations/LayoutAnimationKeyFrameManager.cpp index 46ccd76eabe..ecf5c3568d5 100644 --- a/ReactCommon/react/renderer/animations/LayoutAnimationKeyFrameManager.cpp +++ b/ReactCommon/react/renderer/animations/LayoutAnimationKeyFrameManager.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -828,6 +829,15 @@ LayoutAnimationKeyFrameManager::pullTransaction( LOG(ERROR) << "BEGINNING DONE DISPLAYING ONGOING inflightAnimations_!"; #endif + // Stub PropsParserContext used for cloneProps. + // This is/should be safe because cloning doesn't actually need to + // parse props, and just copies them; therefore there should be no + // need to actually use anything in the PropsParserContext. + // If this ever changes, the LayoutAnimations API will need to change + // to pass in a real PropsParserContext. + ContextContainer contextContainer{}; + PropsParserContext propsParserContext{surfaceId, contextContainer}; + // What to do if we detect a conflict? Get current value and make // that the baseline of the next animation. Scale the remaining time // in the animation @@ -1082,7 +1092,7 @@ LayoutAnimationKeyFrameManager::pullTransaction( haveComponentDescriptor) { auto props = getComponentDescriptorForShadowView(baselineShadowView) - .cloneProps(viewStart.props, {}); + .cloneProps(propsParserContext, viewStart.props, {}); // Dynamic cast, because - we don't know the type of this // ShadowNode, it could be Image or Text or something else with @@ -1107,7 +1117,7 @@ LayoutAnimationKeyFrameManager::pullTransaction( if ((isScaleX || isScaleY) && haveComponentDescriptor) { auto props = getComponentDescriptorForShadowView(baselineShadowView) - .cloneProps(viewStart.props, {}); + .cloneProps(propsParserContext, viewStart.props, {}); // Dynamic cast, because - we don't know the type of this // ShadowNode, it could be Image or Text or something else with @@ -1210,7 +1220,7 @@ LayoutAnimationKeyFrameManager::pullTransaction( haveComponentDescriptor) { auto props = getComponentDescriptorForShadowView(baselineShadowView) - .cloneProps(viewFinal.props, {}); + .cloneProps(propsParserContext, viewFinal.props, {}); // Dynamic cast, because - we don't know the type of this // ShadowNode, it could be Image or Text or something else with @@ -1237,7 +1247,7 @@ LayoutAnimationKeyFrameManager::pullTransaction( if ((isScaleX || isScaleY) && haveComponentDescriptor) { auto props = getComponentDescriptorForShadowView(baselineShadowView) - .cloneProps(viewFinal.props, {}); + .cloneProps(propsParserContext, viewFinal.props, {}); // Dynamic cast, because - we don't know the type of this // ShadowNode, it could be Image or Text or something else with @@ -1721,6 +1731,16 @@ ShadowView LayoutAnimationKeyFrameManager::createInterpolatedShadowView( react_native_assert(false); return finalView; } + + // Stub PropsParserContext used for interpolateProps. + // This is/should be safe because interpolating doesn't actually need to + // parse props, and just copies them; therefore there should be no + // need to actually use anything in the PropsParserContext. + // If this ever changes, the LayoutAnimations API will need to change + // to pass in a real PropsParserContext. + ContextContainer contextContainer{}; + PropsParserContext propsParserContext{-1, contextContainer}; + ComponentDescriptor const &componentDescriptor = getComponentDescriptorForShadowView(startingView); @@ -1742,7 +1762,7 @@ ShadowView LayoutAnimationKeyFrameManager::createInterpolatedShadowView( // Animate opacity or scale/transform mutatedShadowView.props = componentDescriptor.interpolateProps( - progress, startingView.props, finalView.props); + propsParserContext, progress, startingView.props, finalView.props); react_native_assert(mutatedShadowView.props != nullptr); if (mutatedShadowView.props == nullptr) { return finalView; diff --git a/ReactCommon/react/renderer/componentregistry/ComponentDescriptorProviderRegistry.cpp b/ReactCommon/react/renderer/componentregistry/ComponentDescriptorProviderRegistry.cpp index 4255db72157..3ffb39e493a 100644 --- a/ReactCommon/react/renderer/componentregistry/ComponentDescriptorProviderRegistry.cpp +++ b/ReactCommon/react/renderer/componentregistry/ComponentDescriptorProviderRegistry.cpp @@ -65,11 +65,12 @@ void ComponentDescriptorProviderRegistry::request( ComponentDescriptorRegistry::Shared ComponentDescriptorProviderRegistry::createComponentDescriptorRegistry( - ComponentDescriptorParameters const ¶meters) const { + ComponentDescriptorParameters const ¶meters, + ContextContainer::Shared contextContainer) const { std::shared_lock lock(mutex_); - auto registry = - std::make_shared(parameters, *this); + auto registry = std::make_shared( + parameters, *this, contextContainer); for (auto const &pair : componentDescriptorProviders_) { registry->add(pair.second); diff --git a/ReactCommon/react/renderer/componentregistry/ComponentDescriptorProviderRegistry.h b/ReactCommon/react/renderer/componentregistry/ComponentDescriptorProviderRegistry.h index 769f0f3b91c..25c3ed8c5cf 100644 --- a/ReactCommon/react/renderer/componentregistry/ComponentDescriptorProviderRegistry.h +++ b/ReactCommon/react/renderer/componentregistry/ComponentDescriptorProviderRegistry.h @@ -12,6 +12,7 @@ #include #include #include +#include namespace facebook { namespace react { @@ -51,7 +52,8 @@ class ComponentDescriptorProviderRegistry final { * The methods can be called on any thread. */ ComponentDescriptorRegistry::Shared createComponentDescriptorRegistry( - ComponentDescriptorParameters const ¶meters) const; + ComponentDescriptorParameters const ¶meters, + ContextContainer::Shared contextContainer) const; private: friend class ComponentDescriptorRegistry; diff --git a/ReactCommon/react/renderer/componentregistry/ComponentDescriptorRegistry.cpp b/ReactCommon/react/renderer/componentregistry/ComponentDescriptorRegistry.cpp index bfbc34fc512..137fb20cbbf 100644 --- a/ReactCommon/react/renderer/componentregistry/ComponentDescriptorRegistry.cpp +++ b/ReactCommon/react/renderer/componentregistry/ComponentDescriptorRegistry.cpp @@ -11,6 +11,7 @@ #include #include +#include #include namespace facebook { @@ -18,8 +19,11 @@ namespace react { ComponentDescriptorRegistry::ComponentDescriptorRegistry( ComponentDescriptorParameters const ¶meters, - ComponentDescriptorProviderRegistry const &providerRegistry) - : parameters_(parameters), providerRegistry_(providerRegistry) {} + ComponentDescriptorProviderRegistry const &providerRegistry, + ContextContainer::Shared contextContainer) + : parameters_(parameters), + providerRegistry_(providerRegistry), + contextContainer_(contextContainer) {} void ComponentDescriptorRegistry::add( ComponentDescriptorProvider componentDescriptorProvider) const { @@ -132,8 +136,10 @@ SharedShadowNode ComponentDescriptorRegistry::createNode( auto const fragment = ShadowNodeFamilyFragment{tag, surfaceId, nullptr}; auto family = componentDescriptor.createFamily(fragment, std::move(eventTarget)); - auto const props = - componentDescriptor.cloneProps(nullptr, RawProps(propsDynamic)); + auto const props = componentDescriptor.cloneProps( + PropsParserContext{surfaceId, *contextContainer_.get()}, + nullptr, + RawProps(propsDynamic)); auto const state = componentDescriptor.createInitialState(ShadowNodeFragment{props}, family); diff --git a/ReactCommon/react/renderer/componentregistry/ComponentDescriptorRegistry.h b/ReactCommon/react/renderer/componentregistry/ComponentDescriptorRegistry.h index 29dac6f371e..e23d41c1461 100644 --- a/ReactCommon/react/renderer/componentregistry/ComponentDescriptorRegistry.h +++ b/ReactCommon/react/renderer/componentregistry/ComponentDescriptorRegistry.h @@ -14,6 +14,7 @@ #include #include +#include namespace facebook { namespace react { @@ -37,7 +38,8 @@ class ComponentDescriptorRegistry { */ ComponentDescriptorRegistry( ComponentDescriptorParameters const ¶meters, - ComponentDescriptorProviderRegistry const &providerRegistry); + ComponentDescriptorProviderRegistry const &providerRegistry, + ContextContainer::Shared contextContainer); /* * This is broken. Please do not use. @@ -85,6 +87,7 @@ class ComponentDescriptorRegistry { ComponentDescriptor::Shared _fallbackComponentDescriptor; ComponentDescriptorParameters parameters_{}; ComponentDescriptorProviderRegistry const &providerRegistry_; + ContextContainer::Shared contextContainer_; }; } // namespace react diff --git a/ReactCommon/react/renderer/mounting/ShadowTree.cpp b/ReactCommon/react/renderer/mounting/ShadowTree.cpp index 2ed6f90cd21..1d3c6fe8dce 100644 --- a/ReactCommon/react/renderer/mounting/ShadowTree.cpp +++ b/ReactCommon/react/renderer/mounting/ShadowTree.cpp @@ -223,7 +223,8 @@ ShadowTree::ShadowTree( SurfaceId surfaceId, LayoutConstraints const &layoutConstraints, LayoutContext const &layoutContext, - ShadowTreeDelegate const &delegate) + ShadowTreeDelegate const &delegate, + ContextContainer const &contextContainer) : surfaceId_(surfaceId), delegate_(delegate) { const auto noopEventEmitter = std::make_shared( nullptr, -1, std::shared_ptr()); @@ -234,7 +235,10 @@ ShadowTree::ShadowTree( EventDispatcher::Shared{}, nullptr, nullptr}); const auto props = std::make_shared( - *RootShadowNode::defaultSharedProps(), layoutConstraints, layoutContext); + PropsParserContext{surfaceId, contextContainer}, + *RootShadowNode::defaultSharedProps(), + layoutConstraints, + layoutContext); auto const fragment = ShadowNodeFamilyFragment{surfaceId, surfaceId, noopEventEmitter}; diff --git a/ReactCommon/react/renderer/mounting/ShadowTree.h b/ReactCommon/react/renderer/mounting/ShadowTree.h index 2a8f1d1fadd..2553fdc3d31 100644 --- a/ReactCommon/react/renderer/mounting/ShadowTree.h +++ b/ReactCommon/react/renderer/mounting/ShadowTree.h @@ -18,6 +18,7 @@ #include #include #include +#include #include "MountingOverrideDelegate.h" namespace facebook { @@ -70,7 +71,8 @@ class ShadowTree final { SurfaceId surfaceId, LayoutConstraints const &layoutConstraints, LayoutContext const &layoutContext, - ShadowTreeDelegate const &delegate); + ShadowTreeDelegate const &delegate, + ContextContainer const &contextContainer); ~ShadowTree(); diff --git a/ReactCommon/react/renderer/runtimescheduler/BUCK b/ReactCommon/react/renderer/runtimescheduler/BUCK index 83037289820..7cdf02a7637 100644 --- a/ReactCommon/react/renderer/runtimescheduler/BUCK +++ b/ReactCommon/react/renderer/runtimescheduler/BUCK @@ -50,6 +50,7 @@ rn_xplat_cxx_library( tests = [":tests"], visibility = ["PUBLIC"], deps = [ + react_native_xplat_target("react/renderer/core:core"), react_native_xplat_target("runtimeexecutor:runtimeexecutor"), react_native_xplat_target("react/renderer/debug:debug"), react_native_xplat_target("better:better"), diff --git a/ReactCommon/react/renderer/runtimescheduler/RuntimeSchedulerBinding.cpp b/ReactCommon/react/renderer/runtimescheduler/RuntimeSchedulerBinding.cpp index 4d5a19f8bb5..05a3d3395a4 100644 --- a/ReactCommon/react/renderer/runtimescheduler/RuntimeSchedulerBinding.cpp +++ b/ReactCommon/react/renderer/runtimescheduler/RuntimeSchedulerBinding.cpp @@ -10,6 +10,7 @@ #include "primitives.h" #include +#include #include #include diff --git a/ReactCommon/react/renderer/runtimescheduler/SchedulerPriority.h b/ReactCommon/react/renderer/runtimescheduler/SchedulerPriority.h index 807865a67f9..4b5a1b7eab2 100644 --- a/ReactCommon/react/renderer/runtimescheduler/SchedulerPriority.h +++ b/ReactCommon/react/renderer/runtimescheduler/SchedulerPriority.h @@ -8,6 +8,7 @@ #pragma once #include +#include #include namespace facebook::react { diff --git a/ReactCommon/react/renderer/scheduler/Scheduler.cpp b/ReactCommon/react/renderer/scheduler/Scheduler.cpp index ca44478f6d8..ef3166c0efa 100644 --- a/ReactCommon/react/renderer/scheduler/Scheduler.cpp +++ b/ReactCommon/react/renderer/scheduler/Scheduler.cpp @@ -36,17 +36,18 @@ Scheduler::Scheduler( UIManagerAnimationDelegate *animationDelegate, SchedulerDelegate *delegate) { runtimeExecutor_ = schedulerToolbox.runtimeExecutor; + contextContainer_ = schedulerToolbox.contextContainer; reactNativeConfig_ = - schedulerToolbox.contextContainer - ->at>("ReactNativeConfig"); + contextContainer_->at>( + "ReactNativeConfig"); // Creating a container for future `EventDispatcher` instance. eventDispatcher_ = std::make_shared>(); auto uiManager = std::make_shared( - runtimeExecutor_, schedulerToolbox.backgroundExecutor); + runtimeExecutor_, schedulerToolbox.backgroundExecutor, contextContainer_); auto eventOwnerBox = std::make_shared(); eventOwnerBox->owner = eventDispatcher_; @@ -90,7 +91,7 @@ Scheduler::Scheduler( EventDispatcher::Shared{eventDispatcher_, &eventDispatcher_->value()}; componentDescriptorRegistry_ = schedulerToolbox.componentRegistryFactory( - eventDispatcher, schedulerToolbox.contextContainer); + eventDispatcher, contextContainer_); uiManager->setDelegate(this); uiManager->setComponentDescriptorRegistry(componentDescriptorRegistry_); @@ -104,8 +105,8 @@ Scheduler::Scheduler( auto componentDescriptorRegistryKey = "ComponentDescriptorRegistry_DO_NOT_USE_PRETTY_PLEASE"; - schedulerToolbox.contextContainer->erase(componentDescriptorRegistryKey); - schedulerToolbox.contextContainer->insert( + contextContainer_->erase(componentDescriptorRegistryKey); + contextContainer_->insert( componentDescriptorRegistryKey, std::weak_ptr( componentDescriptorRegistry_)); @@ -193,6 +194,7 @@ Scheduler::~Scheduler() { void Scheduler::registerSurface( SurfaceHandler const &surfaceHandler) const noexcept { + surfaceHandler.setContextContainer(getContextContainer()); surfaceHandler.setUIManager(uiManager_.get()); } @@ -352,5 +354,9 @@ void Scheduler::uiManagerDidSetIsJSResponder( } } +ContextContainer::Shared Scheduler::getContextContainer() const { + return contextContainer_; +} + } // namespace react } // namespace facebook diff --git a/ReactCommon/react/renderer/scheduler/Scheduler.h b/ReactCommon/react/renderer/scheduler/Scheduler.h index 470890137b9..e604c4adaca 100644 --- a/ReactCommon/react/renderer/scheduler/Scheduler.h +++ b/ReactCommon/react/renderer/scheduler/Scheduler.h @@ -104,6 +104,9 @@ class Scheduler final : public UIManagerDelegate { bool isJSResponder, bool blockNativeResponder) override; +#pragma mark - ContextContainer + ContextContainer::Shared getContextContainer() const; + private: friend class SurfaceHandler; @@ -124,6 +127,12 @@ class Scheduler final : public UIManagerDelegate { */ std::shared_ptr> eventDispatcher_; + /** + * Hold onto ContextContainer. See SchedulerToolbox. + * Must not be nullptr. + */ + ContextContainer::Shared contextContainer_; + /* * Temporary flags. */ diff --git a/ReactCommon/react/renderer/scheduler/SurfaceHandler.cpp b/ReactCommon/react/renderer/scheduler/SurfaceHandler.cpp index a1a134cfacb..9e366968033 100644 --- a/ReactCommon/react/renderer/scheduler/SurfaceHandler.cpp +++ b/ReactCommon/react/renderer/scheduler/SurfaceHandler.cpp @@ -43,11 +43,17 @@ SurfaceHandler &SurfaceHandler::operator=(SurfaceHandler &&other) noexcept { other.link_ = Link{}; other.parameters_ = Parameters{}; + other.parameters_.contextContainer = parameters_.contextContainer; return *this; } #pragma mark - Surface Life-Cycle Management +void SurfaceHandler::setContextContainer( + ContextContainer::Shared contextContainer) const noexcept { + parameters_.contextContainer = contextContainer; +} + Status SurfaceHandler::getStatus() const noexcept { std::shared_lock lock(linkMutex_); return link_.status; @@ -61,6 +67,8 @@ void SurfaceHandler::start() const noexcept { react_native_assert( getLayoutConstraints().layoutDirection != LayoutDirection::Undefined && "layoutDirection must be set."); + react_native_assert( + parameters_.contextContainer && "ContextContainer must be set."); auto parameters = Parameters{}; { @@ -73,7 +81,8 @@ void SurfaceHandler::start() const noexcept { parameters.surfaceId, parameters.layoutConstraints, parameters.layoutContext, - *link_.uiManager); + *link_.uiManager, + *parameters.contextContainer); link_.shadowTree = shadowTree.get(); @@ -194,8 +203,11 @@ Size SurfaceHandler::measure( auto currentRootShadowNode = link_.shadowTree->getCurrentRevision().rootShadowNode; - auto rootShadowNode = - currentRootShadowNode->clone(layoutConstraints, layoutContext); + PropsParserContext propsParserContext{ + parameters_.surfaceId, *parameters_.contextContainer.get()}; + + auto rootShadowNode = currentRootShadowNode->clone( + propsParserContext, layoutConstraints, layoutContext); rootShadowNode->layoutIfNeeded(); return rootShadowNode->getLayoutMetrics().frame.size; } @@ -223,10 +235,14 @@ void SurfaceHandler::constraintLayout( return; } + PropsParserContext propsParserContext{ + parameters_.surfaceId, *parameters_.contextContainer.get()}; + react_native_assert( link_.shadowTree && "`link_.shadowTree` must not be null."); link_.shadowTree->commit([&](RootShadowNode const &oldRootShadowNode) { - return oldRootShadowNode.clone(layoutConstraints, layoutContext); + return oldRootShadowNode.clone( + propsParserContext, layoutConstraints, layoutContext); }); } } diff --git a/ReactCommon/react/renderer/scheduler/SurfaceHandler.h b/ReactCommon/react/renderer/scheduler/SurfaceHandler.h index b564f5ebac1..a606167c370 100644 --- a/ReactCommon/react/renderer/scheduler/SurfaceHandler.h +++ b/ReactCommon/react/renderer/scheduler/SurfaceHandler.h @@ -12,6 +12,7 @@ #include #include #include +#include namespace facebook { namespace react { @@ -73,6 +74,12 @@ class SurfaceHandler final { #pragma mark - Surface Life-Cycle Management + /* + * Must be called before surface is started. + */ + void setContextContainer( + ContextContainer::Shared contextContainer) const noexcept; + /* * Returns a momentum value of the status. */ @@ -171,6 +178,7 @@ class SurfaceHandler final { folly::dynamic props{}; LayoutConstraints layoutConstraints{}; LayoutContext layoutContext{}; + ContextContainer::Shared contextContainer{}; }; /* diff --git a/ReactCommon/react/renderer/scheduler/SurfaceManager.cpp b/ReactCommon/react/renderer/scheduler/SurfaceManager.cpp index 2cd0c6ed27a..a6f8a537f92 100644 --- a/ReactCommon/react/renderer/scheduler/SurfaceManager.cpp +++ b/ReactCommon/react/renderer/scheduler/SurfaceManager.cpp @@ -24,6 +24,7 @@ void SurfaceManager::startSurface( { std::unique_lock lock(mutex_); auto surfaceHandler = SurfaceHandler{moduleName, surfaceId}; + surfaceHandler.setContextContainer(scheduler_.getContextContainer()); registry_.emplace(surfaceId, std::move(surfaceHandler)); } diff --git a/ReactCommon/react/renderer/uimanager/UIManager.cpp b/ReactCommon/react/renderer/uimanager/UIManager.cpp index ea5e77036a0..56bb2bad80a 100644 --- a/ReactCommon/react/renderer/uimanager/UIManager.cpp +++ b/ReactCommon/react/renderer/uimanager/UIManager.cpp @@ -8,6 +8,7 @@ #include "UIManager.h" #include +#include #include #include #include @@ -29,9 +30,11 @@ static std::unique_ptr constructLeakCheckerIfNeeded( UIManager::UIManager( RuntimeExecutor const &runtimeExecutor, - BackgroundExecutor const &backgroundExecutor) + BackgroundExecutor const &backgroundExecutor, + ContextContainer::Shared contextContainer) : runtimeExecutor_(runtimeExecutor), backgroundExecutor_(backgroundExecutor), + contextContainer_(contextContainer), leakChecker_(constructLeakCheckerIfNeeded(runtimeExecutor)) {} UIManager::~UIManager() { @@ -51,10 +54,13 @@ SharedShadowNode UIManager::createNode( auto fallbackDescriptor = componentDescriptorRegistry_->getFallbackComponentDescriptor(); + PropsParserContext propsParserContext{surfaceId, *contextContainer_.get()}; + auto const fragment = ShadowNodeFamilyFragment{tag, surfaceId, nullptr}; auto family = componentDescriptor.createFamily(fragment, std::move(eventTarget)); - auto const props = componentDescriptor.cloneProps(nullptr, rawProps); + auto const props = + componentDescriptor.cloneProps(propsParserContext, nullptr, rawProps); auto const state = componentDescriptor.createInitialState(ShadowNodeFragment{props}, family); @@ -65,7 +71,9 @@ SharedShadowNode UIManager::createNode( fallbackDescriptor->getComponentHandle() == componentDescriptor.getComponentHandle() ? componentDescriptor.cloneProps( - props, RawProps(folly::dynamic::object("name", name))) + propsParserContext, + props, + RawProps(folly::dynamic::object("name", name))) : props, /* .children = */ ShadowNodeFragment::childrenPlaceholder(), /* .state = */ state, @@ -88,13 +96,16 @@ SharedShadowNode UIManager::cloneNode( const RawProps *rawProps) const { SystraceSection s("UIManager::cloneNode"); + PropsParserContext propsParserContext{ + shadowNode->getFamily().getSurfaceId(), *contextContainer_.get()}; + auto &componentDescriptor = shadowNode->getComponentDescriptor(); auto clonedShadowNode = componentDescriptor.cloneShadowNode( *shadowNode, { /* .props = */ rawProps ? componentDescriptor.cloneProps( - shadowNode->getProps(), *rawProps) + propsParserContext, shadowNode->getProps(), *rawProps) : ShadowNodeFragment::propsPlaceholder(), /* .children = */ children, }); diff --git a/ReactCommon/react/renderer/uimanager/UIManager.h b/ReactCommon/react/renderer/uimanager/UIManager.h index ebb8a419bd0..e24434cc9bc 100644 --- a/ReactCommon/react/renderer/uimanager/UIManager.h +++ b/ReactCommon/react/renderer/uimanager/UIManager.h @@ -23,6 +23,7 @@ #include #include #include +#include namespace facebook::react { @@ -33,7 +34,8 @@ class UIManager final : public ShadowTreeDelegate { public: UIManager( RuntimeExecutor const &runtimeExecutor, - BackgroundExecutor const &backgroundExecutor); + BackgroundExecutor const &backgroundExecutor, + ContextContainer::Shared contextContainer); ~UIManager(); @@ -189,6 +191,7 @@ class UIManager final : public ShadowTreeDelegate { RuntimeExecutor const runtimeExecutor_{}; ShadowTreeRegistry shadowTreeRegistry_{}; BackgroundExecutor const backgroundExecutor_{}; + ContextContainer::Shared contextContainer_; mutable better::shared_mutex commitHookMutex_; mutable std::vector commitHooks_;