From 4ce57cb7c7b61b2f59b6fbb3b428971ab3549d72 Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Tue, 9 Oct 2018 16:25:08 -0700 Subject: [PATCH] Fabric: Passing size constraints as part of starting Surface Summary: Size constraints are essential part of the running Surface, decoupling them from starting process means that we will have to perform additional commit later. This and previous couple diffs fix a problem with initial zero size of the surface and following visible "jumpy" relayout. Reviewed By: sahrens Differential Revision: D10174280 fbshipit-source-id: 0ec48692cb814fd46cc3a1d044c5eb8ab9ecb031 --- React/Fabric/RCTScheduler.h | 4 +- React/Fabric/RCTScheduler.mm | 6 ++- React/Fabric/RCTSurfacePresenter.mm | 43 ++++++++++++++------- ReactCommon/fabric/uimanager/Scheduler.cpp | 8 ++-- ReactCommon/fabric/uimanager/Scheduler.h | 4 +- ReactCommon/fabric/uimanager/ShadowTree.cpp | 27 +++++++++---- ReactCommon/fabric/uimanager/ShadowTree.h | 15 ++++--- 7 files changed, 72 insertions(+), 35 deletions(-) diff --git a/React/Fabric/RCTScheduler.h b/React/Fabric/RCTScheduler.h index d747032a1349fd..e66d0ce9b2a362 100644 --- a/React/Fabric/RCTScheduler.h +++ b/React/Fabric/RCTScheduler.h @@ -41,7 +41,9 @@ NS_ASSUME_NONNULL_BEGIN - (void)startSurfaceWithSurfaceId:(facebook::react::SurfaceId)surfaceId moduleName:(NSString *)moduleName - initailProps:(NSDictionary *)initialProps; + initailProps:(NSDictionary *)initialProps + layoutConstraints:(facebook::react::LayoutConstraints)layoutConstraints + layoutContext:(facebook::react::LayoutContext)layoutContext; - (void)stopSurfaceWithSurfaceId:(facebook::react::SurfaceId)surfaceId; diff --git a/React/Fabric/RCTScheduler.mm b/React/Fabric/RCTScheduler.mm index 7a1822dd94a03f..d9ccfe8efbaa81 100644 --- a/React/Fabric/RCTScheduler.mm +++ b/React/Fabric/RCTScheduler.mm @@ -60,11 +60,15 @@ - (void)dealloc - (void)startSurfaceWithSurfaceId:(SurfaceId)surfaceId moduleName:(NSString *)moduleName initailProps:(NSDictionary *)initialProps + layoutConstraints:(LayoutConstraints)layoutConstraints + layoutContext:(LayoutContext)layoutContext; { _scheduler->startSurface( surfaceId, RCTStringFromNSString(moduleName), - convertIdToFollyDynamic(initialProps) + convertIdToFollyDynamic(initialProps), + layoutConstraints, + layoutContext ); } diff --git a/React/Fabric/RCTSurfacePresenter.mm b/React/Fabric/RCTSurfacePresenter.mm index bf3344025e3b93..ea6637de8bcac5 100644 --- a/React/Fabric/RCTSurfacePresenter.mm +++ b/React/Fabric/RCTSurfacePresenter.mm @@ -108,11 +108,14 @@ - (CGSize)sizeThatFitsMinimumSize:(CGSize)minimumSize maximumSize:(CGSize)maximumSize surface:(RCTFabricSurface *)surface { - LayoutContext layoutContext; - layoutContext.pointScaleFactor = RCTScreenScale(); - LayoutConstraints layoutConstraints = {}; - layoutConstraints.minimumSize = RCTSizeFromCGSize(minimumSize); - layoutConstraints.maximumSize = RCTSizeFromCGSize(maximumSize); + LayoutContext layoutContext = { + .pointScaleFactor = RCTScreenScale() + }; + + LayoutConstraints layoutConstraints = { + .minimumSize = RCTSizeFromCGSize(minimumSize), + .maximumSize = RCTSizeFromCGSize(maximumSize) + }; return [self._scheduler measureSurfaceWithLayoutConstraints:layoutConstraints layoutContext:layoutContext @@ -123,11 +126,14 @@ - (void)setMinimumSize:(CGSize)minimumSize maximumSize:(CGSize)maximumSize surface:(RCTFabricSurface *)surface { - LayoutContext layoutContext; - layoutContext.pointScaleFactor = RCTScreenScale(); - LayoutConstraints layoutConstraints = {}; - layoutConstraints.minimumSize = RCTSizeFromCGSize(minimumSize); - layoutConstraints.maximumSize = RCTSizeFromCGSize(maximumSize); + LayoutContext layoutContext = { + .pointScaleFactor = RCTScreenScale() + }; + + LayoutConstraints layoutConstraints = { + .minimumSize = RCTSizeFromCGSize(minimumSize), + .maximumSize = RCTSizeFromCGSize(maximumSize) + }; [self._scheduler constraintSurfaceLayoutWithLayoutConstraints:layoutConstraints layoutContext:layoutContext @@ -174,13 +180,20 @@ - (void)_startSurface:(RCTFabricSurface *)surface { [_mountingManager.componentViewRegistry dequeueComponentViewWithName:@"Root" tag:surface.rootTag]; + LayoutContext layoutContext = { + .pointScaleFactor = RCTScreenScale() + }; + + LayoutConstraints layoutConstraints = { + .minimumSize = RCTSizeFromCGSize(surface.minimumSize), + .maximumSize = RCTSizeFromCGSize(surface.maximumSize) + }; + [self._scheduler startSurfaceWithSurfaceId:surface.rootTag moduleName:surface.moduleName - initailProps:surface.properties]; - - [self setMinimumSize:surface.minimumSize - maximumSize:surface.maximumSize - surface:surface]; + initailProps:surface.properties + layoutConstraints:layoutConstraints + layoutContext:layoutContext]; } - (void)_stopSurface:(RCTFabricSurface *)surface diff --git a/ReactCommon/fabric/uimanager/Scheduler.cpp b/ReactCommon/fabric/uimanager/Scheduler.cpp index a09a40a66aed10..4cbada1e4d0984 100644 --- a/ReactCommon/fabric/uimanager/Scheduler.cpp +++ b/ReactCommon/fabric/uimanager/Scheduler.cpp @@ -54,11 +54,13 @@ Scheduler::~Scheduler() { void Scheduler::startSurface( SurfaceId surfaceId, const std::string &moduleName, - const folly::dynamic &initialProps + const folly::dynamic &initialProps, + const LayoutConstraints &layoutConstraints, + const LayoutContext &layoutContext ) const { std::lock_guard lock(mutex_); - auto shadowTree = std::make_unique(surfaceId); + auto shadowTree = std::make_unique(surfaceId, layoutConstraints, layoutContext); shadowTree->setDelegate(this); shadowTreeRegistry_.emplace(surfaceId, std::move(shadowTree)); @@ -121,7 +123,7 @@ SchedulerDelegate *Scheduler::getDelegate() const { void Scheduler::shadowTreeDidCommit(const ShadowTree &shadowTree, const ShadowViewMutationList &mutations) const { if (delegate_) { - delegate_->schedulerDidFinishTransaction(shadowTree.getRootTag(), mutations); + delegate_->schedulerDidFinishTransaction(shadowTree.getSurfaceId(), mutations); } } diff --git a/ReactCommon/fabric/uimanager/Scheduler.h b/ReactCommon/fabric/uimanager/Scheduler.h index bed761c1f3a90c..0fa004369caf4d 100644 --- a/ReactCommon/fabric/uimanager/Scheduler.h +++ b/ReactCommon/fabric/uimanager/Scheduler.h @@ -37,7 +37,9 @@ class Scheduler final: void startSurface( SurfaceId surfaceId, const std::string &moduleName, - const folly::dynamic &initialProps + const folly::dynamic &initialProps, + const LayoutConstraints &layoutConstraints = {}, + const LayoutContext &layoutContext = {} ) const; void stopSurface(SurfaceId surfaceId) const; diff --git a/ReactCommon/fabric/uimanager/ShadowTree.cpp b/ReactCommon/fabric/uimanager/ShadowTree.cpp index 872f908066eac6..8717ea8fb1f313 100644 --- a/ReactCommon/fabric/uimanager/ShadowTree.cpp +++ b/ReactCommon/fabric/uimanager/ShadowTree.cpp @@ -15,15 +15,26 @@ namespace facebook { namespace react { -ShadowTree::ShadowTree(Tag rootTag): - rootTag_(rootTag) { +ShadowTree::ShadowTree( + SurfaceId surfaceId, + const LayoutConstraints &layoutConstraints, + const LayoutContext &layoutContext +): + surfaceId_(surfaceId) { + + const auto noopEventEmitter = std::make_shared(nullptr, -1, std::shared_ptr()); + + const auto props = std::make_shared( + *RootShadowNode::defaultSharedProps(), + layoutConstraints, + layoutContext + ); - const auto noopEventEmitter = std::make_shared(nullptr, rootTag, std::shared_ptr()); rootShadowNode_ = std::make_shared( ShadowNodeFragment { - .tag = rootTag, - .rootTag = rootTag, - .props = RootShadowNode::defaultSharedProps(), + .tag = surfaceId, + .rootTag = surfaceId, + .props = props, .eventEmitter = noopEventEmitter, }, nullptr @@ -34,8 +45,8 @@ ShadowTree::~ShadowTree() { complete(std::make_shared(SharedShadowNodeList {})); } -Tag ShadowTree::getRootTag() const { - return rootTag_; +Tag ShadowTree::getSurfaceId() const { + return surfaceId_; } SharedRootShadowNode ShadowTree::getRootShadowNode() const { diff --git a/ReactCommon/fabric/uimanager/ShadowTree.h b/ReactCommon/fabric/uimanager/ShadowTree.h index a0f6bee185eefb..eedaabaeea584e 100644 --- a/ReactCommon/fabric/uimanager/ShadowTree.h +++ b/ReactCommon/fabric/uimanager/ShadowTree.h @@ -26,17 +26,20 @@ class ShadowTree final { public: /* - * Creates a new shadow tree instance with given `rootTag`. + * Creates a new shadow tree instance. */ - ShadowTree(Tag rootTag); + ShadowTree( + SurfaceId surfaceId, + const LayoutConstraints &layoutConstraints, + const LayoutContext &layoutContext + ); ~ShadowTree(); /* - * Returns the rootTag associated with the shadow tree (the tag of the - * root shadow node). + * Returns the `SurfaceId` associated with the shadow tree. */ - Tag getRootTag() const; + SurfaceId getSurfaceId() const; /* * Synchronously runs `function` when `commitMutex_` is acquired. @@ -100,7 +103,7 @@ class ShadowTree final { */ SharedRootShadowNode getRootShadowNode() const; - const Tag rootTag_; + const SurfaceId surfaceId_; mutable SharedRootShadowNode rootShadowNode_; // Protected by `commitMutex_`. ShadowTreeDelegate const *delegate_; mutable std::recursive_mutex commitMutex_;