From 4ae9ec128d492350658286aad86708a7449d97c5 Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Fri, 31 Jan 2020 21:35:41 -0800 Subject: [PATCH] Fabric: `RootShadowNode::layoutIfNeeded` Summary: Reasons: * The name of the method now better represent what it's doing; * It exposes information about "dirty" state of the node without opening actual `LayoutableShadowNode` protected APIs; * It's a tiny bit faster now because it checks the flag before calling Yoga. Changelog: [Internal] Fabric-specific internal change. Reviewed By: sammy-SC Differential Revision: D19596282 fbshipit-source-id: 3d87d9d5ba20bb8e360683f149b5ebf90beecd65 --- ReactCommon/fabric/components/root/RootShadowNode.cpp | 9 ++++++++- ReactCommon/fabric/components/root/RootShadowNode.h | 9 ++++----- ReactCommon/fabric/mounting/ShadowTree.cpp | 2 +- .../fabric/mounting/tests/ShadowTreeLifeCycleTest.cpp | 2 +- ReactCommon/fabric/uimanager/Scheduler.cpp | 2 +- 5 files changed, 15 insertions(+), 9 deletions(-) diff --git a/ReactCommon/fabric/components/root/RootShadowNode.cpp b/ReactCommon/fabric/components/root/RootShadowNode.cpp index 7226afe601..74a93a2f53 100644 --- a/ReactCommon/fabric/components/root/RootShadowNode.cpp +++ b/ReactCommon/fabric/components/root/RootShadowNode.cpp @@ -15,9 +15,14 @@ namespace react { const char RootComponentName[] = "RootView"; -void RootShadowNode::layout( +bool RootShadowNode::layoutIfNeeded( std::vector *affectedNodes) { SystraceSection s("RootShadowNode::layout"); + + if (getIsLayoutClean()) { + return false; + } + ensureUnsealed(); auto layoutContext = getProps()->layoutContext; @@ -31,6 +36,8 @@ void RootShadowNode::layout( setLayoutMetrics(layoutMetricsFromYogaNode(yogaNode_)); setHasNewLayout(false); } + + return true; } RootShadowNode::Unshared RootShadowNode::clone( diff --git a/ReactCommon/fabric/components/root/RootShadowNode.h b/ReactCommon/fabric/components/root/RootShadowNode.h index 1e2761cc2a..cb45c793cf 100644 --- a/ReactCommon/fabric/components/root/RootShadowNode.h +++ b/ReactCommon/fabric/components/root/RootShadowNode.h @@ -35,9 +35,11 @@ class RootShadowNode final using Unshared = std::shared_ptr; /* - * Layouts the shadow tree. + * Layouts the shadow tree if needed. + * Returns `false` if the three is already laid out. */ - void layout(std::vector *affectedNodes = {}); + bool layoutIfNeeded( + std::vector *affectedNodes = {}); /* * Clones the node with given `layoutConstraints` and `layoutContext`. @@ -58,9 +60,6 @@ class RootShadowNode final ShadowNodeFamily const &shadowNodeFamily, std::function callback) const; - - private: - using YogaLayoutableShadowNode::layout; }; } // namespace react diff --git a/ReactCommon/fabric/mounting/ShadowTree.cpp b/ReactCommon/fabric/mounting/ShadowTree.cpp index 97d741b3ba..0d55bbfbae 100644 --- a/ReactCommon/fabric/mounting/ShadowTree.cpp +++ b/ReactCommon/fabric/mounting/ShadowTree.cpp @@ -169,7 +169,7 @@ bool ShadowTree::tryCommit(ShadowTreeCommitTransaction transaction) const { affectedLayoutableNodes.reserve(1024); telemetry.willLayout(); - newRootShadowNode->layout(&affectedLayoutableNodes); + newRootShadowNode->layoutIfNeeded(&affectedLayoutableNodes); telemetry.didLayout(); newRootShadowNode->sealRecursive(); diff --git a/ReactCommon/fabric/mounting/tests/ShadowTreeLifeCycleTest.cpp b/ReactCommon/fabric/mounting/tests/ShadowTreeLifeCycleTest.cpp index f298b80f75..e263f68b08 100644 --- a/ReactCommon/fabric/mounting/tests/ShadowTreeLifeCycleTest.cpp +++ b/ReactCommon/fabric/mounting/tests/ShadowTreeLifeCycleTest.cpp @@ -92,7 +92,7 @@ static void testShadowNodeTreeLifeCycle( // Laying out the tree. std::const_pointer_cast(nextRootNode) - ->layout(&affectedLayoutableNodes); + ->layoutIfNeeded(&affectedLayoutableNodes); nextRootNode->sealRecursive(); allNodes.push_back(nextRootNode); diff --git a/ReactCommon/fabric/uimanager/Scheduler.cpp b/ReactCommon/fabric/uimanager/Scheduler.cpp index 833cf3ad5b..29ce6dc7bc 100644 --- a/ReactCommon/fabric/uimanager/Scheduler.cpp +++ b/ReactCommon/fabric/uimanager/Scheduler.cpp @@ -234,7 +234,7 @@ Size Scheduler::measureSurface( [&](RootShadowNode::Shared const &oldRootShadowNode) { auto rootShadowNode = oldRootShadowNode->clone(layoutConstraints, layoutContext); - rootShadowNode->layout(); + rootShadowNode->layoutIfNeeded(); size = rootShadowNode->getLayoutMetrics().frame.size; return nullptr; });