amis-rpc-design/node_modules/react-native/ReactCommon/react/renderer/components/view/YogaLayoutableShadowNode.h
2023-10-07 19:42:30 +08:00

207 lines
6.3 KiB
C++

/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#pragma once
#include <memory>
#include <vector>
#include <yoga/YGNode.h>
#include <react/debug/react_native_assert.h>
#include <react/renderer/components/view/YogaStylableProps.h>
#include <react/renderer/core/LayoutableShadowNode.h>
#include <react/renderer/core/Sealable.h>
#include <react/renderer/core/ShadowNode.h>
#include <react/renderer/debug/DebugStringConvertible.h>
namespace facebook {
namespace react {
class YogaLayoutableShadowNode : public LayoutableShadowNode {
using CompactValue = facebook::yoga::detail::CompactValue;
public:
using Shared = std::shared_ptr<YogaLayoutableShadowNode const>;
using ListOfShared =
butter::small_vector<Shared, kShadowNodeChildrenSmallVectorSize>;
static ShadowNodeTraits BaseTraits();
static ShadowNodeTraits::Trait IdentifierTrait();
#pragma mark - Constructors
YogaLayoutableShadowNode(
ShadowNodeFragment const &fragment,
ShadowNodeFamily::Shared const &family,
ShadowNodeTraits traits);
YogaLayoutableShadowNode(
ShadowNode const &sourceShadowNode,
ShadowNodeFragment const &fragment);
#pragma mark - Mutating Methods
/*
* Connects `measureFunc` function of Yoga node with
* `LayoutableShadowNode::measure()` method.
*/
void enableMeasurement();
void appendChild(ShadowNode::Shared const &child) override;
void replaceChild(
ShadowNode const &oldChild,
ShadowNode::Shared const &newChild,
size_t suggestedIndex = -1) override;
void updateYogaChildren();
void updateYogaProps();
/*
* Sets layoutable size of node.
*/
void setSize(Size size) const;
void setPadding(RectangleEdges<Float> padding) const;
/*
* Sets position type of Yoga node (relative, absolute).
*/
void setPositionType(YGPositionType positionType) const;
#pragma mark - LayoutableShadowNode
void cleanLayout() override;
void dirtyLayout() override;
bool getIsLayoutClean() const override;
/*
* Computes layout using Yoga layout engine.
* See `LayoutableShadowNode` for more details.
*/
void layoutTree(
LayoutContext layoutContext,
LayoutConstraints layoutConstraints) override;
void layout(LayoutContext layoutContext) override;
protected:
/*
* Yoga config associated (only) with this particular node.
*/
YGConfig yogaConfig_;
/*
* All Yoga functions only accept non-const arguments, so we have to mark
* Yoga node as `mutable` here to avoid `static_cast`ing the pointer to this
* all the time.
*/
mutable YGNode yogaNode_;
private:
/*
* Goes over `yogaNode_.getChildren()` and in case child's owner is
* equal to address of `yogaNode_`, it sets child's owner address
* to `0xBADC0FFEE0DDF00D`. This is magic constant, the intention
* is to make debugging easier when the address pops up in debugger.
* This prevents ABA problem where child yoga node goes from owned -> unowned
* -> back to owned because its parent is allocated at the same address.
*/
void updateYogaChildrenOwnersIfNeeded();
/*
* Return true if child's yogaNode's owner is this->yogaNode_. Otherwise
* returns false.
*/
bool doesOwn(YogaLayoutableShadowNode const &child) const;
/*
* Appends a Yoga node to the Yoga node associated with this node.
* The method does *not* do anything besides that (no cloning or `owner` field
* adjustment).
*/
void appendYogaChild(YogaLayoutableShadowNode::Shared const &childNode);
/*
* Makes the child node with a given `index` (and Yoga node associated with) a
* valid child node satisfied requirements of the Concurrent Layout approach.
*/
void adoptYogaChild(size_t index);
static YGConfig &initializeYogaConfig(YGConfig &config);
static YGNode *yogaNodeCloneCallbackConnector(
YGNode *oldYogaNode,
YGNode *parentYogaNode,
int childIndex);
static YGSize yogaNodeMeasureCallbackConnector(
YGNode *yogaNode,
float width,
YGMeasureMode widthMode,
float height,
YGMeasureMode heightMode);
static YogaLayoutableShadowNode &shadowNodeFromContext(YGNode *yogaNode);
#pragma mark - RTL Legacy Autoflip
/*
* Walks though shadow node hierarchy and reassign following values:
* - (left|right) → (start|end)
* - margin(Left|Right) → margin(Start|End)
* - padding(Left|Right) → padding(Start|End)
* - borderTop(Left|Right)Radius → borderTop(Start|End)Radius
* - borderBottom(Left|Right)Radius → borderBottom(Start|End)Radius
* - border(Left|Right)Width → border(Start|End)Width
* - border(Left|Right)Color → border(Start|End)Color
* This is neccesarry to be backwards compatible with old renderer, it swaps
* the values as well in https://fburl.com/diffusion/kl7bjr3h
*/
static void swapLeftAndRightInTree(
YogaLayoutableShadowNode const &shadowNode);
/*
* In shadow node passed as argument, reassigns following values
* - borderTop(Left|Right)Radius → borderTop(Start|End)Radius
* - borderBottom(Left|Right)Radius → borderBottom(Start|End)Radius
* - border(Left|Right)Width → border(Start|End)Width
* - border(Left|Right)Color → border(Start|End)Color
*/
static void swapLeftAndRightInViewProps(
YogaLayoutableShadowNode const &shadowNode);
/*
* In yoga node passed as argument, reassigns following values
* - (left|right) → (start|end)
* - margin(Left|Right) → margin(Start|End)
* - padding(Left|Right) → padding(Start|End)
*/
static void swapLeftAndRightInYogaStyleProps(
YogaLayoutableShadowNode const &shadowNode);
/*
* Combine a base YGStyle with aliased properties which should be flattened
* into it. E.g. reconciling "marginInlineStart" and "marginStart".
*/
static YGStyle applyAliasedProps(
const YGStyle &baseStyle,
const YogaStylableProps &props);
#pragma mark - Consistency Ensuring Helpers
void ensureConsistency() const;
void ensureYogaChildrenAlignment() const;
void ensureYogaChildrenOwnersConsistency() const;
void ensureYogaChildrenLookFine() const;
#pragma mark - Private member variables
/*
* List of children which derive from YogaLayoutableShadowNode
*/
ListOfShared yogaLayoutableChildren_;
};
} // namespace react
} // namespace facebook