Skip to content

Commit

Permalink
C++ Cleanup 1/N: Reorganize YGStyle
Browse files Browse the repository at this point in the history
Summary:
## This diff

This diff adds a `style` directory for code related to storing and manipulating styles. `YGStyle`, which is not a public API, is renamed to `yoga::Style` and moved into this folder, alongside `CompactValue`. We will eventually add `ValuePool` alongside this for the next generation style representation.

## This stack

The organization of the C++ internals of Yoga are in need of attention.
1. Some of the C++ internals are namespaced, but others not.
2. Some of the namespaces include `detail`, but are meant to be used outside of the translation unit (FB Clang Tidy rules warn on any usage of these)
2. Most of the files are in a flat hierarchy, except for event tracing in its own folder
3. Some files and functions begin with YG, others don’t
4. Some functions are uppercase, others are not
5. Almost all of the interesting logic is in Yoga.cpp, and the file is too large to reason about
6. There are multiple grab bag files where folks put random functions they need in (Utils, BitUtils, Yoga-Internal.h)
7. There is no clear indication from file structure or type naming what is private vs not
8. Handles like `YGNodeRef` and `YGConfigRef` can be used to access internals just by importing headers

This stack does some much needed spring cleaning:
1. All non-public headers and C++ implementation details are in separate folders from the root level `yoga`. This will give us room to split up logic and add more files without too large a flat hierarchy
3. All private C++ internals are under the `facebook::yoga` namespace. Details namespaces are only ever used within the same header, as they are intended
4. Utils files are split
5. Most C++ internals drop the YG prefix
6. Most C++ internal function names are all lower camel case
7. We start to split up Yoga.cpp
8. Every header beginning with YG or at the top-level directory is public and C only, with the exception of Yoga-Internal.h which has non-public functions for bindings
9. It is not possible to use private APIs without static casting handles to internal classes

This will give us more leeway to continue splitting monolithic files, and consistent guidelines for style in new files as well.

These changes should not be breaking to any project using only public Yoga headers. This includes every usage of Yoga in fbsource except for RN Fabric which is currently tied to internals. This refactor should make that boundary clearer.

Changelog: [Internal]

Differential Revision: D48710084

fbshipit-source-id: 1fc5424ab697c58ab6714ad75ddc35f4aef8d8e8
  • Loading branch information
NickGerleman authored and facebook-github-bot committed Aug 26, 2023
1 parent 61861d2 commit 83d1d4a
Show file tree
Hide file tree
Showing 22 changed files with 198 additions and 203 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ MapBuffer convertBorderRadii(CascadedBorderRadii const &radii) {
return builder.build();
}

