mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Fabric: Devirtualizing LayoutableShadowNode::cloneAndReplaceChild
Summary: D19963353 mentioned the infrastructure that re-routes methods calls related to adding and cloning children between YogaLayoutableShadowNode and ShadowNode. `cloneAndReplaceChild` is exactly this. It was implemented as a virtual method that is called from `ConcreteViewShadowNode`. The whole process requires building a list of children of some class and passing that as a list of pointers. Now we don't need it all that because we can call directly and statically. That change will allow us to simplify that infra even more in the future diffs. Changelog: [Internal] Fabric-specific internal change. Reviewed By: sammy-SC Differential Revision: D20052022 fbshipit-source-id: ddf341c112edd8a2f79eaf74465a9a360a168541
This commit is contained in:
committed by
Facebook Github Bot
parent
1090b05e61
commit
7953c3e854
@@ -89,32 +89,6 @@ class ConcreteViewShadowNode : public ConcreteShadowNode<
|
||||
return traits;
|
||||
}
|
||||
|
||||
void appendChild(const ShadowNode::Shared &child) {
|
||||
BaseShadowNode::ensureUnsealed();
|
||||
|
||||
ShadowNode::appendChild(child);
|
||||
|
||||
auto nonConstChild = const_cast<ShadowNode *>(child.get());
|
||||
auto yogaLayoutableChild =
|
||||
dynamic_cast<YogaLayoutableShadowNode *>(nonConstChild);
|
||||
if (yogaLayoutableChild) {
|
||||
YogaLayoutableShadowNode::appendChild(yogaLayoutableChild);
|
||||
}
|
||||
}
|
||||
|
||||
LayoutableShadowNode *cloneAndReplaceChild(
|
||||
LayoutableShadowNode *child,
|
||||
int suggestedIndex = -1) override {
|
||||
Sealable::ensureUnsealed();
|
||||
auto childShadowNode = static_cast<const ConcreteViewShadowNode *>(child);
|
||||
auto clonedChildShadowNode =
|
||||
std::static_pointer_cast<ConcreteViewShadowNode>(
|
||||
childShadowNode->clone({}));
|
||||
ShadowNode::replaceChild(
|
||||
*childShadowNode, clonedChildShadowNode, suggestedIndex);
|
||||
return clonedChildShadowNode.get();
|
||||
}
|
||||
|
||||
Transform getTransform() const override {
|
||||
return BaseShadowNode::getConcreteProps().transform;
|
||||
}
|
||||
|
||||
@@ -78,28 +78,45 @@ void YogaLayoutableShadowNode::enableMeasurement() {
|
||||
YogaLayoutableShadowNode::yogaNodeMeasureCallbackConnector);
|
||||
}
|
||||
|
||||
void YogaLayoutableShadowNode::appendChild(YogaLayoutableShadowNode *child) {
|
||||
void YogaLayoutableShadowNode::appendChild(ShadowNode::Shared const &child) {
|
||||
ensureUnsealed();
|
||||
|
||||
LayoutableShadowNode::appendChild(child);
|
||||
|
||||
auto yogaLayoutableChild =
|
||||
traitCast<YogaLayoutableShadowNode const *>(child.get());
|
||||
if (yogaLayoutableChild) {
|
||||
appendChildYogaNode(
|
||||
*const_cast<YogaLayoutableShadowNode *>(yogaLayoutableChild));
|
||||
}
|
||||
}
|
||||
|
||||
void YogaLayoutableShadowNode::appendChildYogaNode(
|
||||
YogaLayoutableShadowNode &child) {
|
||||
ensureUnsealed();
|
||||
|
||||
if (getTraits().check(ShadowNodeTraits::Trait::LeafYogaNode)) {
|
||||
// This node is a declared leaf, therefore we must not add the Yoga node as
|
||||
// a child.
|
||||
return;
|
||||
}
|
||||
|
||||
ensureUnsealed();
|
||||
|
||||
yogaNode_.setDirty(true);
|
||||
|
||||
auto yogaNodeRawPtr = &yogaNode_;
|
||||
auto childYogaNodeRawPtr = &child->yogaNode_;
|
||||
auto childYogaNodeRawPtr = &child.yogaNode_;
|
||||
auto childNodePtr = &child;
|
||||
|
||||
if (childYogaNodeRawPtr->getOwner() != nullptr) {
|
||||
child = static_cast<YogaLayoutableShadowNode *>(
|
||||
cloneAndReplaceChild(child, yogaNode_.getChildren().size()));
|
||||
childYogaNodeRawPtr = &child->yogaNode_;
|
||||
childNodePtr =
|
||||
&cloneAndReplaceChild(*childNodePtr, yogaNode_.getChildren().size());
|
||||
childYogaNodeRawPtr = &childNodePtr->yogaNode_;
|
||||
}
|
||||
|
||||
// Inserted node must have a clear owner (must not be shared).
|
||||
assert(childYogaNodeRawPtr->getOwner() == nullptr);
|
||||
|
||||
child->ensureUnsealed();
|
||||
childNodePtr->ensureUnsealed();
|
||||
childYogaNodeRawPtr->setOwner(yogaNodeRawPtr);
|
||||
|
||||
yogaNodeRawPtr->insertChild(
|
||||
@@ -125,7 +142,7 @@ void YogaLayoutableShadowNode::setChildren(
|
||||
|
||||
auto i = int{0};
|
||||
for (auto const &child : children) {
|
||||
appendChild(child);
|
||||
appendChildYogaNode(*child);
|
||||
|
||||
isClean = isClean && !child->yogaNode_.isDirty() &&
|
||||
child->yogaNode_.getStyle() == oldChildren[i++]->getStyle();
|
||||
@@ -246,6 +263,15 @@ YogaLayoutableShadowNode::getLayoutableChildNodes() const {
|
||||
return yogaLayoutableChildNodes;
|
||||
}
|
||||
|
||||
YogaLayoutableShadowNode &YogaLayoutableShadowNode::cloneAndReplaceChild(
|
||||
YogaLayoutableShadowNode &child,
|
||||
int suggestedIndex) {
|
||||
auto clonedChildShadowNode = child.clone({});
|
||||
replaceChild(child, clonedChildShadowNode, suggestedIndex);
|
||||
|
||||
return static_cast<YogaLayoutableShadowNode &>(*clonedChildShadowNode);
|
||||
}
|
||||
|
||||
#pragma mark - Yoga Connectors
|
||||
|
||||
YGNode *YogaLayoutableShadowNode::yogaNodeCloneCallbackConnector(
|
||||
@@ -260,8 +286,7 @@ YGNode *YogaLayoutableShadowNode::yogaNodeCloneCallbackConnector(
|
||||
static_cast<YogaLayoutableShadowNode *>(parentYogaNode->getContext());
|
||||
auto oldNode =
|
||||
static_cast<YogaLayoutableShadowNode *>(oldYogaNode->getContext());
|
||||
auto clonedNode = static_cast<YogaLayoutableShadowNode *>(
|
||||
parentNode->cloneAndReplaceChild(oldNode, childIndex));
|
||||
auto clonedNode = &parentNode->cloneAndReplaceChild(*oldNode, childIndex);
|
||||
return &clonedNode->yogaNode_;
|
||||
}
|
||||
|
||||
|
||||
@@ -47,12 +47,7 @@ class YogaLayoutableShadowNode : public LayoutableShadowNode {
|
||||
*/
|
||||
void enableMeasurement();
|
||||
|
||||
/*
|
||||
* Appends `child`'s Yoga node to the own Yoga node.
|
||||
* Complements `ShadowNode::appendChild(...)` functionality from Yoga
|
||||
* perspective.
|
||||
*/
|
||||
void appendChild(YogaLayoutableShadowNode *child);
|
||||
void appendChild(ShadowNode::Shared const &child);
|
||||
|
||||
/*
|
||||
* Sets Yoga children based on collection of `YogaLayoutableShadowNode`
|
||||
@@ -111,6 +106,17 @@ class YogaLayoutableShadowNode : public LayoutableShadowNode {
|
||||
mutable YGNode yogaNode_;
|
||||
|
||||
private:
|
||||
/*
|
||||
* Appends `child`'s Yoga node to the own Yoga node.
|
||||
* Complements `ShadowNode::appendChild(...)` functionality from Yoga
|
||||
* perspective.
|
||||
*/
|
||||
void appendChildYogaNode(YogaLayoutableShadowNode &child);
|
||||
|
||||
YogaLayoutableShadowNode &cloneAndReplaceChild(
|
||||
YogaLayoutableShadowNode &child,
|
||||
int suggestedIndex);
|
||||
|
||||
static YGConfig &initializeYogaConfig(YGConfig &config);
|
||||
static YGNode *yogaNodeCloneCallbackConnector(
|
||||
YGNode *oldYogaNode,
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <better/small_vector.h>
|
||||
#include <react/core/LayoutMetrics.h>
|
||||
#include <react/core/ShadowNode.h>
|
||||
#include <react/core/ShadowNodeFragment.h>
|
||||
#include <react/debug/DebugStringConvertible.h>
|
||||
#include <react/graphics/Geometry.h>
|
||||
#include <react/graphics/Transform.h>
|
||||
@@ -136,14 +137,6 @@ class LayoutableShadowNode : public ShadowNode {
|
||||
virtual LayoutableShadowNode::UnsharedList getLayoutableChildNodes()
|
||||
const = 0;
|
||||
|
||||
/*
|
||||
* In case layout algorithm needs to mutate this (probably sealed) node,
|
||||
* it has to clone and replace it in the hierarchy before to do so.
|
||||
*/
|
||||
virtual LayoutableShadowNode *cloneAndReplaceChild(
|
||||
LayoutableShadowNode *child,
|
||||
int suggestedIndex = -1) = 0;
|
||||
|
||||
/*
|
||||
* Sets layout metrics for the shadow node.
|
||||
* Returns true if the metrics are different from previous ones.
|
||||
|
||||
Reference in New Issue
Block a user