Fabric: YogaLayoutableShadowNode::isLeaf_ and using that in ParagraphShadowNode

Summary:
As soon as we have traits infra, it's pretty straight-forward to implement this kinda flag. Without the traits, it's challenging to build that in a performant and elegant way. The challenges of the dynamic_cast-involved approach are:
 * How to check for that feature in YogaLayoutableShadowNode?
 * Even if we use `dynamic_cast`, to which class to cast?
 * We also need to do that in constructor... and dynamic_cast-like checks for `this` don't work in constructors (C++ design limitation).
 * How to scale that if we have more classes like Paragraph (and we will have it for sure)?
 * Performance.
 * Relying on RTTI.

Changelog: [Internal] Fabric-specific internal change.

Reviewed By: sammy-SC

Differential Revision: D18525347

fbshipit-source-id: b1915f43ff3fe4364ab6345fb9d1becc591b5a35
This commit is contained in:
Valentin Shergin 2019-11-15 19:47:51 -08:00 коммит произвёл Facebook Github Bot
Родитель 059142935a
Коммит 3426f1f537
4 изменённых файлов: 34 добавлений и 9 удалений

Просмотреть файл

@ -39,6 +39,12 @@ class ParagraphShadowNode : public ConcreteViewShadowNode<
public: public:
using ConcreteViewShadowNode::ConcreteViewShadowNode; using ConcreteViewShadowNode::ConcreteViewShadowNode;
static ShadowNodeTraits BaseTraits() {
auto traits = ConcreteViewShadowNode::BaseTraits();
traits.set(ShadowNodeTraits::Trait::LeafYogaNode);
return traits;
}
/* /*
* Returns a `AttributedString` which represents text content of the node. * Returns a `AttributedString` which represents text content of the node.
*/ */

Просмотреть файл

@ -58,7 +58,8 @@ class ConcreteViewShadowNode : public ConcreteShadowNode<
ComponentDescriptor const &componentDescriptor, ComponentDescriptor const &componentDescriptor,
ShadowNodeTraits traits) ShadowNodeTraits traits)
: BaseShadowNode(fragment, componentDescriptor, traits), : BaseShadowNode(fragment, componentDescriptor, traits),
YogaLayoutableShadowNode() { YogaLayoutableShadowNode(
traits.check(ShadowNodeTraits::Trait::LeafYogaNode)) {
YogaLayoutableShadowNode::setProps( YogaLayoutableShadowNode::setProps(
*std::static_pointer_cast<const ConcreteViewProps>(fragment.props)); *std::static_pointer_cast<const ConcreteViewProps>(fragment.props));
YogaLayoutableShadowNode::setChildren( YogaLayoutableShadowNode::setChildren(

Просмотреть файл

@ -21,18 +21,21 @@
namespace facebook { namespace facebook {
namespace react { namespace react {
YogaLayoutableShadowNode::YogaLayoutableShadowNode() YogaLayoutableShadowNode::YogaLayoutableShadowNode(bool isLeaf)
: yogaConfig_(nullptr), yogaNode_(&initializeYogaConfig(yogaConfig_)) { : yogaConfig_(nullptr),
yogaNode_(&initializeYogaConfig(yogaConfig_)),
isLeaf_(isLeaf) {
yogaNode_.setContext(this); yogaNode_.setContext(this);
} }
YogaLayoutableShadowNode::YogaLayoutableShadowNode( YogaLayoutableShadowNode::YogaLayoutableShadowNode(
const YogaLayoutableShadowNode &layoutableShadowNode) YogaLayoutableShadowNode const &layoutableShadowNode)
: LayoutableShadowNode(layoutableShadowNode), : LayoutableShadowNode(layoutableShadowNode),
yogaConfig_(nullptr), yogaConfig_(nullptr),
yogaNode_( yogaNode_(
layoutableShadowNode.yogaNode_, layoutableShadowNode.yogaNode_,
&initializeYogaConfig(yogaConfig_)) { &initializeYogaConfig(yogaConfig_)),
isLeaf_(layoutableShadowNode.isLeaf_) {
yogaNode_.setContext(this); yogaNode_.setContext(this);
yogaNode_.setOwner(nullptr); yogaNode_.setOwner(nullptr);
@ -70,6 +73,10 @@ void YogaLayoutableShadowNode::enableMeasurement() {
} }
void YogaLayoutableShadowNode::appendChild(YogaLayoutableShadowNode *child) { void YogaLayoutableShadowNode::appendChild(YogaLayoutableShadowNode *child) {
if (isLeaf_) {
return;
}
ensureUnsealed(); ensureUnsealed();
yogaNode_.setDirty(true); yogaNode_.setDirty(true);
@ -95,6 +102,10 @@ void YogaLayoutableShadowNode::appendChild(YogaLayoutableShadowNode *child) {
void YogaLayoutableShadowNode::setChildren( void YogaLayoutableShadowNode::setChildren(
YogaLayoutableShadowNode::UnsharedList children) { YogaLayoutableShadowNode::UnsharedList children) {
if (isLeaf_) {
return;
}
ensureUnsealed(); ensureUnsealed();
// Optimization: // Optimization:

Просмотреть файл

@ -32,10 +32,10 @@ class YogaLayoutableShadowNode : public LayoutableShadowNode,
#pragma mark - Constructors #pragma mark - Constructors
YogaLayoutableShadowNode(); YogaLayoutableShadowNode(bool isLeaf);
YogaLayoutableShadowNode( YogaLayoutableShadowNode(
const YogaLayoutableShadowNode &layoutableShadowNode); YogaLayoutableShadowNode const &layoutableShadowNode);
#pragma mark - Mutating Methods #pragma mark - Mutating Methods
@ -64,14 +64,14 @@ class YogaLayoutableShadowNode : public LayoutableShadowNode,
*/ */
void setProps(const YogaStylableProps &props); void setProps(const YogaStylableProps &props);
/** /*
* Sets layoutable size of node. * Sets layoutable size of node.
*/ */
void setSize(Size size) const; void setSize(Size size) const;
void setPadding(RectangleEdges<Float> padding) const; void setPadding(RectangleEdges<Float> padding) const;
/** /*
* Sets position type of Yoga node (relative, absolute). * Sets position type of Yoga node (relative, absolute).
*/ */
void setPositionType(YGPositionType positionType) const; void setPositionType(YGPositionType positionType) const;
@ -108,6 +108,13 @@ class YogaLayoutableShadowNode : public LayoutableShadowNode,
*/ */
mutable YGNode yogaNode_; mutable YGNode yogaNode_;
/*
* Forces associated YGNode to be a leaf.
* Adding a child `ShadowNode` will not add `YGNode` associated with it as a
* child to the stored `YGNode`.
*/
bool const isLeaf_;
private: private:
static YGConfig &initializeYogaConfig(YGConfig &config); static YGConfig &initializeYogaConfig(YGConfig &config);
static YGNode *yogaNodeCloneCallbackConnector( static YGNode *yogaNodeCloneCallbackConnector(