MapBuffer convertBorderWidths(YGStyle::Edges const &border) {
MapBuffer convertBorderWidths(yoga::Style::Edges const &border) {
MapBufferBuilder builder(7);
putOptionalFloat(
builder, EDGE_TOP, optionalFloatFromYogaValue(border[YGEdgeTop]));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@

#include <fbjni/fbjni.h>

#include <yoga/CompactValue.h>
#include <yoga/YGEnums.h>
#include <yoga/YGValue.h>
#include <yoga/style/CompactValue.h>

#include <react/renderer/core/ConcreteComponentDescriptor.h>

Expand All @@ -38,7 +38,7 @@ class AndroidTextInputComponentDescriptor final
ShadowNodeFamily::Shared const &family) const override {
int surfaceId = family->getSurfaceId();

YGStyle::Edges theme;
yoga::Style::Edges theme;
// TODO: figure out RTL/start/end/left/right stuff here
if (surfaceIdToThemePaddingMap_.find(surfaceId) !=
surfaceIdToThemePaddingMap_.end()) {
Expand Down Expand Up @@ -97,7 +97,7 @@ class AndroidTextInputComponentDescriptor final
int surfaceId = textInputShadowNode.getSurfaceId();
if (surfaceIdToThemePaddingMap_.find(surfaceId) !=
surfaceIdToThemePaddingMap_.end()) {
YGStyle::Edges theme = surfaceIdToThemePaddingMap_[surfaceId];
yoga::Style::Edges theme = surfaceIdToThemePaddingMap_[surfaceId];

auto &textInputProps = textInputShadowNode.getConcreteProps();

Expand All @@ -106,7 +106,7 @@ class AndroidTextInputComponentDescriptor final
// TODO: T62959168 account for RTL and paddingLeft when setting default
// paddingStart, and vice-versa with paddingRight/paddingEnd.
// For now this assumes no RTL.
YGStyle::Edges result = textInputProps.yogaStyle.padding();
yoga::Style::Edges result = textInputProps.yogaStyle.padding();
bool changedPadding = false;
if (!textInputProps.hasPadding && !textInputProps.hasPaddingStart &&
!textInputProps.hasPaddingLeft &&
Expand Down Expand Up @@ -171,7 +171,7 @@ class AndroidTextInputComponentDescriptor final
"com/facebook/react/fabric/FabricUIManager";

SharedTextLayoutManager textLayoutManager_;
mutable butter::map<int, YGStyle::Edges> surfaceIdToThemePaddingMap_;
mutable butter::map<int, yoga::Style::Edges> surfaceIdToThemePaddingMap_;
};

} // namespace facebook::react
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ void ViewShadowNode::initialize() noexcept {

bool formsView = formsStackingContext ||
isColorMeaningful(viewProps.backgroundColor) ||
!(viewProps.yogaStyle.border() == YGStyle::Edges{}) ||
!(viewProps.yogaStyle.border() == yoga::Style::Edges{}) ||
!viewProps.testId.empty() ||
HostPlatformViewTraitsInitializer::formsView(viewProps);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -378,10 +378,10 @@ void YogaLayoutableShadowNode::updateYogaProps() {
yogaNode_.setStyle(styleResult);
}

/*static*/ YGStyle YogaLayoutableShadowNode::applyAliasedProps(
const YGStyle &baseStyle,
/*static*/ yoga::Style YogaLayoutableShadowNode::applyAliasedProps(
const yoga::Style &baseStyle,
const YogaStylableProps &props) {
YGStyle result{baseStyle};
yoga::Style result{baseStyle};

// Aliases with precedence
if (!props.inset.isUndefined()) {
Expand Down Expand Up @@ -864,9 +864,9 @@ void YogaLayoutableShadowNode::swapLeftAndRightInYogaStyleProps(
YogaLayoutableShadowNode const &shadowNode) {
auto yogaStyle = shadowNode.yogaNode_.getStyle();

YGStyle::Edges const &position = yogaStyle.position();
YGStyle::Edges const &padding = yogaStyle.padding();
YGStyle::Edges const &margin = yogaStyle.margin();
yoga::Style::Edges const &position = yogaStyle.position();
yoga::Style::Edges const &padding = yogaStyle.padding();
yoga::Style::Edges const &margin = yogaStyle.margin();

// Swap Yoga node values, position, padding and margin.

Expand Down Expand Up @@ -950,7 +950,7 @@ void YogaLayoutableShadowNode::swapLeftAndRightInViewProps(
props.borderStyles.right.reset();
}

YGStyle::Edges const &border = props.yogaStyle.border();
yoga::Style::Edges const &border = props.yogaStyle.border();

if (props.yogaStyle.border()[YGEdgeLeft] != YGValueUndefined) {
props.yogaStyle.border()[YGEdgeStart] = border[YGEdgeLeft];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
namespace facebook::react {

class YogaLayoutableShadowNode : public LayoutableShadowNode {
using CompactValue = facebook::yoga::detail::CompactValue;
using CompactValue = facebook::yoga::CompactValue;

public:
using Shared = std::shared_ptr<YogaLayoutableShadowNode const>;
Expand Down Expand Up @@ -202,11 +202,11 @@ class YogaLayoutableShadowNode : public LayoutableShadowNode {
YogaLayoutableShadowNode const &shadowNode);

/*
* Combine a base YGStyle with aliased properties which should be flattened
* into it. E.g. reconciling "marginInlineStart" and "marginStart".
* Combine a base yoga::Style with aliased properties which should be
* flattened into it. E.g. reconciling "marginInlineStart" and "marginStart".
*/
static YGStyle applyAliasedProps(
const YGStyle &baseStyle,
static yoga::Style applyAliasedProps(
const yoga::Style &baseStyle,
const YogaStylableProps &props);

#pragma mark - Consistency Ensuring Helpers
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ void YogaStylableProps::setProp(
RawPropsPropNameHash hash,
const char *propName,
RawValue const &value) {
static const auto ygDefaults = YGStyle{};
static const auto ygDefaults = yoga::Style{};
static const auto defaults = YogaStylableProps{};

Props::setProp(context, hash, propName, value);
Expand Down Expand Up @@ -161,7 +161,7 @@ void YogaStylableProps::setProp(

#if RN_DEBUG_STRING_CONVERTIBLE
SharedDebugStringConvertibleList YogaStylableProps::getDebugProps() const {
auto const defaultYogaStyle = YGStyle{};
auto const defaultYogaStyle = yoga::Style{};
return {
debugStringConvertibleItem(
"direction", yogaStyle.direction(), defaultYogaStyle.direction()),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

#pragma once

#include <yoga/YGStyle.h>
#include <yoga/style/Style.h>

#include <react/renderer/core/Props.h>
#include <react/renderer/core/PropsParserContext.h>
Expand All @@ -16,7 +16,7 @@
namespace facebook::react {

class YogaStylableProps : public Props {
using CompactValue = facebook::yoga::detail::CompactValue;
using CompactValue = facebook::yoga::CompactValue;

public:
YogaStylableProps() = default;
Expand All @@ -38,7 +38,7 @@ class YogaStylableProps : public Props {
#endif

#pragma mark - Props
YGStyle yogaStyle{};
yoga::Style yogaStyle{};

// Duplicates of existing properties with different names, taking
// precedence. E.g. "marginBlock" instead of "marginVertical"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,7 @@ inline void fromRawValue(
inline void fromRawValue(
const PropsParserContext &context,
const RawValue &value,
YGStyle::ValueRepr &result) {
yoga::Style::ValueRepr &result) {
if (value.hasType<Float>()) {
result = yogaStyleValueFromFloat((Float)value);
return;
Expand Down Expand Up @@ -440,7 +440,7 @@ inline void fromRawValue(
const PropsParserContext &context,
const RawValue &value,
YGValue &result) {
YGStyle::ValueRepr ygValue{};
yoga::Style::ValueRepr ygValue{};
fromRawValue(context, value, ygValue);
result = ygValue;
}
Expand Down Expand Up @@ -826,11 +826,11 @@ inline std::string toString(const YGFloatOptional &value) {
return folly::to<std::string>(floatFromYogaFloat(value.unwrap()));
}

inline std::string toString(const YGStyle::Dimensions &value) {
inline std::string toString(const yoga::Style::Dimensions &value) {
return "{" + toString(value[0]) + ", " + toString(value[1]) + "}";
}

inline std::string toString(const YGStyle::Edges &value) {
inline std::string toString(const yoga::Style::Edges &value) {
static std::array<std::string, yoga::enums::count<YGEdge>()> names = {
{"left",
"top",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

namespace facebook::react {

MapBuffer convertBorderWidths(YGStyle::Edges const &border) {
MapBuffer convertBorderWidths(yoga::Style::Edges const &border) {
MapBufferBuilder builder(7);
putOptionalFloat(
builder, EDGE_TOP, optionalFloatFromYogaValue(border[YGEdgeTop]));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ namespace facebook::react {

// Nearly this entire file can be deleted when iterator-style Prop parsing
// ships fully for View
static inline YGStyle::Dimensions convertRawProp(
static inline yoga::Style::Dimensions convertRawProp(
const PropsParserContext &context,
RawProps const &rawProps,
char const *widthName,
char const *heightName,
YGStyle::Dimensions const &sourceValue,
YGStyle::Dimensions const &defaultValue) {
yoga::Style::Dimensions const &sourceValue,
yoga::Style::Dimensions const &defaultValue) {
auto dimensions = defaultValue;
dimensions[YGDimensionWidth] = convertRawProp(
context,
Expand All @@ -40,13 +40,13 @@ static inline YGStyle::Dimensions convertRawProp(
return dimensions;
}

static inline YGStyle::Edges convertRawProp(
static inline yoga::Style::Edges convertRawProp(
const PropsParserContext &context,
RawProps const &rawProps,
char const *prefix,
char const *suffix,
YGStyle::Edges const &sourceValue,
YGStyle::Edges const &defaultValue) {
yoga::Style::Edges const &sourceValue,
yoga::Style::Edges const &defaultValue) {
auto result = defaultValue;
result[YGEdgeLeft] = convertRawProp(
context,
Expand Down Expand Up @@ -123,11 +123,11 @@ static inline YGStyle::Edges convertRawProp(
return result;
}

static inline YGStyle::Edges convertRawProp(
static inline yoga::Style::Edges convertRawProp(
const PropsParserContext &context,
RawProps const &rawProps,
YGStyle::Edges const &sourceValue,
YGStyle::Edges const &defaultValue) {
yoga::Style::Edges const &sourceValue,
yoga::Style::Edges const &defaultValue) {
auto result = defaultValue;
result[YGEdgeLeft] = convertRawProp(
context,
Expand Down Expand Up @@ -168,11 +168,11 @@ static inline YGStyle::Edges convertRawProp(
return result;
}

static inline YGStyle convertRawProp(
static inline yoga::Style convertRawProp(
const PropsParserContext &context,
RawProps const &rawProps,
YGStyle const &sourceValue) {
auto yogaStyle = YGStyle{};
yoga::Style const &sourceValue) {
auto yogaStyle = yoga::Style{};
yogaStyle.direction() = convertRawProp(
context,
rawProps,
Expand Down
12 changes: 6 additions & 6 deletions packages/react-native/ReactCommon/yoga/yoga/Utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
#pragma once

#include "YGNode.h"
#include "Yoga-internal.h"
#include "CompactValue.h"
#include <yoga/Yoga-internal.h>
#include <yoga/style/CompactValue.h>

// This struct is an helper model to hold the data for step 4 of flexbox algo,
// which is collecting the flex items in a line.
Expand Down Expand Up @@ -56,8 +56,8 @@ struct YGCollectFlexItemsRowValues {

bool YGValueEqual(const YGValue& a, const YGValue& b);
inline bool YGValueEqual(
facebook::yoga::detail::CompactValue a,
facebook::yoga::detail::CompactValue b) {
facebook::yoga::CompactValue a,
facebook::yoga::CompactValue b) {
return YGValueEqual((YGValue) a, (YGValue) b);
}

Expand Down Expand Up @@ -115,7 +115,7 @@ inline YGFloatOptional YGResolveValue(
}

inline YGFloatOptional YGResolveValue(
facebook::yoga::detail::CompactValue value,
facebook::yoga::CompactValue value,
float ownerSize) {
return YGResolveValue((YGValue) value, ownerSize);
}
Expand All @@ -140,7 +140,7 @@ inline YGFlexDirection YGResolveFlexDirection(
}

inline YGFloatOptional YGResolveValueMargin(
facebook::yoga::detail::CompactValue value,
facebook::yoga::CompactValue value,
const float ownerSize) {
return value.isAuto() ? YGFloatOptional{0} : YGResolveValue(value, ownerSize);
}
4 changes: 2 additions & 2 deletions packages/react-native/ReactCommon/yoga/yoga/YGConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@

#include <yoga/Yoga.h>

#include "BitUtils.h"
#include "Yoga-internal.h"
#include <yoga/BitUtils.h>
#include <yoga/Yoga-internal.h>

namespace facebook::yoga {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

#include <cmath>
#include <limits>
#include "Yoga-internal.h"
#include <yoga/Yoga-internal.h>

struct YGFloatOptional {
private:
Expand Down
6 changes: 3 additions & 3 deletions packages/react-native/ReactCommon/yoga/yoga/YGLayout.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@

#pragma once

#include "BitUtils.h"
#include "YGFloatOptional.h"
#include "Yoga-internal.h"
#include <yoga/BitUtils.h>
#include <yoga/YGFloatOptional.h>
#include <yoga/Yoga-internal.h>

struct YGLayout {
std::array<float, 4> position = {};
Expand Down
Loading

0 comments on commit 83d1d4a

Please sign in to comment.