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
This commit is contained in:
Valentin Shergin 2018-10-09 16:25:08 -07:00 committed by Facebook Github Bot
parent b8947c459f
commit 4ce57cb7c7
7 changed files with 72 additions and 35 deletions

View File

@ -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;

View File

@ -60,11 +60,15 @@ private:
- (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
);
}

View File

@ -108,11 +108,14 @@ using namespace facebook::react;
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 @@ using namespace facebook::react;
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 @@ using namespace facebook::react;
{
[_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

View File

@ -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<std::mutex> lock(mutex_);
auto shadowTree = std::make_unique<ShadowTree>(surfaceId);
auto shadowTree = std::make_unique<ShadowTree>(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);
}
}

View File

@ -37,7 +37,9 @@ public:
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;

View File

@ -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<const ViewEventEmitter>(nullptr, -1, std::shared_ptr<const EventDispatcher>());
const auto props = std::make_shared<const RootProps>(
*RootShadowNode::defaultSharedProps(),
layoutConstraints,
layoutContext
);
const auto noopEventEmitter = std::make_shared<const ViewEventEmitter>(nullptr, rootTag, std::shared_ptr<const EventDispatcher>());
rootShadowNode_ = std::make_shared<RootShadowNode>(
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>(SharedShadowNodeList {}));
}
Tag ShadowTree::getRootTag() const {
return rootTag_;
Tag ShadowTree::getSurfaceId() const {
return surfaceId_;
}
SharedRootShadowNode ShadowTree::getRootShadowNode() const {

View File

@ -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 @@ private:
*/
SharedRootShadowNode getRootShadowNode() const;
const Tag rootTag_;
const SurfaceId surfaceId_;
mutable SharedRootShadowNode rootShadowNode_; // Protected by `commitMutex_`.
ShadowTreeDelegate const *delegate_;
mutable std::recursive_mutex commitMutex_;