From 1068da2ec7a782f6213e035b5a9bae155a5b003e Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Mon, 3 Sep 2018 22:53:26 -0700 Subject: [PATCH] Introducing `LayoutableShadowNode::isLayoutOnly` and (theoretical) view-flattening MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: @public Voalá, this small change actually implements view flattening. Obviously, it does not work right now because there are no `ShadowNode` classes which implement `isLayoutOnly`. Surprisingly, correct implementing of `isLayoutOnly` is quite tricky, we will work on this in coming diffs. Reviewed By: mdvacca Differential Revision: D9403565 fbshipit-source-id: 1f16f912cb5c6841405a1fc3cf36aec28698c11f --- .../core/layout/LayoutableShadowNode.cpp | 4 ++++ .../fabric/core/layout/LayoutableShadowNode.h | 7 ++++++ .../fabric/uimanager/Differentiator.cpp | 24 +++++++++++++++---- 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/ReactCommon/fabric/core/layout/LayoutableShadowNode.cpp b/ReactCommon/fabric/core/layout/LayoutableShadowNode.cpp index aa296769a..786cd4108 100644 --- a/ReactCommon/fabric/core/layout/LayoutableShadowNode.cpp +++ b/ReactCommon/fabric/core/layout/LayoutableShadowNode.cpp @@ -31,6 +31,10 @@ bool LayoutableShadowNode::setLayoutMetrics(LayoutMetrics layoutMetrics) { return true; } +bool LayoutableShadowNode::LayoutableShadowNode::isLayoutOnly() const { + return false; +} + void LayoutableShadowNode::cleanLayout() { isLayoutClean_ = true; } diff --git a/ReactCommon/fabric/core/layout/LayoutableShadowNode.h b/ReactCommon/fabric/core/layout/LayoutableShadowNode.h index febc222cf..5cf49ebae 100644 --- a/ReactCommon/fabric/core/layout/LayoutableShadowNode.h +++ b/ReactCommon/fabric/core/layout/LayoutableShadowNode.h @@ -52,6 +52,13 @@ public: */ virtual LayoutMetrics getLayoutMetrics() const; + /* + * Returns `true` if the node represents only information necessary for + * layout computation and can be safely removed from view hierarchy. + * Default implementation returns `false`. + */ + virtual bool isLayoutOnly() const; + protected: /* diff --git a/ReactCommon/fabric/uimanager/Differentiator.cpp b/ReactCommon/fabric/uimanager/Differentiator.cpp index 43b837850..3e69be60b 100644 --- a/ReactCommon/fabric/uimanager/Differentiator.cpp +++ b/ReactCommon/fabric/uimanager/Differentiator.cpp @@ -11,13 +11,27 @@ namespace facebook { namespace react { +static void sliceChildShadowNodeViewPairsRecursively(ShadowViewNodePairList &pairList, Point layoutOffset, const ShadowNode &shadowNode) { + for (const auto &childShadowNode : shadowNode.getChildren()) { + auto shadowView = ShadowView(*childShadowNode); + + const auto layoutableShadowNode = dynamic_cast(childShadowNode.get()); + if (layoutableShadowNode && layoutableShadowNode->isLayoutOnly()) { + sliceChildShadowNodeViewPairsRecursively( + pairList, + layoutOffset + shadowView.layoutMetrics.frame.origin, + *childShadowNode + ); + } else { + shadowView.layoutMetrics.frame.origin += layoutOffset; + pairList.push_back({shadowView, *childShadowNode}); + } + } +} + static ShadowViewNodePairList sliceChildShadowNodeViewPairs(const ShadowNode &shadowNode) { ShadowViewNodePairList pairList; - - for (const auto &childShadowNode : shadowNode.getChildren()) { - pairList.push_back({ShadowView(*childShadowNode), *childShadowNode}); - } - + sliceChildShadowNodeViewPairsRecursively(pairList, {0, 0}, shadowNode); return pairList; }