bump yoga native

This commit is contained in:
Atul R 2021-03-07 15:11:54 +01:00
parent 99978de2ab
commit b7ad6ed815
29 changed files with 2437 additions and 1616 deletions

View File

@ -0,0 +1,66 @@
/*
* Copyright (c) Facebook, Inc. and its 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 <cstdio>
#include <cstdint>
#include "YGEnums.h"
namespace facebook {
namespace yoga {
namespace detail {
constexpr size_t log2ceilFn(size_t n) {
return n < 1 ? 0 : (1 + log2ceilFn(n / 2));
}
constexpr int mask(size_t bitWidth, size_t index) {
return ((1 << bitWidth) - 1) << index;
}
// The number of bits necessary to represent enums defined with YG_ENUM_SEQ_DECL
template <typename Enum>
constexpr size_t bitWidthFn() {
static_assert(
enums::count<Enum>() > 0, "Enums must have at least one entries");
return log2ceilFn(enums::count<Enum>() - 1);
}
template <typename Enum>
constexpr Enum getEnumData(int flags, size_t index) {
return static_cast<Enum>((flags & mask(bitWidthFn<Enum>(), index)) >> index);
}
template <typename Enum>
void setEnumData(uint32_t& flags, size_t index, int newValue) {
flags = (flags & ~mask(bitWidthFn<Enum>(), index)) |
((newValue << index) & (mask(bitWidthFn<Enum>(), index)));
}
template <typename Enum>
void setEnumData(uint8_t& flags, size_t index, int newValue) {
flags = (flags & ~mask(bitWidthFn<Enum>(), index)) |
((newValue << index) & (mask(bitWidthFn<Enum>(), index)));
}
constexpr bool getBooleanData(int flags, size_t index) {
return (flags >> index) & 1;
}
inline void setBooleanData(uint8_t& flags, size_t index, bool value) {
if (value) {
flags |= 1 << index;
} else {
flags &= ~(1 << index);
}
}
} // namespace detail
} // namespace yoga
} // namespace facebook

View File

@ -1,144 +0,0 @@
/*
* Copyright (c) Facebook, Inc. and its 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 <yoga/YGEnums.h>
#include <cstddef>
#include <limits>
#include <type_traits>
namespace facebook {
namespace yoga {
namespace detail {
constexpr size_t log2ceil(size_t n) {
return n < 1 ? 0 : (1 + log2ceil(n / 2));
}
// The number of bits necessary to represent enums defined with YG_ENUM_SEQ_DECL
template <typename Enum>
constexpr size_t bitWidth() {
static_assert(enums::count<Enum>() > 0,
"Enums must have at least one entries");
return log2ceil(enums::count<Enum>() - 1);
}
// Number of bits needed for a boolean
template <>
constexpr size_t bitWidth<bool>() {
return 1;
}
template <typename U, typename... Ts>
struct BitTraits {};
template <typename U>
struct BitTraits<U> {
// Base cases
static constexpr size_t width(size_t) { return 0; }
static constexpr size_t shift(size_t) { return 0; }
};
template <typename U, typename T, typename... Ts>
struct BitTraits<U, T, Ts...> {
using Rest = BitTraits<U, Ts...>;
static constexpr size_t width(size_t idx) {
return idx == 0 ? bitWidth<T>() : Rest::width(idx - 1);
}
static constexpr size_t shift(size_t idx) {
return idx == 0 ? Rest::width(0) + Rest::shift(0) : Rest::shift(idx - 1);
}
static constexpr U mask(size_t idx) {
return ((U{1} << width(idx)) - 1) << shift(idx);
}
};
template <size_t Idx, typename T, typename... Ts>
struct IndexedType {
using Type = typename IndexedType<Idx - 1, Ts...>::Type;
};
template <typename T, typename... Ts>
struct IndexedType<0, T, Ts...> {
using Type = T;
};
} // namespace detail
template <typename Storage, typename... Fields>
class Bitfield {
static_assert(std::is_integral<Storage>::value,
"Bitfield needs an integral storage type");
static_assert(std::is_unsigned<Storage>::value,
"Bitfield needs an unsigned storage type");
static_assert(sizeof...(Fields) > 0, "Bitfield needs at least one member");
using BitTraits = detail::BitTraits<Storage, Fields...>;
#if !defined(_MSC_VER) || _MSC_VER > 1914
static_assert(BitTraits::shift(0) + BitTraits::width(0) <=
std::numeric_limits<Storage>::digits,
"Specified storage type is too narrow to hold all types");
#endif
template <size_t Idx>
using TypeAt = typename detail::IndexedType<Idx, Fields...>::Type;
template <size_t Idx, typename Value, typename... Values>
static constexpr Storage initStorage(Value value, Values... values) {
return ((value << BitTraits::shift(Idx)) & BitTraits::mask(Idx)) |
initStorage<Idx + 1, Values...>(values...);
}
template <size_t Idx>
static constexpr Storage initStorage() {
return Storage{0};
}
Storage storage_ = 0;
public:
template <size_t Idx>
class Ref {
Bitfield& bitfield_;
public:
Ref(Bitfield& bitfield) : bitfield_(bitfield) {}
Ref& operator=(TypeAt<Idx> value) {
bitfield_.storage_ =
(bitfield_.storage_ & ~BitTraits::mask(Idx)) |
((value << BitTraits::shift(Idx)) & BitTraits::mask(Idx));
return *this;
}
operator TypeAt<Idx>() const {
return const_cast<const Bitfield&>(bitfield_).at<Idx>();
}
};
constexpr Bitfield() = default;
constexpr Bitfield(Fields... values) : storage_{initStorage<0>(values...)} {}
template <size_t Idx>
constexpr TypeAt<Idx> at() const {
return static_cast<TypeAt<Idx>>((storage_ & BitTraits::mask(Idx)) >>
BitTraits::shift(Idx));
}
template <size_t Idx>
Ref<Idx> at() {
return {*this};
}
};
} // namespace yoga
} // namespace facebook

View File

@ -7,13 +7,12 @@
#pragma once
#include "YGValue.h"
#include "YGMacros.h"
#include <cmath>
#include <cstdint>
#include <limits>
#include "YGMacros.h"
#include "YGValue.h"
static_assert(
std::numeric_limits<float>::is_iec559,
"facebook::yoga::detail::CompactValue only works with IEEE754 floats");
@ -44,7 +43,7 @@ namespace detail {
class YOGA_EXPORT CompactValue {
friend constexpr bool operator==(CompactValue, CompactValue) noexcept;
public:
public:
static constexpr auto LOWER_BOUND = 1.08420217e-19f;
static constexpr auto UPPER_BOUND_POINT = 36893485948395847680.0f;
static constexpr auto UPPER_BOUND_PERCENT = 18446742974197923840.0f;
@ -126,18 +125,19 @@ class YOGA_EXPORT CompactValue {
data.repr &= ~PERCENT_BIT;
data.repr += BIAS;
return YGValue{data.value,
payload_.repr & 0x40000000 ? YGUnitPercent : YGUnitPoint};
return YGValue{
data.value, payload_.repr & 0x40000000 ? YGUnitPercent : YGUnitPoint};
}
bool isUndefined() const noexcept {
return (payload_.repr != AUTO_BITS && payload_.repr != ZERO_BITS_POINT &&
payload_.repr != ZERO_BITS_PERCENT && std::isnan(payload_.value));
return (
payload_.repr != AUTO_BITS && payload_.repr != ZERO_BITS_POINT &&
payload_.repr != ZERO_BITS_PERCENT && std::isnan(payload_.value));
}
bool isAuto() const noexcept { return payload_.repr == AUTO_BITS; }
private:
private:
union Payload {
float value;
uint32_t repr;
@ -179,6 +179,6 @@ constexpr bool operator!=(CompactValue a, CompactValue b) noexcept {
return !(a == b);
}
} // namespace detail
} // namespace yoga
} // namespace facebook
} // namespace detail
} // namespace yoga
} // namespace facebook

View File

@ -6,14 +6,16 @@
*/
#include "Utils.h"
#include <stdexcept>
using namespace facebook;
YGFlexDirection YGFlexDirectionCross(const YGFlexDirection flexDirection,
const YGDirection direction) {
YGFlexDirection YGFlexDirectionCross(
const YGFlexDirection flexDirection,
const YGDirection direction) {
return YGFlexDirectionIsColumn(flexDirection)
? YGResolveFlexDirection(YGFlexDirectionRow, direction)
: YGFlexDirectionColumn;
? YGResolveFlexDirection(YGFlexDirectionRow, direction)
: YGFlexDirectionColumn;
}
float YGFloatMax(const float a, const float b) {
@ -51,6 +53,13 @@ bool YGFloatsEqual(const float a, const float b) {
return yoga::isUndefined(a) && yoga::isUndefined(b);
}
bool YGDoubleEqual(const double a, const double b) {
if (!yoga::isUndefined(a) && !yoga::isUndefined(b)) {
return fabs(a - b) < 0.0001f;
}
return yoga::isUndefined(a) && yoga::isUndefined(b);
}
float YGFloatSanitize(const float val) {
return yoga::isUndefined(val) ? 0 : val;
}
@ -64,3 +73,7 @@ YGFloatOptional YGFloatOptionalMax(YGFloatOptional op1, YGFloatOptional op2) {
}
return op1.isUndefined() ? op2 : op1;
}
void throwLogicalErrorWithMessage(const char* message) {
throw std::logic_error(message);
}

View File

@ -6,9 +6,9 @@
*/
#pragma once
#include "CompactValue.h"
#include "YGNode.h"
#include "Yoga-internal.h"
#include "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.
@ -54,19 +54,23 @@ struct YGCollectFlexItemsRowValues {
};
bool YGValueEqual(const YGValue& a, const YGValue& b);
inline bool YGValueEqual(facebook::yoga::detail::CompactValue a,
facebook::yoga::detail::CompactValue b) {
return YGValueEqual((YGValue)a, (YGValue)b);
inline bool YGValueEqual(
facebook::yoga::detail::CompactValue a,
facebook::yoga::detail::CompactValue b) {
return YGValueEqual((YGValue) a, (YGValue) b);
}
// This custom float equality function returns true if either absolute
// difference between two floats is less than 0.0001f or both are undefined.
bool YGFloatsEqual(const float a, const float b);
bool YGDoubleEqual(const double a, const double b);
float YGFloatMax(const float a, const float b);
YGFloatOptional YGFloatOptionalMax(const YGFloatOptional op1,
const YGFloatOptional op2);
YGFloatOptional YGFloatOptionalMax(
const YGFloatOptional op1,
const YGFloatOptional op2);
float YGFloatMin(const float a, const float b);
@ -74,8 +78,9 @@ float YGFloatMin(const float a, const float b);
// YGFloatsEqual, as the default float comparison operator will not work(Look
// at the comments of YGFloatsEqual function).
template <std::size_t size>
bool YGFloatArrayEqual(const std::array<float, size>& val1,
const std::array<float, size>& val2) {
bool YGFloatArrayEqual(
const std::array<float, size>& val1,
const std::array<float, size>& val2) {
bool areEqual = true;
for (std::size_t i = 0; i < size && areEqual; ++i) {
areEqual = YGFloatsEqual(val1[i], val2[i]);
@ -86,16 +91,18 @@ bool YGFloatArrayEqual(const std::array<float, size>& val1,
// This function returns 0 if YGFloatIsUndefined(val) is true and val otherwise
float YGFloatSanitize(const float val);
YGFlexDirection YGFlexDirectionCross(const YGFlexDirection flexDirection,
const YGDirection direction);
YGFlexDirection YGFlexDirectionCross(
const YGFlexDirection flexDirection,
const YGDirection direction);
inline bool YGFlexDirectionIsRow(const YGFlexDirection flexDirection) {
return flexDirection == YGFlexDirectionRow ||
flexDirection == YGFlexDirectionRowReverse;
flexDirection == YGFlexDirectionRowReverse;
}
inline YGFloatOptional YGResolveValue(const YGValue value,
const float ownerSize) {
inline YGFloatOptional YGResolveValue(
const YGValue value,
const float ownerSize) {
switch (value.unit) {
case YGUnitPoint:
return YGFloatOptional{value.value};
@ -106,18 +113,20 @@ inline YGFloatOptional YGResolveValue(const YGValue value,
}
}
inline YGFloatOptional YGResolveValue(yoga::detail::CompactValue value,
float ownerSize) {
return YGResolveValue((YGValue)value, ownerSize);
inline YGFloatOptional YGResolveValue(
yoga::detail::CompactValue value,
float ownerSize) {
return YGResolveValue((YGValue) value, ownerSize);
}
inline bool YGFlexDirectionIsColumn(const YGFlexDirection flexDirection) {
return flexDirection == YGFlexDirectionColumn ||
flexDirection == YGFlexDirectionColumnReverse;
flexDirection == YGFlexDirectionColumnReverse;
}
inline YGFlexDirection YGResolveFlexDirection(
const YGFlexDirection flexDirection, const YGDirection direction) {
const YGFlexDirection flexDirection,
const YGDirection direction) {
if (direction == YGDirectionRTL) {
if (flexDirection == YGFlexDirectionRow) {
return YGFlexDirectionRowReverse;
@ -129,7 +138,10 @@ inline YGFlexDirection YGResolveFlexDirection(
return flexDirection;
}
inline YGFloatOptional YGResolveValueMargin(yoga::detail::CompactValue value,
const float ownerSize) {
inline YGFloatOptional YGResolveValueMargin(
yoga::detail::CompactValue value,
const float ownerSize) {
return value.isAuto() ? YGFloatOptional{0} : YGResolveValue(value, ownerSize);
}
void throwLogicalErrorWithMessage(const char* message);

View File

@ -12,8 +12,13 @@ YGConfig::YGConfig(YGLogger logger) : cloneNodeCallback_{nullptr} {
loggerUsesContext_ = false;
}
void YGConfig::log(YGConfig* config, YGNode* node, YGLogLevel logLevel,
void* logContext, const char* format, va_list args) {
void YGConfig::log(
YGConfig* config,
YGNode* node,
YGLogLevel logLevel,
void* logContext,
const char* format,
va_list args) {
if (loggerUsesContext_) {
logger_.withContext(config, node, logLevel, logContext, format, args);
} else {
@ -21,14 +26,16 @@ void YGConfig::log(YGConfig* config, YGNode* node, YGLogLevel logLevel,
}
}
YGNodeRef YGConfig::cloneNode(YGNodeRef node, YGNodeRef owner, int childIndex,
void* cloneContext) {
YGNodeRef YGConfig::cloneNode(
YGNodeRef node,
YGNodeRef owner,
int childIndex,
void* cloneContext) {
YGNodeRef clone = nullptr;
if (cloneNodeCallback_.noContext != nullptr) {
clone = cloneNodeUsesContext_
? cloneNodeCallback_.withContext(node, owner, childIndex,
cloneContext)
: cloneNodeCallback_.noContext(node, owner, childIndex);
? cloneNodeCallback_.withContext(node, owner, childIndex, cloneContext)
: cloneNodeCallback_.noContext(node, owner, childIndex);
}
if (clone == nullptr) {
clone = YGNodeClone(node);

View File

@ -10,13 +10,20 @@
#include "Yoga.h"
struct YOGA_EXPORT YGConfig {
using LogWithContextFn = int (*)(YGConfigRef config, YGNodeRef node,
YGLogLevel level, void* context,
const char* format, va_list args);
using CloneWithContextFn = YGNodeRef (*)(YGNodeRef node, YGNodeRef owner,
int childIndex, void* cloneContext);
using LogWithContextFn = int (*)(
YGConfigRef config,
YGNodeRef node,
YGLogLevel level,
void* context,
const char* format,
va_list args);
using CloneWithContextFn = YGNodeRef (*)(
YGNodeRef node,
YGNodeRef owner,
int childIndex,
void* cloneContext);
private:
private:
union {
CloneWithContextFn withContext;
YGCloneNodeFunc noContext;
@ -28,7 +35,7 @@ struct YOGA_EXPORT YGConfig {
bool cloneNodeUsesContext_;
bool loggerUsesContext_;
public:
public:
bool useWebDefaults = false;
bool useLegacyStretchBehaviour = false;
bool shouldDiffLayoutWithoutLegacyStretchBehaviour = false;
@ -50,8 +57,11 @@ struct YOGA_EXPORT YGConfig {
}
void setLogger(std::nullptr_t) { setLogger(YGLogger{nullptr}); }
YGNodeRef cloneNode(YGNodeRef node, YGNodeRef owner, int childIndex,
void* cloneContext);
YGNodeRef cloneNode(
YGNodeRef node,
YGNodeRef owner,
int childIndex,
void* cloneContext);
void setCloneNodeCallback(YGCloneNodeFunc cloneNode) {
cloneNodeCallback_.noContext = cloneNode;
cloneNodeUsesContext_ = false;

View File

@ -179,6 +179,8 @@ const char* YGOverflowToString(const YGOverflow value) {
const char* YGPositionTypeToString(const YGPositionType value) {
switch (value) {
case YGPositionTypeStatic:
return "static";
case YGPositionTypeRelative:
return "relative";
case YGPositionTypeAbsolute:

View File

@ -15,18 +15,18 @@ namespace yoga {
namespace enums {
template <typename T>
constexpr int count(); // can't use `= delete` due to a defect in clang < 3.9
constexpr int count(); // can't use `= delete` due to a defect in clang < 3.9
namespace detail {
template <int... xs>
constexpr int n() {
return sizeof...(xs);
}
} // namespace detail
} // namespace detail
} // namespace enums
} // namespace yoga
} // namespace facebook
} // namespace enums
} // namespace yoga
} // namespace facebook
#endif
#define YG_ENUM_DECL(NAME, ...) \
@ -54,49 +54,98 @@ constexpr int n() {
YG_EXTERN_C_BEGIN
YG_ENUM_SEQ_DECL(YGAlign, YGAlignAuto, YGAlignFlexStart, YGAlignCenter,
YGAlignFlexEnd, YGAlignStretch, YGAlignBaseline,
YGAlignSpaceBetween, YGAlignSpaceAround);
YG_ENUM_SEQ_DECL(
YGAlign,
YGAlignAuto,
YGAlignFlexStart,
YGAlignCenter,
YGAlignFlexEnd,
YGAlignStretch,
YGAlignBaseline,
YGAlignSpaceBetween,
YGAlignSpaceAround);
YG_ENUM_SEQ_DECL(YGDimension, YGDimensionWidth, YGDimensionHeight)
YG_ENUM_SEQ_DECL(YGDirection, YGDirectionInherit, YGDirectionLTR,
YGDirectionRTL)
YG_ENUM_SEQ_DECL(
YGDirection,
YGDirectionInherit,
YGDirectionLTR,
YGDirectionRTL)
YG_ENUM_SEQ_DECL(YGDisplay, YGDisplayFlex, YGDisplayNone)
YG_ENUM_SEQ_DECL(YGEdge, YGEdgeLeft, YGEdgeTop, YGEdgeRight, YGEdgeBottom,
YGEdgeStart, YGEdgeEnd, YGEdgeHorizontal, YGEdgeVertical,
YGEdgeAll)
YG_ENUM_SEQ_DECL(
YGEdge,
YGEdgeLeft,
YGEdgeTop,
YGEdgeRight,
YGEdgeBottom,
YGEdgeStart,
YGEdgeEnd,
YGEdgeHorizontal,
YGEdgeVertical,
YGEdgeAll)
YG_ENUM_SEQ_DECL(YGExperimentalFeature, YGExperimentalFeatureWebFlexBasis)
YG_ENUM_SEQ_DECL(YGFlexDirection, YGFlexDirectionColumn,
YGFlexDirectionColumnReverse, YGFlexDirectionRow,
YGFlexDirectionRowReverse)
YG_ENUM_SEQ_DECL(
YGFlexDirection,
YGFlexDirectionColumn,
YGFlexDirectionColumnReverse,
YGFlexDirectionRow,
YGFlexDirectionRowReverse)
YG_ENUM_SEQ_DECL(YGJustify, YGJustifyFlexStart, YGJustifyCenter,
YGJustifyFlexEnd, YGJustifySpaceBetween, YGJustifySpaceAround,
YGJustifySpaceEvenly)
YG_ENUM_SEQ_DECL(
YGJustify,
YGJustifyFlexStart,
YGJustifyCenter,
YGJustifyFlexEnd,
YGJustifySpaceBetween,
YGJustifySpaceAround,
YGJustifySpaceEvenly)
YG_ENUM_SEQ_DECL(YGLogLevel, YGLogLevelError, YGLogLevelWarn, YGLogLevelInfo,
YGLogLevelDebug, YGLogLevelVerbose, YGLogLevelFatal)
YG_ENUM_SEQ_DECL(
YGLogLevel,
YGLogLevelError,
YGLogLevelWarn,
YGLogLevelInfo,
YGLogLevelDebug,
YGLogLevelVerbose,
YGLogLevelFatal)
YG_ENUM_SEQ_DECL(YGMeasureMode, YGMeasureModeUndefined, YGMeasureModeExactly,
YGMeasureModeAtMost)
YG_ENUM_SEQ_DECL(
YGMeasureMode,
YGMeasureModeUndefined,
YGMeasureModeExactly,
YGMeasureModeAtMost)
YG_ENUM_SEQ_DECL(YGNodeType, YGNodeTypeDefault, YGNodeTypeText)
YG_ENUM_SEQ_DECL(YGOverflow, YGOverflowVisible, YGOverflowHidden,
YGOverflowScroll)
YG_ENUM_SEQ_DECL(
YGOverflow,
YGOverflowVisible,
YGOverflowHidden,
YGOverflowScroll)
YG_ENUM_SEQ_DECL(YGPositionType, YGPositionTypeRelative, YGPositionTypeAbsolute)
YG_ENUM_SEQ_DECL(
YGPositionType,
YGPositionTypeStatic,
YGPositionTypeRelative,
YGPositionTypeAbsolute)
YG_ENUM_DECL(YGPrintOptions, YGPrintOptionsLayout = 1, YGPrintOptionsStyle = 2,
YGPrintOptionsChildren = 4)
YG_ENUM_DECL(
YGPrintOptions,
YGPrintOptionsLayout = 1,
YGPrintOptionsStyle = 2,
YGPrintOptionsChildren = 4)
YG_ENUM_SEQ_DECL(YGUnit, YGUnitUndefined, YGUnitPoint, YGUnitPercent,
YGUnitAuto)
YG_ENUM_SEQ_DECL(
YGUnit,
YGUnitUndefined,
YGUnitPoint,
YGUnitPercent,
YGUnitAuto)
YG_ENUM_SEQ_DECL(YGWrap, YGWrapNoWrap, YGWrapWrap, YGWrapWrapReverse)

View File

@ -9,14 +9,13 @@
#include <cmath>
#include <limits>
#include "Yoga-internal.h"
struct YGFloatOptional {
private:
private:
float value_ = std::numeric_limits<float>::quiet_NaN();
public:
public:
explicit constexpr YGFloatOptional(float value) : value_(value) {}
constexpr YGFloatOptional() = default;
@ -30,7 +29,7 @@ struct YGFloatOptional {
inline bool operator==(YGFloatOptional lhs, YGFloatOptional rhs) {
return lhs.unwrap() == rhs.unwrap() ||
(lhs.isUndefined() && rhs.isUndefined());
(lhs.isUndefined() && rhs.isUndefined());
}
inline bool operator!=(YGFloatOptional lhs, YGFloatOptional rhs) {
return !(lhs == rhs);
@ -39,10 +38,16 @@ inline bool operator!=(YGFloatOptional lhs, YGFloatOptional rhs) {
inline bool operator==(YGFloatOptional lhs, float rhs) {
return lhs == YGFloatOptional{rhs};
}
inline bool operator!=(YGFloatOptional lhs, float rhs) { return !(lhs == rhs); }
inline bool operator!=(YGFloatOptional lhs, float rhs) {
return !(lhs == rhs);
}
inline bool operator==(float lhs, YGFloatOptional rhs) { return rhs == lhs; }
inline bool operator!=(float lhs, YGFloatOptional rhs) { return !(lhs == rhs); }
inline bool operator==(float lhs, YGFloatOptional rhs) {
return rhs == lhs;
}
inline bool operator!=(float lhs, YGFloatOptional rhs) {
return !(lhs == rhs);
}
inline YGFloatOptional operator+(YGFloatOptional lhs, YGFloatOptional rhs) {
return YGFloatOptional{lhs.unwrap() + rhs.unwrap()};

View File

@ -6,14 +6,12 @@
*/
#include "YGLayout.h"
#include "Utils.h"
using namespace facebook;
bool YGLayout::operator==(YGLayout layout) const {
bool isEqual =
YGFloatArrayEqual(position, layout.position) &&
bool isEqual = YGFloatArrayEqual(position, layout.position) &&
YGFloatArrayEqual(dimensions, layout.dimensions) &&
YGFloatArrayEqual(margin, layout.margin) &&
YGFloatArrayEqual(border, layout.border) &&

View File

@ -6,10 +6,12 @@
*/
#pragma once
#include "Bitfield.h"
#include "BitUtils.h"
#include "YGFloatOptional.h"
#include "Yoga-internal.h"
using namespace facebook::yoga;
struct YGLayout {
std::array<float, 4> position = {};
std::array<float, 2> dimensions = {{YGUndefined, YGUndefined}};
@ -17,22 +19,24 @@ struct YGLayout {
std::array<float, 4> border = {};
std::array<float, 4> padding = {};
private:
static constexpr size_t directionIdx = 0;
static constexpr size_t didUseLegacyFlagIdx = 1;
static constexpr size_t doesLegacyStretchFlagAffectsLayoutIdx = 2;
static constexpr size_t hadOverflowIdx = 3;
facebook::yoga::Bitfield<uint8_t, YGDirection, bool, bool, bool> flags_ = {
YGDirectionInherit, false, false, false};
private:
static constexpr size_t directionOffset = 0;
static constexpr size_t didUseLegacyFlagOffset =
directionOffset + facebook::yoga::detail::bitWidthFn<YGDirection>();
static constexpr size_t doesLegacyStretchFlagAffectsLayoutOffset =
didUseLegacyFlagOffset + 1;
static constexpr size_t hadOverflowOffset =
doesLegacyStretchFlagAffectsLayoutOffset + 1;
uint8_t flags = 0;
public:
public:
uint32_t computedFlexBasisGeneration = 0;
YGFloatOptional computedFlexBasis = {};
// Instead of recomputing the entire layout every single time, we cache some
// information to break early when nothing changed
uint32_t generationCount = 0;
YGDirection lastOwnerDirection = (YGDirection)-1;
YGDirection lastOwnerDirection = YGDirectionInherit;
uint32_t nextCachedMeasurementsIndex = 0;
std::array<YGCachedMeasurement, YG_MAX_CACHED_RESULT_COUNT>
@ -41,27 +45,41 @@ struct YGLayout {
YGCachedMeasurement cachedLayout = YGCachedMeasurement();
YGDirection direction() const { return flags_.at<directionIdx>(); }
decltype(flags_)::Ref<directionIdx> direction() {
return flags_.at<directionIdx>();
YGDirection direction() const {
return facebook::yoga::detail::getEnumData<YGDirection>(
flags, directionOffset);
}
bool didUseLegacyFlag() const { return flags_.at<didUseLegacyFlagIdx>(); }
decltype(flags_)::Ref<didUseLegacyFlagIdx> didUseLegacyFlag() {
return flags_.at<didUseLegacyFlagIdx>();
void setDirection(YGDirection direction) {
facebook::yoga::detail::setEnumData<YGDirection>(
flags, directionOffset, direction);
}
bool didUseLegacyFlag() const {
return facebook::yoga::detail::getBooleanData(
flags, didUseLegacyFlagOffset);
}
void setDidUseLegacyFlag(bool val) {
facebook::yoga::detail::setBooleanData(flags, didUseLegacyFlagOffset, val);
}
bool doesLegacyStretchFlagAffectsLayout() const {
return flags_.at<doesLegacyStretchFlagAffectsLayoutIdx>();
}
decltype(flags_)::Ref<doesLegacyStretchFlagAffectsLayoutIdx>
doesLegacyStretchFlagAffectsLayout() {
return flags_.at<doesLegacyStretchFlagAffectsLayoutIdx>();
return facebook::yoga::detail::getBooleanData(
flags, doesLegacyStretchFlagAffectsLayoutOffset);
}
bool hadOverflow() const { return flags_.at<hadOverflowIdx>(); }
decltype(flags_)::Ref<hadOverflowIdx> hadOverflow() {
return flags_.at<hadOverflowIdx>();
void setDoesLegacyStretchFlagAffectsLayout(bool val) {
facebook::yoga::detail::setBooleanData(
flags, doesLegacyStretchFlagAffectsLayoutOffset, val);
}
bool hadOverflow() const {
return facebook::yoga::detail::getBooleanData(flags, hadOverflowOffset);
}
void setHadOverflow(bool hadOverflow) {
facebook::yoga::detail::setBooleanData(
flags, hadOverflowOffset, hadOverflow);
}
bool operator==(YGLayout layout) const;

View File

@ -6,10 +6,8 @@
*/
#include "YGNode.h"
#include <algorithm>
#include <iostream>
#include "CompactValue.h"
#include "Utils.h"
@ -18,7 +16,7 @@ using facebook::yoga::detail::CompactValue;
YGNode::YGNode(YGNode&& node) {
context_ = node.context_;
flags_ = node.flags_;
flags = node.flags;
measure_ = node.measure_;
baseline_ = node.baseline_;
print_ = node.print_;
@ -31,7 +29,7 @@ YGNode::YGNode(YGNode&& node) {
config_ = node.config_;
resolvedDimensions_ = node.resolvedDimensions_;
for (auto c : children_) {
c->setOwner(c);
c->setOwner(this);
}
}
@ -44,7 +42,7 @@ YGNode::YGNode(const YGNode& node, YGConfigRef config) : YGNode{node} {
void YGNode::print(void* printContext) {
if (print_.noContext != nullptr) {
if (flags_.at<printUsesContext_>()) {
if (facebook::yoga::detail::getBooleanData(flags, printUsesContext_)) {
print_.withContext(this, printContext);
} else {
print_.noContext(this);
@ -52,104 +50,114 @@ void YGNode::print(void* printContext) {
}
}
YGFloatOptional YGNode::getLeadingPosition(const YGFlexDirection axis,
const float axisSize) const {
YGFloatOptional YGNode::getLeadingPosition(
const YGFlexDirection axis,
const float axisSize) const {
if (YGFlexDirectionIsRow(axis)) {
auto leadingPosition = YGComputedEdgeValue(style_.position(), YGEdgeStart,
CompactValue::ofUndefined());
auto leadingPosition = YGComputedEdgeValue(
style_.position(), YGEdgeStart, CompactValue::ofUndefined());
if (!leadingPosition.isUndefined()) {
return YGResolveValue(leadingPosition, axisSize);
}
}
auto leadingPosition = YGComputedEdgeValue(style_.position(), leading[axis],
CompactValue::ofUndefined());
auto leadingPosition = YGComputedEdgeValue(
style_.position(), leading[axis], CompactValue::ofUndefined());
return leadingPosition.isUndefined()
? YGFloatOptional{0}
: YGResolveValue(leadingPosition, axisSize);
? YGFloatOptional{0}
: YGResolveValue(leadingPosition, axisSize);
}
YGFloatOptional YGNode::getTrailingPosition(const YGFlexDirection axis,
const float axisSize) const {
YGFloatOptional YGNode::getTrailingPosition(
const YGFlexDirection axis,
const float axisSize) const {
if (YGFlexDirectionIsRow(axis)) {
auto trailingPosition = YGComputedEdgeValue(style_.position(), YGEdgeEnd,
CompactValue::ofUndefined());
auto trailingPosition = YGComputedEdgeValue(
style_.position(), YGEdgeEnd, CompactValue::ofUndefined());
if (!trailingPosition.isUndefined()) {
return YGResolveValue(trailingPosition, axisSize);
}
}
auto trailingPosition = YGComputedEdgeValue(style_.position(), trailing[axis],
CompactValue::ofUndefined());
auto trailingPosition = YGComputedEdgeValue(
style_.position(), trailing[axis], CompactValue::ofUndefined());
return trailingPosition.isUndefined()
? YGFloatOptional{0}
: YGResolveValue(trailingPosition, axisSize);
? YGFloatOptional{0}
: YGResolveValue(trailingPosition, axisSize);
}
bool YGNode::isLeadingPositionDefined(const YGFlexDirection axis) const {
return (YGFlexDirectionIsRow(axis) &&
!YGComputedEdgeValue(style_.position(), YGEdgeStart,
CompactValue::ofUndefined())
!YGComputedEdgeValue(
style_.position(), YGEdgeStart, CompactValue::ofUndefined())
.isUndefined()) ||
!YGComputedEdgeValue(style_.position(), leading[axis],
CompactValue::ofUndefined())
.isUndefined();
!YGComputedEdgeValue(
style_.position(), leading[axis], CompactValue::ofUndefined())
.isUndefined();
}
bool YGNode::isTrailingPosDefined(const YGFlexDirection axis) const {
return (YGFlexDirectionIsRow(axis) &&
!YGComputedEdgeValue(style_.position(), YGEdgeEnd,
CompactValue::ofUndefined())
!YGComputedEdgeValue(
style_.position(), YGEdgeEnd, CompactValue::ofUndefined())
.isUndefined()) ||
!YGComputedEdgeValue(style_.position(), trailing[axis],
CompactValue::ofUndefined())
.isUndefined();
!YGComputedEdgeValue(
style_.position(), trailing[axis], CompactValue::ofUndefined())
.isUndefined();
}
YGFloatOptional YGNode::getLeadingMargin(const YGFlexDirection axis,
const float widthSize) const {
YGFloatOptional YGNode::getLeadingMargin(
const YGFlexDirection axis,
const float widthSize) const {
if (YGFlexDirectionIsRow(axis) &&
!style_.margin()[YGEdgeStart].isUndefined()) {
return YGResolveValueMargin(style_.margin()[YGEdgeStart], widthSize);
}
return YGResolveValueMargin(
YGComputedEdgeValue(style_.margin(), leading[axis],
CompactValue::ofZero()),
YGComputedEdgeValue(
style_.margin(), leading[axis], CompactValue::ofZero()),
widthSize);
}
YGFloatOptional YGNode::getTrailingMargin(const YGFlexDirection axis,
const float widthSize) const {
YGFloatOptional YGNode::getTrailingMargin(
const YGFlexDirection axis,
const float widthSize) const {
if (YGFlexDirectionIsRow(axis) && !style_.margin()[YGEdgeEnd].isUndefined()) {
return YGResolveValueMargin(style_.margin()[YGEdgeEnd], widthSize);
}
return YGResolveValueMargin(
YGComputedEdgeValue(style_.margin(), trailing[axis],
CompactValue::ofZero()),
YGComputedEdgeValue(
style_.margin(), trailing[axis], CompactValue::ofZero()),
widthSize);
}
YGFloatOptional YGNode::getMarginForAxis(const YGFlexDirection axis,
const float widthSize) const {
YGFloatOptional YGNode::getMarginForAxis(
const YGFlexDirection axis,
const float widthSize) const {
return getLeadingMargin(axis, widthSize) + getTrailingMargin(axis, widthSize);
}
YGSize YGNode::measure(float width, YGMeasureMode widthMode, float height,
YGMeasureMode heightMode, void* layoutContext) {
return flags_.at<measureUsesContext_>()
? measure_.withContext(this, width, widthMode, height, heightMode,
layoutContext)
: measure_.noContext(this, width, widthMode, height, heightMode);
YGSize YGNode::measure(
float width,
YGMeasureMode widthMode,
float height,
YGMeasureMode heightMode,
void* layoutContext) {
return facebook::yoga::detail::getBooleanData(flags, measureUsesContext_)
? measure_.withContext(
this, width, widthMode, height, heightMode, layoutContext)
: measure_.noContext(this, width, widthMode, height, heightMode);
}
float YGNode::baseline(float width, float height, void* layoutContext) {
return flags_.at<baselineUsesContext_>()
? baseline_.withContext(this, width, height, layoutContext)
: baseline_.noContext(this, width, height);
return facebook::yoga::detail::getBooleanData(flags, baselineUsesContext_)
? baseline_.withContext(this, width, height, layoutContext)
: baseline_.noContext(this, width, height);
}
// Setters
@ -158,10 +166,11 @@ void YGNode::setMeasureFunc(decltype(YGNode::measure_) measureFunc) {
if (measureFunc.noContext == nullptr) {
// TODO: t18095186 Move nodeType to opt-in function and mark appropriate
// places in Litho
flags_.at<nodeType_>() = YGNodeTypeDefault;
setNodeType(YGNodeTypeDefault);
} else {
YGAssertWithNode(
this, children_.size() == 0,
this,
children_.size() == 0,
"Cannot set measure function: Nodes with measure functions cannot have "
"children.");
// TODO: t18095186 Move nodeType to opt-in function and mark appropriate
@ -173,14 +182,14 @@ void YGNode::setMeasureFunc(decltype(YGNode::measure_) measureFunc) {
}
void YGNode::setMeasureFunc(YGMeasureFunc measureFunc) {
flags_.at<measureUsesContext_>() = false;
facebook::yoga::detail::setBooleanData(flags, measureUsesContext_, false);
decltype(YGNode::measure_) m;
m.noContext = measureFunc;
setMeasureFunc(m);
}
YOGA_EXPORT void YGNode::setMeasureFunc(MeasureWithContextFn measureFunc) {
flags_.at<measureUsesContext_>() = true;
facebook::yoga::detail::setBooleanData(flags, measureUsesContext_, true);
decltype(YGNode::measure_) m;
m.withContext = measureFunc;
setMeasureFunc(m);
@ -199,10 +208,10 @@ void YGNode::insertChild(YGNodeRef child, uint32_t index) {
}
void YGNode::setDirty(bool isDirty) {
if (isDirty == flags_.at<isDirty_>()) {
if (isDirty == facebook::yoga::detail::getBooleanData(flags, isDirty_)) {
return;
}
flags_.at<isDirty_>() = isDirty;
facebook::yoga::detail::setBooleanData(flags, isDirty_, isDirty);
if (isDirty && dirtied_) {
dirtied_(this);
}
@ -223,7 +232,7 @@ void YGNode::removeChild(uint32_t index) {
}
void YGNode::setLayoutDirection(YGDirection direction) {
layout_.direction() = direction;
layout_.setDirection(direction);
}
void YGNode::setLayoutMargin(float margin, int index) {
@ -261,7 +270,7 @@ void YGNode::setLayoutMeasuredDimension(float measuredDimension, int index) {
}
void YGNode::setLayoutHadOverflow(bool hadOverflow) {
layout_.hadOverflow() = hadOverflow;
layout_.setHadOverflow(hadOverflow);
}
void YGNode::setLayoutDimension(float dimension, int index) {
@ -270,8 +279,9 @@ void YGNode::setLayoutDimension(float dimension, int index) {
// If both left and right are defined, then use left. Otherwise return +left or
// -right depending on which is defined.
YGFloatOptional YGNode::relativePosition(const YGFlexDirection axis,
const float axisSize) const {
YGFloatOptional YGNode::relativePosition(
const YGFlexDirection axis,
const float axisSize) const {
if (isLeadingPositionDefined(axis)) {
return getLeadingPosition(axis, axisSize);
}
@ -283,8 +293,11 @@ YGFloatOptional YGNode::relativePosition(const YGFlexDirection axis,
return trailingPosition;
}
void YGNode::setPosition(const YGDirection direction, const float mainSize,
const float crossSize, const float ownerWidth) {
void YGNode::setPosition(
const YGDirection direction,
const float mainSize,
const float crossSize,
const float ownerWidth) {
/* Root nodes should be always layouted as LTR, so we don't return negative
* values. */
const YGDirection directionRespectingRoot =
@ -294,6 +307,9 @@ void YGNode::setPosition(const YGDirection direction, const float mainSize,
const YGFlexDirection crossAxis =
YGFlexDirectionCross(mainAxis, directionRespectingRoot);
// Here we should check for `YGPositionTypeStatic` and in this case zero inset
// properties (left, right, top, bottom, begin, end).
// https://www.w3.org/TR/css-position-3/#valdef-position-static
const YGFloatOptional relativePositionMain =
relativePosition(mainAxis, mainSize);
const YGFloatOptional relativePositionCross =
@ -338,7 +354,9 @@ YGValue YGNode::resolveFlexBasisPtr() const {
return flexBasis;
}
if (!style_.flex().isUndefined() && style_.flex().unwrap() > 0.0f) {
return flags_.at<useWebDefaults_>() ? YGValueAuto : YGValueZero;
return facebook::yoga::detail::getBooleanData(flags, useWebDefaults_)
? YGValueAuto
: YGValueZero;
}
return YGValueAuto;
}
@ -377,7 +395,7 @@ void YGNode::cloneChildrenIfNeeded(void* cloneContext) {
}
void YGNode::markDirtyAndPropogate() {
if (!flags_.at<isDirty_>()) {
if (!facebook::yoga::detail::getBooleanData(flags, isDirty_)) {
setDirty(true);
setLayoutComputedFlexBasis(YGFloatOptional());
if (owner_) {
@ -387,7 +405,7 @@ void YGNode::markDirtyAndPropogate() {
}
void YGNode::markDirtyAndPropogateDownwards() {
flags_.at<isDirty_>() = true;
facebook::yoga::detail::setBooleanData(flags, isDirty_, true);
for_each(children_.begin(), children_.end(), [](YGNodeRef childNode) {
childNode->markDirtyAndPropogateDownwards();
});
@ -414,17 +432,19 @@ float YGNode::resolveFlexShrink() const {
if (!style_.flexShrink().isUndefined()) {
return style_.flexShrink().unwrap();
}
if (!flags_.at<useWebDefaults_>() && !style_.flex().isUndefined() &&
style_.flex().unwrap() < 0.0f) {
if (!facebook::yoga::detail::getBooleanData(flags, useWebDefaults_) &&
!style_.flex().isUndefined() && style_.flex().unwrap() < 0.0f) {
return -style_.flex().unwrap();
}
return flags_.at<useWebDefaults_>() ? kWebDefaultFlexShrink
: kDefaultFlexShrink;
return facebook::yoga::detail::getBooleanData(flags, useWebDefaults_)
? kWebDefaultFlexShrink
: kDefaultFlexShrink;
}
bool YGNode::isNodeFlexible() {
return ((style_.positionType() == YGPositionTypeRelative) &&
(resolveFlexGrow() != 0 || resolveFlexShrink() != 0));
return (
(style_.positionType() != YGPositionTypeAbsolute) &&
(resolveFlexGrow() != 0 || resolveFlexShrink() != 0));
}
float YGNode::getLeadingBorder(const YGFlexDirection axis) const {
@ -437,8 +457,8 @@ float YGNode::getLeadingBorder(const YGFlexDirection axis) const {
}
}
leadingBorder = YGComputedEdgeValue(style_.border(), leading[axis],
CompactValue::ofZero());
leadingBorder = YGComputedEdgeValue(
style_.border(), leading[axis], CompactValue::ofZero());
return YGFloatMax(leadingBorder.value, 0.0f);
}
@ -452,13 +472,14 @@ float YGNode::getTrailingBorder(const YGFlexDirection flexDirection) const {
}
}
trailingBorder = YGComputedEdgeValue(style_.border(), trailing[flexDirection],
CompactValue::ofZero());
trailingBorder = YGComputedEdgeValue(
style_.border(), trailing[flexDirection], CompactValue::ofZero());
return YGFloatMax(trailingBorder.value, 0.0f);
}
YGFloatOptional YGNode::getLeadingPadding(const YGFlexDirection axis,
const float widthSize) const {
YGFloatOptional YGNode::getLeadingPadding(
const YGFlexDirection axis,
const float widthSize) const {
const YGFloatOptional paddingEdgeStart =
YGResolveValue(style_.padding()[YGEdgeStart], widthSize);
if (YGFlexDirectionIsRow(axis) &&
@ -467,39 +488,42 @@ YGFloatOptional YGNode::getLeadingPadding(const YGFlexDirection axis,
return paddingEdgeStart;
}
YGFloatOptional resolvedValue =
YGResolveValue(YGComputedEdgeValue(style_.padding(), leading[axis],
CompactValue::ofZero()),
widthSize);
YGFloatOptional resolvedValue = YGResolveValue(
YGComputedEdgeValue(
style_.padding(), leading[axis], CompactValue::ofZero()),
widthSize);
return YGFloatOptionalMax(resolvedValue, YGFloatOptional(0.0f));
}
YGFloatOptional YGNode::getTrailingPadding(const YGFlexDirection axis,
const float widthSize) const {
YGFloatOptional YGNode::getTrailingPadding(
const YGFlexDirection axis,
const float widthSize) const {
const YGFloatOptional paddingEdgeEnd =
YGResolveValue(style_.padding()[YGEdgeEnd], widthSize);
if (YGFlexDirectionIsRow(axis) && paddingEdgeEnd >= YGFloatOptional{0.0f}) {
return paddingEdgeEnd;
}
YGFloatOptional resolvedValue =
YGResolveValue(YGComputedEdgeValue(style_.padding(), trailing[axis],
CompactValue::ofZero()),
widthSize);
YGFloatOptional resolvedValue = YGResolveValue(
YGComputedEdgeValue(
style_.padding(), trailing[axis], CompactValue::ofZero()),
widthSize);
return YGFloatOptionalMax(resolvedValue, YGFloatOptional(0.0f));
}
YGFloatOptional YGNode::getLeadingPaddingAndBorder(
const YGFlexDirection axis, const float widthSize) const {
const YGFlexDirection axis,
const float widthSize) const {
return getLeadingPadding(axis, widthSize) +
YGFloatOptional(getLeadingBorder(axis));
YGFloatOptional(getLeadingBorder(axis));
}
YGFloatOptional YGNode::getTrailingPaddingAndBorder(
const YGFlexDirection axis, const float widthSize) const {
const YGFlexDirection axis,
const float widthSize) const {
return getTrailingPadding(axis, widthSize) +
YGFloatOptional(getTrailingBorder(axis));
YGFloatOptional(getTrailingBorder(axis));
}
bool YGNode::didUseLegacyFlag() {
@ -518,11 +542,11 @@ bool YGNode::didUseLegacyFlag() {
void YGNode::setLayoutDoesLegacyFlagAffectsLayout(
bool doesLegacyFlagAffectsLayout) {
layout_.doesLegacyStretchFlagAffectsLayout() = doesLegacyFlagAffectsLayout;
layout_.setDoesLegacyStretchFlagAffectsLayout(doesLegacyFlagAffectsLayout);
}
void YGNode::setLayoutDidUseLegacyFlag(bool didUseLegacyFlag) {
layout_.didUseLegacyFlag() = didUseLegacyFlag;
layout_.setDidUseLegacyFlag(didUseLegacyFlag);
}
bool YGNode::isLayoutTreeEqualToNode(const YGNode& node) const {
@ -550,14 +574,17 @@ bool YGNode::isLayoutTreeEqualToNode(const YGNode& node) const {
}
void YGNode::reset() {
YGAssertWithNode(this, children_.size() == 0,
"Cannot reset a node which still has children attached");
YGAssertWithNode(this, owner_ == nullptr,
"Cannot reset a node still attached to a owner");
YGAssertWithNode(
this,
children_.size() == 0,
"Cannot reset a node which still has children attached");
YGAssertWithNode(
this, owner_ == nullptr, "Cannot reset a node still attached to a owner");
clearChildren();
auto webDefaults = flags_.at<useWebDefaults_>();
auto webDefaults =
facebook::yoga::detail::getBooleanData(flags, useWebDefaults_);
*this = YGNode{getConfig()};
if (webDefaults) {
useWebDefaults();

View File

@ -6,27 +6,28 @@
*/
#pragma once
#include <stdio.h>
#ifdef __cplusplus
#include <cstdint>
#include "Bitfield.h"
#include <stdio.h>
#include "BitUtils.h"
#include "CompactValue.h"
#include "YGConfig.h"
#include "YGLayout.h"
#include "YGMacros.h"
#include "YGStyle.h"
#include "YGMacros.h"
#include "Yoga-internal.h"
YGConfigRef YGConfigGetDefault();
struct YOGA_EXPORT YGNode {
using MeasureWithContextFn = YGSize (*)(YGNode*, float, YGMeasureMode, float,
YGMeasureMode, void*);
using MeasureWithContextFn =
YGSize (*)(YGNode*, float, YGMeasureMode, float, YGMeasureMode, void*);
using BaselineWithContextFn = float (*)(YGNode*, float, float, void*);
using PrintWithContextFn = void (*)(YGNode*, void*);
private:
private:
static constexpr size_t hasNewLayout_ = 0;
static constexpr size_t isReferenceBaseline_ = 1;
static constexpr size_t isDirty_ = 2;
@ -37,10 +38,7 @@ struct YOGA_EXPORT YGNode {
static constexpr size_t useWebDefaults_ = 7;
void* context_ = nullptr;
using Flags = facebook::yoga::Bitfield<uint8_t, bool, bool, bool, YGNodeType,
bool, bool, bool, bool>;
Flags flags_ = {true, false, false, YGNodeTypeDefault,
false, false, false, false};
uint8_t flags = 1;
uint8_t reserved_ = 0;
union {
YGMeasureFunc noContext;
@ -64,20 +62,21 @@ struct YOGA_EXPORT YGNode {
std::array<YGValue, 2> resolvedDimensions_ = {
{YGValueUndefined, YGValueUndefined}};
YGFloatOptional relativePosition(const YGFlexDirection axis,
const float axisSize) const;
YGFloatOptional relativePosition(
const YGFlexDirection axis,
const float axisSize) const;
void setMeasureFunc(decltype(measure_));
void setBaselineFunc(decltype(baseline_));
void useWebDefaults() {
flags_.at<useWebDefaults_>() = true;
facebook::yoga::detail::setBooleanData(flags, useWebDefaults_, true);
style_.flexDirection() = YGFlexDirectionRow;
style_.alignContent() = YGAlignStretch;
}
// DANGER DANGER DANGER!
// If the the node assigned to has children, we'd either have to deallocate
// If the node assigned to has children, we'd either have to deallocate
// them (potentially incorrect) or ignore them (danger of leaks). Only ever
// use this after checking that there are no children.
// DO NOT CHANGE THE VISIBILITY OF THIS METHOD!
@ -85,14 +84,14 @@ struct YOGA_EXPORT YGNode {
using CompactValue = facebook::yoga::detail::CompactValue;
public:
public:
YGNode() : YGNode{YGConfigGetDefault()} {}
explicit YGNode(const YGConfigRef config) : config_{config} {
if (config->useWebDefaults) {
useWebDefaults();
}
};
~YGNode() = default; // cleanup of owner/children relationships in YGNodeFree
~YGNode() = default; // cleanup of owner/children relationships in YGNodeFree
YGNode(YGNode&&);
@ -115,9 +114,13 @@ struct YOGA_EXPORT YGNode {
void print(void*);
bool getHasNewLayout() const { return flags_.at<hasNewLayout_>(); }
bool getHasNewLayout() const {
return facebook::yoga::detail::getBooleanData(flags, hasNewLayout_);
}
YGNodeType getNodeType() const { return flags_.at<nodeType_>(); }
YGNodeType getNodeType() const {
return facebook::yoga::detail::getEnumData<YGNodeType>(flags, nodeType_);
}
bool hasMeasureFunc() const noexcept { return measure_.noContext != nullptr; }
@ -143,7 +146,9 @@ struct YOGA_EXPORT YGNode {
uint32_t getLineIndex() const { return lineIndex_; }
bool isReferenceBaseline() { return flags_.at<isReferenceBaseline_>(); }
bool isReferenceBaseline() {
return facebook::yoga::detail::getBooleanData(flags, isReferenceBaseline_);
}
// returns the YGNodeRef that owns this YGNode. An owner is used to identify
// the YogaTree that a YGNode belongs to. This method will return the parent
@ -176,7 +181,9 @@ struct YOGA_EXPORT YGNode {
YGConfigRef getConfig() const { return config_; }
bool isDirty() const { return flags_.at<isDirty_>(); }
bool isDirty() const {
return facebook::yoga::detail::getBooleanData(flags, isDirty_);
}
std::array<YGValue, 2> getResolvedDimensions() const {
return resolvedDimensions_;
@ -187,47 +194,59 @@ struct YOGA_EXPORT YGNode {
}
// Methods related to positions, margin, padding and border
YGFloatOptional getLeadingPosition(const YGFlexDirection axis,
const float axisSize) const;
YGFloatOptional getLeadingPosition(
const YGFlexDirection axis,
const float axisSize) const;
bool isLeadingPositionDefined(const YGFlexDirection axis) const;
bool isTrailingPosDefined(const YGFlexDirection axis) const;
YGFloatOptional getTrailingPosition(const YGFlexDirection axis,
const float axisSize) const;
YGFloatOptional getLeadingMargin(const YGFlexDirection axis,
const float widthSize) const;
YGFloatOptional getTrailingMargin(const YGFlexDirection axis,
const float widthSize) const;
YGFloatOptional getTrailingPosition(
const YGFlexDirection axis,
const float axisSize) const;
YGFloatOptional getLeadingMargin(
const YGFlexDirection axis,
const float widthSize) const;
YGFloatOptional getTrailingMargin(
const YGFlexDirection axis,
const float widthSize) const;
float getLeadingBorder(const YGFlexDirection flexDirection) const;
float getTrailingBorder(const YGFlexDirection flexDirection) const;
YGFloatOptional getLeadingPadding(const YGFlexDirection axis,
const float widthSize) const;
YGFloatOptional getTrailingPadding(const YGFlexDirection axis,
const float widthSize) const;
YGFloatOptional getLeadingPaddingAndBorder(const YGFlexDirection axis,
const float widthSize) const;
YGFloatOptional getTrailingPaddingAndBorder(const YGFlexDirection axis,
const float widthSize) const;
YGFloatOptional getMarginForAxis(const YGFlexDirection axis,
const float widthSize) const;
YGFloatOptional getLeadingPadding(
const YGFlexDirection axis,
const float widthSize) const;
YGFloatOptional getTrailingPadding(
const YGFlexDirection axis,
const float widthSize) const;
YGFloatOptional getLeadingPaddingAndBorder(
const YGFlexDirection axis,
const float widthSize) const;
YGFloatOptional getTrailingPaddingAndBorder(
const YGFlexDirection axis,
const float widthSize) const;
YGFloatOptional getMarginForAxis(
const YGFlexDirection axis,
const float widthSize) const;
// Setters
void setContext(void* context) { context_ = context; }
void setPrintFunc(YGPrintFunc printFunc) {
print_.noContext = printFunc;
flags_.at<printUsesContext_>() = false;
facebook::yoga::detail::setBooleanData(flags, printUsesContext_, false);
}
void setPrintFunc(PrintWithContextFn printFunc) {
print_.withContext = printFunc;
flags_.at<printUsesContext_>() = true;
facebook::yoga::detail::setBooleanData(flags, printUsesContext_, true);
}
void setPrintFunc(std::nullptr_t) { setPrintFunc(YGPrintFunc{nullptr}); }
void setHasNewLayout(bool hasNewLayout) {
flags_.at<hasNewLayout_>() = hasNewLayout;
facebook::yoga::detail::setBooleanData(flags, hasNewLayout_, hasNewLayout);
}
void setNodeType(YGNodeType nodeType) { flags_.at<nodeType_>() = nodeType; }
void setNodeType(YGNodeType nodeType) {
return facebook::yoga::detail::setEnumData<YGNodeType>(
flags, nodeType_, nodeType);
}
void setMeasureFunc(YGMeasureFunc measureFunc);
void setMeasureFunc(MeasureWithContextFn);
@ -236,11 +255,11 @@ struct YOGA_EXPORT YGNode {
}
void setBaselineFunc(YGBaselineFunc baseLineFunc) {
flags_.at<baselineUsesContext_>() = false;
facebook::yoga::detail::setBooleanData(flags, baselineUsesContext_, false);
baseline_.noContext = baseLineFunc;
}
void setBaselineFunc(BaselineWithContextFn baseLineFunc) {
flags_.at<baselineUsesContext_>() = true;
facebook::yoga::detail::setBooleanData(flags, baselineUsesContext_, true);
baseline_.withContext = baseLineFunc;
}
void setBaselineFunc(std::nullptr_t) {
@ -256,7 +275,8 @@ struct YOGA_EXPORT YGNode {
void setLineIndex(uint32_t lineIndex) { lineIndex_ = lineIndex; }
void setIsReferenceBaseline(bool isReferenceBaseline) {
flags_.at<isReferenceBaseline_>() = isReferenceBaseline;
facebook::yoga::detail::setBooleanData(
flags, isReferenceBaseline_, isReferenceBaseline);
}
void setOwner(YGNodeRef owner) { owner_ = owner; }
@ -280,8 +300,11 @@ struct YOGA_EXPORT YGNode {
void setLayoutBorder(float border, int index);
void setLayoutPadding(float padding, int index);
void setLayoutPosition(float position, int index);
void setPosition(const YGDirection direction, const float mainSize,
const float crossSize, const float ownerWidth);
void setPosition(
const YGDirection direction,
const float mainSize,
const float crossSize,
const float ownerWidth);
void setLayoutDoesLegacyFlagAffectsLayout(bool doesLegacyFlagAffectsLayout);
void setLayoutDidUseLegacyFlag(bool didUseLegacyFlag);
void markDirtyAndPropogateDownwards();
@ -310,3 +333,5 @@ struct YOGA_EXPORT YGNode {
bool isLayoutTreeEqualToNode(const YGNode& node) const;
void reset();
};
#endif

View File

@ -7,13 +7,11 @@
#ifdef DEBUG
#include "YGNodePrint.h"
#include <stdarg.h>
#include "Utils.h"
#include "YGEnums.h"
#include "YGNode.h"
#include "Yoga-internal.h"
#include "Utils.h"
namespace facebook {
namespace yoga {
@ -27,7 +25,7 @@ static void indent(string& base, uint32_t level) {
static bool areFourValuesEqual(const YGStyle::Edges& four) {
return YGValueEqual(four[0], four[1]) && YGValueEqual(four[0], four[2]) &&
YGValueEqual(four[0], four[3]);
YGValueEqual(four[0], four[3]);
}
static void appendFormatedString(string& str, const char* fmt, ...) {
@ -43,35 +41,43 @@ static void appendFormatedString(string& str, const char* fmt, ...) {
str.append(result);
}
static void appendFloatOptionalIfDefined(string& base, const string key,
const YGFloatOptional num) {
static void appendFloatOptionalIfDefined(
string& base,
const string key,
const YGFloatOptional num) {
if (!num.isUndefined()) {
appendFormatedString(base, "%s: %g; ", key.c_str(), num.unwrap());
}
}
static void appendNumberIfNotUndefined(string& base, const string key,
const YGValue number) {
static void appendNumberIfNotUndefined(
string& base,
const string key,
const YGValue number) {
if (number.unit != YGUnitUndefined) {
if (number.unit == YGUnitAuto) {
base.append(key + ": auto; ");
} else {
string unit = number.unit == YGUnitPoint ? "px" : "%%";
appendFormatedString(base, "%s: %g%s; ", key.c_str(), number.value,
unit.c_str());
appendFormatedString(
base, "%s: %g%s; ", key.c_str(), number.value, unit.c_str());
}
}
}
static void appendNumberIfNotAuto(string& base, const string& key,
const YGValue number) {
static void appendNumberIfNotAuto(
string& base,
const string& key,
const YGValue number) {
if (number.unit != YGUnitAuto) {
appendNumberIfNotUndefined(base, key, number);
}
}
static void appendNumberIfNotZero(string& base, const string& str,
const YGValue number) {
static void appendNumberIfNotZero(
string& base,
const string& str,
const YGValue number) {
if (number.unit == YGUnitAuto) {
base.append(str + ": auto; ");
} else if (!YGFloatsEqual(number.value, 0)) {
@ -79,8 +85,10 @@ static void appendNumberIfNotZero(string& base, const string& str,
}
}
static void appendEdges(string& base, const string& key,
const YGStyle::Edges& edges) {
static void appendEdges(
string& base,
const string& key,
const YGStyle::Edges& edges) {
if (areFourValuesEqual(edges)) {
appendNumberIfNotZero(base, key, edges[YGEdgeLeft]);
} else {
@ -91,29 +99,35 @@ static void appendEdges(string& base, const string& key,
}
}
static void appendEdgeIfNotUndefined(string& base, const string& str,
const YGStyle::Edges& edges,
const YGEdge edge) {
static void appendEdgeIfNotUndefined(
string& base,
const string& str,
const YGStyle::Edges& edges,
const YGEdge edge) {
appendNumberIfNotUndefined(
base, str,
base,
str,
YGComputedEdgeValue(edges, edge, detail::CompactValue::ofUndefined()));
}
void YGNodeToString(std::string& str, YGNodeRef node, YGPrintOptions options,
uint32_t level) {
void YGNodeToString(
std::string& str,
YGNodeRef node,
YGPrintOptions options,
uint32_t level) {
indent(str, level);
appendFormatedString(str, "<div ");
if (options & YGPrintOptionsLayout) {
appendFormatedString(str, "layout=\"");
appendFormatedString(str, "width: %g; ",
node->getLayout().dimensions[YGDimensionWidth]);
appendFormatedString(str, "height: %g; ",
node->getLayout().dimensions[YGDimensionHeight]);
appendFormatedString(str, "top: %g; ",
node->getLayout().position[YGEdgeTop]);
appendFormatedString(str, "left: %g;",
node->getLayout().position[YGEdgeLeft]);
appendFormatedString(
str, "width: %g; ", node->getLayout().dimensions[YGDimensionWidth]);
appendFormatedString(
str, "height: %g; ", node->getLayout().dimensions[YGDimensionHeight]);
appendFormatedString(
str, "top: %g; ", node->getLayout().position[YGEdgeTop]);
appendFormatedString(
str, "left: %g;", node->getLayout().position[YGEdgeLeft]);
appendFormatedString(str, "\" ");
}
@ -121,24 +135,28 @@ void YGNodeToString(std::string& str, YGNodeRef node, YGPrintOptions options,
appendFormatedString(str, "style=\"");
const auto& style = node->getStyle();
if (style.flexDirection() != YGNode().getStyle().flexDirection()) {
appendFormatedString(str, "flex-direction: %s; ",
YGFlexDirectionToString(style.flexDirection()));
appendFormatedString(
str,
"flex-direction: %s; ",
YGFlexDirectionToString(style.flexDirection()));
}
if (style.justifyContent() != YGNode().getStyle().justifyContent()) {
appendFormatedString(str, "justify-content: %s; ",
YGJustifyToString(style.justifyContent()));
appendFormatedString(
str,
"justify-content: %s; ",
YGJustifyToString(style.justifyContent()));
}
if (style.alignItems() != YGNode().getStyle().alignItems()) {
appendFormatedString(str, "align-items: %s; ",
YGAlignToString(style.alignItems()));
appendFormatedString(
str, "align-items: %s; ", YGAlignToString(style.alignItems()));
}
if (style.alignContent() != YGNode().getStyle().alignContent()) {
appendFormatedString(str, "align-content: %s; ",
YGAlignToString(style.alignContent()));
appendFormatedString(
str, "align-content: %s; ", YGAlignToString(style.alignContent()));
}
if (style.alignSelf() != YGNode().getStyle().alignSelf()) {
appendFormatedString(str, "align-self: %s; ",
YGAlignToString(style.alignSelf()));
appendFormatedString(
str, "align-self: %s; ", YGAlignToString(style.alignSelf()));
}
appendFloatOptionalIfDefined(str, "flex-grow", style.flexGrow());
appendFloatOptionalIfDefined(str, "flex-shrink", style.flexShrink());
@ -146,18 +164,18 @@ void YGNodeToString(std::string& str, YGNodeRef node, YGPrintOptions options,
appendFloatOptionalIfDefined(str, "flex", style.flex());
if (style.flexWrap() != YGNode().getStyle().flexWrap()) {
appendFormatedString(str, "flex-wrap: %s; ",
YGWrapToString(style.flexWrap()));
appendFormatedString(
str, "flex-wrap: %s; ", YGWrapToString(style.flexWrap()));
}
if (style.overflow() != YGNode().getStyle().overflow()) {
appendFormatedString(str, "overflow: %s; ",
YGOverflowToString(style.overflow()));
appendFormatedString(
str, "overflow: %s; ", YGOverflowToString(style.overflow()));
}
if (style.display() != YGNode().getStyle().display()) {
appendFormatedString(str, "display: %s; ",
YGDisplayToString(style.display()));
appendFormatedString(
str, "display: %s; ", YGDisplayToString(style.display()));
}
appendEdges(str, "margin", style.margin());
appendEdges(str, "padding", style.padding());
@ -165,18 +183,18 @@ void YGNodeToString(std::string& str, YGNodeRef node, YGPrintOptions options,
appendNumberIfNotAuto(str, "width", style.dimensions()[YGDimensionWidth]);
appendNumberIfNotAuto(str, "height", style.dimensions()[YGDimensionHeight]);
appendNumberIfNotAuto(str, "max-width",
style.maxDimensions()[YGDimensionWidth]);
appendNumberIfNotAuto(str, "max-height",
style.maxDimensions()[YGDimensionHeight]);
appendNumberIfNotAuto(str, "min-width",
style.minDimensions()[YGDimensionWidth]);
appendNumberIfNotAuto(str, "min-height",
style.minDimensions()[YGDimensionHeight]);
appendNumberIfNotAuto(
str, "max-width", style.maxDimensions()[YGDimensionWidth]);
appendNumberIfNotAuto(
str, "max-height", style.maxDimensions()[YGDimensionHeight]);
appendNumberIfNotAuto(
str, "min-width", style.minDimensions()[YGDimensionWidth]);
appendNumberIfNotAuto(
str, "min-height", style.minDimensions()[YGDimensionHeight]);
if (style.positionType() != YGNode().getStyle().positionType()) {
appendFormatedString(str, "position: %s; ",
YGPositionTypeToString(style.positionType()));
appendFormatedString(
str, "position: %s; ", YGPositionTypeToString(style.positionType()));
}
appendEdgeIfNotUndefined(str, "left", style.position(), YGEdgeLeft);
@ -202,6 +220,6 @@ void YGNodeToString(std::string& str, YGNodeRef node, YGPrintOptions options,
}
appendFormatedString(str, "</div>");
}
} // namespace yoga
} // namespace facebook
} // namespace yoga
} // namespace facebook
#endif

View File

@ -14,9 +14,12 @@
namespace facebook {
namespace yoga {
void YGNodeToString(std::string& str, YGNodeRef node, YGPrintOptions options,
uint32_t level);
void YGNodeToString(
std::string& str,
YGNodeRef node,
YGPrintOptions options,
uint32_t level);
} // namespace yoga
} // namespace facebook
} // namespace yoga
} // namespace facebook
#endif

View File

@ -6,13 +6,11 @@
*/
#include "YGStyle.h"
#include "Utils.h"
// Yoga specific properties, not compatible with flexbox specification
bool operator==(const YGStyle& lhs, const YGStyle& rhs) {
bool areNonFloatValuesEqual =
lhs.direction() == rhs.direction() &&
bool areNonFloatValuesEqual = lhs.direction() == rhs.direction() &&
lhs.flexDirection() == rhs.flexDirection() &&
lhs.justifyContent() == rhs.justifyContent() &&
lhs.alignContent() == rhs.alignContent() &&
@ -29,22 +27,20 @@ bool operator==(const YGStyle& lhs, const YGStyle& rhs) {
lhs.maxDimensions() == rhs.maxDimensions();
areNonFloatValuesEqual = areNonFloatValuesEqual &&
lhs.flex().isUndefined() == rhs.flex().isUndefined();
lhs.flex().isUndefined() == rhs.flex().isUndefined();
if (areNonFloatValuesEqual && !lhs.flex().isUndefined() &&
!rhs.flex().isUndefined()) {
areNonFloatValuesEqual = areNonFloatValuesEqual && lhs.flex() == rhs.flex();
}
areNonFloatValuesEqual =
areNonFloatValuesEqual &&
areNonFloatValuesEqual = areNonFloatValuesEqual &&
lhs.flexGrow().isUndefined() == rhs.flexGrow().isUndefined();
if (areNonFloatValuesEqual && !lhs.flexGrow().isUndefined()) {
areNonFloatValuesEqual =
areNonFloatValuesEqual && lhs.flexGrow() == rhs.flexGrow();
}
areNonFloatValuesEqual =
areNonFloatValuesEqual &&
areNonFloatValuesEqual = areNonFloatValuesEqual &&
lhs.flexShrink().isUndefined() == rhs.flexShrink().isUndefined();
if (areNonFloatValuesEqual && !rhs.flexShrink().isUndefined()) {
areNonFloatValuesEqual =

View File

@ -6,17 +6,19 @@
*/
#pragma once
#ifdef __cplusplus
#include <algorithm>
#include <array>
#include <cstdint>
#include <type_traits>
#include "Bitfield.h"
#include "CompactValue.h"
#include "YGEnums.h"
#include "YGFloatOptional.h"
#include "Yoga-internal.h"
#include "Yoga.h"
#include "BitUtils.h"
class YOGA_EXPORT YGStyle {
template <typename Enum>
@ -24,10 +26,23 @@ class YOGA_EXPORT YGStyle {
facebook::yoga::detail::Values<facebook::yoga::enums::count<Enum>()>;
using CompactValue = facebook::yoga::detail::CompactValue;
public:
public:
using Dimensions = Values<YGDimension>;
using Edges = Values<YGEdge>;
template <typename T>
struct BitfieldRef {
YGStyle& style;
size_t offset;
operator T() const {
return facebook::yoga::detail::getEnumData<T>(style.flags, offset);
}
BitfieldRef<T>& operator=(T x) {
facebook::yoga::detail::setEnumData<T>(style.flags, offset, x);
return *this;
}
};
template <typename T, T YGStyle::*Prop>
struct Ref {
YGStyle& style;
@ -56,35 +71,40 @@ class YOGA_EXPORT YGStyle {
style.*Prop = values;
return *this;
}
operator const Values<Idx> &() const { return style.*Prop; }
operator const Values<Idx>&() const { return style.*Prop; }
Ref operator[](Idx idx) { return {style, idx}; }
CompactValue operator[](Idx idx) const { return (style.*Prop)[idx]; }
};
YGStyle() = default;
YGStyle() {
alignContent() = YGAlignFlexStart;
alignItems() = YGAlignStretch;
}
~YGStyle() = default;
private:
static constexpr size_t directionIdx = 0;
static constexpr size_t flexDirectionIdx = 1;
static constexpr size_t justifyContentIdx = 2;
static constexpr size_t alignContentIdx = 3;
static constexpr size_t alignItemsIdx = 4;
static constexpr size_t alignSelfIdx = 5;
static constexpr size_t positionTypeIdx = 6;
static constexpr size_t flexWrapIdx = 7;
static constexpr size_t overflowIdx = 8;
static constexpr size_t displayIdx = 9;
using Flags =
facebook::yoga::Bitfield<uint32_t, YGDirection, YGFlexDirection,
YGJustify, YGAlign, YGAlign, YGAlign,
YGPositionType, YGWrap, YGOverflow, YGDisplay>;
private:
static constexpr size_t directionOffset = 0;
static constexpr size_t flexdirectionOffset =
directionOffset + facebook::yoga::detail::bitWidthFn<YGDirection>();
static constexpr size_t justifyContentOffset = flexdirectionOffset +
facebook::yoga::detail::bitWidthFn<YGFlexDirection>();
static constexpr size_t alignContentOffset =
justifyContentOffset + facebook::yoga::detail::bitWidthFn<YGJustify>();
static constexpr size_t alignItemsOffset =
alignContentOffset + facebook::yoga::detail::bitWidthFn<YGAlign>();
static constexpr size_t alignSelfOffset =
alignItemsOffset + facebook::yoga::detail::bitWidthFn<YGAlign>();
static constexpr size_t positionTypeOffset =
alignSelfOffset + facebook::yoga::detail::bitWidthFn<YGAlign>();
static constexpr size_t flexWrapOffset =
positionTypeOffset + facebook::yoga::detail::bitWidthFn<YGPositionType>();
static constexpr size_t overflowOffset =
flexWrapOffset + facebook::yoga::detail::bitWidthFn<YGWrap>();
static constexpr size_t displayOffset =
overflowOffset + facebook::yoga::detail::bitWidthFn<YGOverflow>();
uint32_t flags = 0;
Flags flags_ = {YGDirectionInherit, YGFlexDirectionColumn,
YGJustifyFlexStart, YGAlignFlexStart,
YGAlignStretch, YGAlignAuto,
YGPositionTypeRelative, YGWrapNoWrap,
YGOverflowVisible, YGDisplayFlex};
YGFloatOptional flex_ = {};
YGFloatOptional flexGrow_ = {};
YGFloatOptional flexShrink_ = {};
@ -99,49 +119,72 @@ class YOGA_EXPORT YGStyle {
// Yoga specific properties, not compatible with flexbox specification
YGFloatOptional aspectRatio_ = {};
public:
public:
// for library users needing a type
using ValueRepr = std::remove_reference<decltype(margin_[0])>::type;
YGDirection direction() const { return flags_.at<directionIdx>(); }
Flags::Ref<directionIdx> direction() { return flags_.at<directionIdx>(); }
YGDirection direction() const {
return facebook::yoga::detail::getEnumData<YGDirection>(
flags, directionOffset);
}
BitfieldRef<YGDirection> direction() { return {*this, directionOffset}; }
YGFlexDirection flexDirection() const {
return flags_.at<flexDirectionIdx>();
return facebook::yoga::detail::getEnumData<YGFlexDirection>(
flags, flexdirectionOffset);
}
Flags::Ref<flexDirectionIdx> flexDirection() {
return flags_.at<flexDirectionIdx>();
BitfieldRef<YGFlexDirection> flexDirection() {
return {*this, flexdirectionOffset};
}
YGJustify justifyContent() const { return flags_.at<justifyContentIdx>(); }
Flags::Ref<justifyContentIdx> justifyContent() {
return flags_.at<justifyContentIdx>();
YGJustify justifyContent() const {
return facebook::yoga::detail::getEnumData<YGJustify>(
flags, justifyContentOffset);
}
BitfieldRef<YGJustify> justifyContent() {
return {*this, justifyContentOffset};
}
YGAlign alignContent() const { return flags_.at<alignContentIdx>(); }
Flags::Ref<alignContentIdx> alignContent() {
return flags_.at<alignContentIdx>();
YGAlign alignContent() const {
return facebook::yoga::detail::getEnumData<YGAlign>(
flags, alignContentOffset);
}
BitfieldRef<YGAlign> alignContent() { return {*this, alignContentOffset}; }
YGAlign alignItems() const {
return facebook::yoga::detail::getEnumData<YGAlign>(
flags, alignItemsOffset);
}
BitfieldRef<YGAlign> alignItems() { return {*this, alignItemsOffset}; }
YGAlign alignSelf() const {
return facebook::yoga::detail::getEnumData<YGAlign>(flags, alignSelfOffset);
}
BitfieldRef<YGAlign> alignSelf() { return {*this, alignSelfOffset}; }
YGPositionType positionType() const {
return facebook::yoga::detail::getEnumData<YGPositionType>(
flags, positionTypeOffset);
}
BitfieldRef<YGPositionType> positionType() {
return {*this, positionTypeOffset};
}
YGAlign alignItems() const { return flags_.at<alignItemsIdx>(); }
Flags::Ref<alignItemsIdx> alignItems() { return flags_.at<alignItemsIdx>(); }
YGAlign alignSelf() const { return flags_.at<alignSelfIdx>(); }
Flags::Ref<alignSelfIdx> alignSelf() { return flags_.at<alignSelfIdx>(); }
YGPositionType positionType() const { return flags_.at<positionTypeIdx>(); }
Flags::Ref<positionTypeIdx> positionType() {
return flags_.at<positionTypeIdx>();
YGWrap flexWrap() const {
return facebook::yoga::detail::getEnumData<YGWrap>(flags, flexWrapOffset);
}
BitfieldRef<YGWrap> flexWrap() { return {*this, flexWrapOffset}; }
YGWrap flexWrap() const { return flags_.at<flexWrapIdx>(); }
Flags::Ref<flexWrapIdx> flexWrap() { return flags_.at<flexWrapIdx>(); }
YGOverflow overflow() const {
return facebook::yoga::detail::getEnumData<YGOverflow>(
flags, overflowOffset);
}
BitfieldRef<YGOverflow> overflow() { return {*this, overflowOffset}; }
YGOverflow overflow() const { return flags_.at<overflowIdx>(); }
Flags::Ref<overflowIdx> overflow() { return flags_.at<overflowIdx>(); }
YGDisplay display() const { return flags_.at<displayIdx>(); }
Flags::Ref<displayIdx> display() { return flags_.at<displayIdx>(); }
YGDisplay display() const {
return facebook::yoga::detail::getEnumData<YGDisplay>(flags, displayOffset);
}
BitfieldRef<YGDisplay> display() { return {*this, displayOffset}; }
YGFloatOptional flex() const { return flex_; }
Ref<YGFloatOptional, &YGStyle::flex_> flex() { return {*this}; }
@ -189,3 +232,5 @@ YOGA_EXPORT bool operator==(const YGStyle& lhs, const YGStyle& rhs);
YOGA_EXPORT inline bool operator!=(const YGStyle& lhs, const YGStyle& rhs) {
return !(lhs == rhs);
}
#endif

View File

@ -8,19 +8,26 @@
#pragma once
#include <math.h>
#include "YGEnums.h"
#include "YGMacros.h"
#if defined(_MSC_VER) && defined(__clang__)
#define COMPILING_WITH_CLANG_ON_WINDOWS
#endif
#if defined(COMPILING_WITH_CLANG_ON_WINDOWS)
#include <limits>
constexpr float YGUndefined = std::numeric_limits<float>::quiet_NaN();
#else
YG_EXTERN_C_BEGIN
// Not defined in MSVC++
#ifndef NAN
static const uint32_t __nan = 0x7fc00000;
#define NAN (*(const float*)__nan)
#define NAN (*(const float*) __nan)
#endif
#define YGUndefined NAN
#endif
typedef struct YGValue {
float value;
@ -31,7 +38,10 @@ YOGA_EXPORT extern const YGValue YGValueAuto;
YOGA_EXPORT extern const YGValue YGValueUndefined;
YOGA_EXPORT extern const YGValue YGValueZero;
#if !defined(COMPILING_WITH_CLANG_ON_WINDOWS)
YG_EXTERN_C_END
#endif
#undef COMPILING_WITH_CLANG_ON_WINDOWS
#ifdef __cplusplus
@ -78,8 +88,8 @@ inline YGValue operator"" _percent(unsigned long long value) {
return operator"" _percent(static_cast<long double>(value));
}
} // namespace literals
} // namespace yoga
} // namespace facebook
} // namespace literals
} // namespace yoga
} // namespace facebook
#endif

View File

@ -10,7 +10,6 @@
#include <array>
#include <cmath>
#include <vector>
#include "CompactValue.h"
#include "Yoga.h"
@ -18,20 +17,24 @@ using YGVector = std::vector<YGNodeRef>;
YG_EXTERN_C_BEGIN
void YGNodeCalculateLayoutWithContext(YGNodeRef node, float availableWidth,
float availableHeight,
YGDirection ownerDirection,
void* layoutContext);
void YGNodeCalculateLayoutWithContext(
YGNodeRef node,
float availableWidth,
float availableHeight,
YGDirection ownerDirection,
void* layoutContext);
YG_EXTERN_C_END
namespace facebook {
namespace yoga {
inline bool isUndefined(float value) { return std::isnan(value); }
inline bool isUndefined(float value) {
return std::isnan(value);
}
} // namespace yoga
} // namespace facebook
} // namespace yoga
} // namespace facebook
using namespace facebook;
@ -51,16 +54,16 @@ struct YGCachedMeasurement {
float computedHeight;
YGCachedMeasurement()
: availableWidth(0),
availableHeight(0),
widthMeasureMode((YGMeasureMode)-1),
heightMeasureMode((YGMeasureMode)-1),
: availableWidth(-1),
availableHeight(-1),
widthMeasureMode(YGMeasureModeUndefined),
heightMeasureMode(YGMeasureModeUndefined),
computedWidth(-1),
computedHeight(-1) {}
bool operator==(YGCachedMeasurement measurement) const {
bool isEqual = widthMeasureMode == measurement.widthMeasureMode &&
heightMeasureMode == measurement.heightMeasureMode;
heightMeasureMode == measurement.heightMeasureMode;
if (!yoga::isUndefined(availableWidth) ||
!yoga::isUndefined(measurement.availableWidth)) {
@ -93,10 +96,10 @@ namespace detail {
template <size_t Size>
class Values {
private:
private:
std::array<CompactValue, Size> values_;
public:
public:
Values() = default;
explicit Values(const YGValue& defaultValue) noexcept {
values_.fill(defaultValue);
@ -132,9 +135,9 @@ class Values {
Values& operator=(const Values& other) = default;
};
} // namespace detail
} // namespace yoga
} // namespace facebook
} // namespace detail
} // namespace yoga
} // namespace facebook
static const float kDefaultFlexGrow = 0.0f;
static const float kDefaultFlexShrink = 0.0f;
@ -144,4 +147,5 @@ extern bool YGFloatsEqual(const float a, const float b);
extern facebook::yoga::detail::CompactValue YGComputedEdgeValue(
const facebook::yoga::detail::Values<
facebook::yoga::enums::count<YGEdge>()>& edges,
YGEdge edge, facebook::yoga::detail::CompactValue defaultValue);
YGEdge edge,
facebook::yoga::detail::CompactValue defaultValue);

File diff suppressed because it is too large Load Diff

View File

@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
// v1.18.0
#pragma once
#include <assert.h>
@ -34,30 +34,45 @@ typedef struct YGConfig* YGConfigRef;
typedef struct YGNode* YGNodeRef;
typedef const struct YGNode* YGNodeConstRef;
typedef YGSize (*YGMeasureFunc)(YGNodeRef node, float width,
YGMeasureMode widthMode, float height,
YGMeasureMode heightMode);
typedef YGSize (*YGMeasureFunc)(
YGNodeRef node,
float width,
YGMeasureMode widthMode,
float height,
YGMeasureMode heightMode);
typedef float (*YGBaselineFunc)(YGNodeRef node, float width, float height);
typedef void (*YGDirtiedFunc)(YGNodeRef node);
typedef void (*YGPrintFunc)(YGNodeRef node);
typedef void (*YGNodeCleanupFunc)(YGNodeRef node);
typedef int (*YGLogger)(YGConfigRef config, YGNodeRef node, YGLogLevel level,
const char* format, va_list args);
typedef YGNodeRef (*YGCloneNodeFunc)(YGNodeRef oldNode, YGNodeRef owner,
int childIndex);
typedef int (*YGLogger)(
YGConfigRef config,
YGNodeRef node,
YGLogLevel level,
const char* format,
va_list args);
typedef YGNodeRef (
*YGCloneNodeFunc)(YGNodeRef oldNode, YGNodeRef owner, int childIndex);
// YGNode
WIN_EXPORT YGNodeRef YGNodeNew(void);
WIN_EXPORT YGNodeRef YGNodeNewWithConfig(YGConfigRef config);
WIN_EXPORT YGNodeRef YGNodeClone(YGNodeRef node);
WIN_EXPORT void YGNodeFree(YGNodeRef node);
WIN_EXPORT void YGNodeFreeRecursiveWithCleanupFunc(YGNodeRef node,
YGNodeCleanupFunc cleanup);
WIN_EXPORT void YGNodeFreeRecursiveWithCleanupFunc(
YGNodeRef node,
YGNodeCleanupFunc cleanup);
WIN_EXPORT void YGNodeFreeRecursive(YGNodeRef node);
WIN_EXPORT void YGNodeReset(YGNodeRef node);
WIN_EXPORT void YGNodeInsertChild(YGNodeRef node, YGNodeRef child,
uint32_t index);
WIN_EXPORT void YGNodeInsertChild(
YGNodeRef node,
YGNodeRef child,
uint32_t index);
WIN_EXPORT void YGNodeSwapChild(
YGNodeRef node,
YGNodeRef child,
uint32_t index);
WIN_EXPORT void YGNodeRemoveChild(YGNodeRef node, YGNodeRef child);
WIN_EXPORT void YGNodeRemoveAllChildren(YGNodeRef node);
@ -65,17 +80,22 @@ WIN_EXPORT YGNodeRef YGNodeGetChild(YGNodeRef node, uint32_t index);
WIN_EXPORT YGNodeRef YGNodeGetOwner(YGNodeRef node);
WIN_EXPORT YGNodeRef YGNodeGetParent(YGNodeRef node);
WIN_EXPORT uint32_t YGNodeGetChildCount(YGNodeRef node);
WIN_EXPORT void YGNodeSetChildren(YGNodeRef owner, const YGNodeRef children[],
uint32_t count);
WIN_EXPORT void YGNodeSetChildren(
YGNodeRef owner,
const YGNodeRef children[],
uint32_t count);
WIN_EXPORT void YGNodeSetIsReferenceBaseline(YGNodeRef node,
bool isReferenceBaseline);
WIN_EXPORT void YGNodeSetIsReferenceBaseline(
YGNodeRef node,
bool isReferenceBaseline);
WIN_EXPORT bool YGNodeIsReferenceBaseline(YGNodeRef node);
WIN_EXPORT void YGNodeCalculateLayout(YGNodeRef node, float availableWidth,
float availableHeight,
YGDirection ownerDirection);
WIN_EXPORT void YGNodeCalculateLayout(
YGNodeRef node,
float availableWidth,
float availableHeight,
YGDirection ownerDirection);
// Mark a node as dirty. Only valid for nodes with a custom measure function
// set.
@ -96,10 +116,18 @@ WIN_EXPORT void YGNodePrint(YGNodeRef node, YGPrintOptions options);
WIN_EXPORT bool YGFloatIsUndefined(float value);
WIN_EXPORT bool YGNodeCanUseCachedMeasurement(
YGMeasureMode widthMode, float width, YGMeasureMode heightMode,
float height, YGMeasureMode lastWidthMode, float lastWidth,
YGMeasureMode lastHeightMode, float lastHeight, float lastComputedWidth,
float lastComputedHeight, float marginRow, float marginColumn,
YGMeasureMode widthMode,
float width,
YGMeasureMode heightMode,
float height,
YGMeasureMode lastWidthMode,
float lastWidth,
YGMeasureMode lastHeightMode,
float lastHeight,
float lastComputedWidth,
float lastComputedHeight,
float marginRow,
float marginColumn,
YGConfigRef config);
WIN_EXPORT void YGNodeCopyStyle(YGNodeRef dstNode, YGNodeRef srcNode);
@ -124,16 +152,19 @@ bool YGNodeLayoutGetDidUseLegacyFlag(YGNodeRef node);
WIN_EXPORT void YGNodeStyleSetDirection(YGNodeRef node, YGDirection direction);
WIN_EXPORT YGDirection YGNodeStyleGetDirection(YGNodeConstRef node);
WIN_EXPORT void YGNodeStyleSetFlexDirection(YGNodeRef node,
YGFlexDirection flexDirection);
WIN_EXPORT void YGNodeStyleSetFlexDirection(
YGNodeRef node,
YGFlexDirection flexDirection);
WIN_EXPORT YGFlexDirection YGNodeStyleGetFlexDirection(YGNodeConstRef node);
WIN_EXPORT void YGNodeStyleSetJustifyContent(YGNodeRef node,
YGJustify justifyContent);
WIN_EXPORT void YGNodeStyleSetJustifyContent(
YGNodeRef node,
YGJustify justifyContent);
WIN_EXPORT YGJustify YGNodeStyleGetJustifyContent(YGNodeConstRef node);
WIN_EXPORT void YGNodeStyleSetAlignContent(YGNodeRef node,
YGAlign alignContent);
WIN_EXPORT void YGNodeStyleSetAlignContent(
YGNodeRef node,
YGAlign alignContent);
WIN_EXPORT YGAlign YGNodeStyleGetAlignContent(YGNodeConstRef node);
WIN_EXPORT void YGNodeStyleSetAlignItems(YGNodeRef node, YGAlign alignItems);
@ -142,8 +173,9 @@ WIN_EXPORT YGAlign YGNodeStyleGetAlignItems(YGNodeConstRef node);
WIN_EXPORT void YGNodeStyleSetAlignSelf(YGNodeRef node, YGAlign alignSelf);
WIN_EXPORT YGAlign YGNodeStyleGetAlignSelf(YGNodeConstRef node);
WIN_EXPORT void YGNodeStyleSetPositionType(YGNodeRef node,
YGPositionType positionType);
WIN_EXPORT void YGNodeStyleSetPositionType(
YGNodeRef node,
YGPositionType positionType);
WIN_EXPORT YGPositionType YGNodeStyleGetPositionType(YGNodeConstRef node);
WIN_EXPORT void YGNodeStyleSetFlexWrap(YGNodeRef node, YGWrap flexWrap);
@ -169,22 +201,32 @@ WIN_EXPORT void YGNodeStyleSetFlexBasisPercent(YGNodeRef node, float flexBasis);
WIN_EXPORT void YGNodeStyleSetFlexBasisAuto(YGNodeRef node);
WIN_EXPORT YGValue YGNodeStyleGetFlexBasis(YGNodeConstRef node);
WIN_EXPORT void YGNodeStyleSetPosition(YGNodeRef node, YGEdge edge,
float position);
WIN_EXPORT void YGNodeStyleSetPositionPercent(YGNodeRef node, YGEdge edge,
float position);
WIN_EXPORT void YGNodeStyleSetPosition(
YGNodeRef node,
YGEdge edge,
float position);
WIN_EXPORT void YGNodeStyleSetPositionPercent(
YGNodeRef node,
YGEdge edge,
float position);
WIN_EXPORT YGValue YGNodeStyleGetPosition(YGNodeConstRef node, YGEdge edge);
WIN_EXPORT void YGNodeStyleSetMargin(YGNodeRef node, YGEdge edge, float margin);
WIN_EXPORT void YGNodeStyleSetMarginPercent(YGNodeRef node, YGEdge edge,
float margin);
WIN_EXPORT void YGNodeStyleSetMarginPercent(
YGNodeRef node,
YGEdge edge,
float margin);
WIN_EXPORT void YGNodeStyleSetMarginAuto(YGNodeRef node, YGEdge edge);
WIN_EXPORT YGValue YGNodeStyleGetMargin(YGNodeConstRef node, YGEdge edge);
WIN_EXPORT void YGNodeStyleSetPadding(YGNodeRef node, YGEdge edge,
float padding);
WIN_EXPORT void YGNodeStyleSetPaddingPercent(YGNodeRef node, YGEdge edge,
float padding);
WIN_EXPORT void YGNodeStyleSetPadding(
YGNodeRef node,
YGEdge edge,
float padding);
WIN_EXPORT void YGNodeStyleSetPaddingPercent(
YGNodeRef node,
YGEdge edge,
float padding);
WIN_EXPORT YGValue YGNodeStyleGetPadding(YGNodeConstRef node, YGEdge edge);
WIN_EXPORT void YGNodeStyleSetBorder(YGNodeRef node, YGEdge edge, float border);
@ -254,16 +296,22 @@ WIN_EXPORT float YGNodeLayoutGetPadding(YGNodeRef node, YGEdge edge);
WIN_EXPORT void YGConfigSetLogger(YGConfigRef config, YGLogger logger);
WIN_EXPORT void YGAssert(bool condition, const char* message);
WIN_EXPORT void YGAssertWithNode(YGNodeRef node, bool condition,
const char* message);
WIN_EXPORT void YGAssertWithConfig(YGConfigRef config, bool condition,
const char* message);
WIN_EXPORT void YGAssertWithNode(
YGNodeRef node,
bool condition,
const char* message);
WIN_EXPORT void YGAssertWithConfig(
YGConfigRef config,
bool condition,
const char* message);
// Set this to number of pixels in 1 point to round calculation results If you
// want to avoid rounding - set PointScaleFactor to 0
WIN_EXPORT void YGConfigSetPointScaleFactor(YGConfigRef config,
float pixelsInPoint);
WIN_EXPORT void YGConfigSetPointScaleFactor(
YGConfigRef config,
float pixelsInPoint);
void YGConfigSetShouldDiffLayoutWithoutLegacyStretchBehaviour(
YGConfigRef config, bool shouldDiffLayout);
YGConfigRef config,
bool shouldDiffLayout);
// Yoga previously had an error where containers would take the maximum space
// possible instead of the minimum like they are supposed to. In practice this
@ -271,7 +319,8 @@ void YGConfigSetShouldDiffLayoutWithoutLegacyStretchBehaviour(
// was such a long-standing bug we must allow legacy users to switch back to
// this behaviour.
WIN_EXPORT void YGConfigSetUseLegacyStretchBehaviour(
YGConfigRef config, bool useLegacyStretchBehaviour);
YGConfigRef config,
bool useLegacyStretchBehaviour);
// YGConfig
WIN_EXPORT YGConfigRef YGConfigNew(void);
@ -280,17 +329,21 @@ WIN_EXPORT void YGConfigCopy(YGConfigRef dest, YGConfigRef src);
WIN_EXPORT int32_t YGConfigGetInstanceCount(void);
WIN_EXPORT void YGConfigSetExperimentalFeatureEnabled(
YGConfigRef config, YGExperimentalFeature feature, bool enabled);
YGConfigRef config,
YGExperimentalFeature feature,
bool enabled);
WIN_EXPORT bool YGConfigIsExperimentalFeatureEnabled(
YGConfigRef config, YGExperimentalFeature feature);
YGConfigRef config,
YGExperimentalFeature feature);
// Using the web defaults is the preferred configuration for new projects. Usage
// of non web defaults should be considered as legacy.
WIN_EXPORT void YGConfigSetUseWebDefaults(YGConfigRef config, bool enabled);
WIN_EXPORT bool YGConfigGetUseWebDefaults(YGConfigRef config);
WIN_EXPORT void YGConfigSetCloneNodeFunc(YGConfigRef config,
YGCloneNodeFunc callback);
WIN_EXPORT void YGConfigSetCloneNodeFunc(
YGConfigRef config,
YGCloneNodeFunc callback);
// Export only for C#
WIN_EXPORT YGConfigRef YGConfigGetDefault(void);
@ -298,8 +351,11 @@ WIN_EXPORT YGConfigRef YGConfigGetDefault(void);
WIN_EXPORT void YGConfigSetContext(YGConfigRef config, void* context);
WIN_EXPORT void* YGConfigGetContext(YGConfigRef config);
WIN_EXPORT float YGRoundValueToPixelGrid(float value, float pointScaleFactor,
bool forceCeil, bool forceFloor);
WIN_EXPORT float YGRoundValueToPixelGrid(
double value,
double pointScaleFactor,
bool forceCeil,
bool forceFloor);
YG_EXTERN_C_END
@ -309,8 +365,9 @@ YG_EXTERN_C_END
#include <vector>
// Calls f on each node in the tree including the given node argument.
void YGTraversePreOrder(YGNodeRef node,
std::function<void(YGNodeRef node)>&& f);
void YGTraversePreOrder(
YGNodeRef node,
std::function<void(YGNodeRef node)>&& f);
void YGNodeSetChildren(YGNodeRef owner, const std::vector<YGNodeRef>& children);

View File

@ -6,10 +6,8 @@
*/
#include "event.h"
#include <atomic>
#include <memory>
#include <stdexcept>
namespace facebook {
namespace yoga {
@ -61,7 +59,7 @@ Node* push(Node* newHead) {
return oldHead;
}
} // namespace
} // namespace
void Event::reset() {
auto head = push(nullptr);
@ -78,10 +76,11 @@ void Event::subscribe(std::function<Subscriber>&& subscriber) {
void Event::publish(const YGNode& node, Type eventType, const Data& eventData) {
for (auto subscriber = subscribers.load(std::memory_order_relaxed);
subscriber != nullptr; subscriber = subscriber->next) {
subscriber != nullptr;
subscriber = subscriber->next) {
subscriber->subscriber(node, eventType, eventData);
}
}
} // namespace yoga
} // namespace facebook
} // namespace yoga
} // namespace facebook

View File

@ -7,12 +7,11 @@
#pragma once
#include <yoga/YGEnums.h>
#include <array>
#include <cstdint>
#include <functional>
#include <vector>
#include <array>
#include <yoga/YGEnums.h>
#include <stdint.h>
struct YGConfig;
struct YGNode;
@ -74,7 +73,7 @@ struct YOGA_EXPORT Event {
class Data {
const void* data_;
public:
public:
template <Type E>
Data(const TypedData<E>& data) : data_{&data} {}
@ -100,7 +99,7 @@ struct YOGA_EXPORT Event {
publish<E>(*node, eventData);
}
private:
private:
static void publish(const YGNode&, Type, const Data&);
};
@ -143,5 +142,5 @@ struct Event::TypedData<Event::NodeLayout> {
void* layoutContext;
};
} // namespace yoga
} // namespace facebook
} // namespace yoga
} // namespace facebook

View File

@ -7,24 +7,26 @@
#pragma once
#include <bitset>
#include "experiments.h"
#include <bitset>
namespace facebook {
namespace yoga {
namespace internal {
namespace detail {
extern std::bitset<sizeof(int)> enabledExperiments;
} // namespace detail
} // namespace detail
inline bool isEnabled(Experiment experiment) {
return detail::enabledExperiments.test(static_cast<size_t>(experiment));
}
inline void disableAllExperiments() { detail::enabledExperiments = 0; }
inline void disableAllExperiments() {
detail::enabledExperiments = 0;
}
} // namespace internal
} // namespace yoga
} // namespace facebook
} // namespace internal
} // namespace yoga
} // namespace facebook

View File

@ -6,7 +6,6 @@
*/
#include "experiments.h"
#include "experiments-inl.h"
namespace facebook {
@ -17,7 +16,7 @@ namespace detail {
std::bitset<sizeof(int)> enabledExperiments = 0;
} // namespace detail
} // namespace detail
void enable(Experiment experiment) {
detail::enabledExperiments.set(static_cast<size_t>(experiment));
@ -34,6 +33,6 @@ bool toggle(Experiment experiment) {
return previousState;
}
} // namespace internal
} // namespace yoga
} // namespace facebook
} // namespace internal
} // namespace yoga
} // namespace facebook

View File

@ -21,6 +21,6 @@ void enable(Experiment);
void disable(Experiment);
bool toggle(Experiment);
} // namespace internal
} // namespace yoga
} // namespace facebook
} // namespace internal
} // namespace yoga
} // namespace facebook

View File

@ -7,9 +7,9 @@
#include "log.h"
#include "Yoga.h"
#include "YGConfig.h"
#include "YGNode.h"
#include "Yoga.h"
namespace facebook {
namespace yoga {
@ -17,34 +17,48 @@ namespace detail {
namespace {
void vlog(YGConfig* config, YGNode* node, YGLogLevel level, void* context,
const char* format, va_list args) {
void vlog(
YGConfig* config,
YGNode* node,
YGLogLevel level,
void* context,
const char* format,
va_list args) {
YGConfig* logConfig = config != nullptr ? config : YGConfigGetDefault();
logConfig->log(logConfig, node, level, context, format, args);
if (level == YGLogLevelFatal) {
abort();
}
}
} // namespace
} // namespace
YOGA_EXPORT void Log::log(YGNode* node, YGLogLevel level, void* context,
const char* format, ...) noexcept {
YOGA_EXPORT void Log::log(
YGNode* node,
YGLogLevel level,
void* context,
const char* format,
...) noexcept {
va_list args;
va_start(args, format);
vlog(node == nullptr ? nullptr : node->getConfig(), node, level, context,
format, args);
vlog(
node == nullptr ? nullptr : node->getConfig(),
node,
level,
context,
format,
args);
va_end(args);
}
void Log::log(YGConfig* config, YGLogLevel level, void* context,
const char* format, ...) noexcept {
void Log::log(
YGConfig* config,
YGLogLevel level,
void* context,
const char* format,
...) noexcept {
va_list args;
va_start(args, format);
vlog(config, nullptr, level, context, format, args);
va_end(args);
}
} // namespace detail
} // namespace yoga
} // namespace facebook
} // namespace detail
} // namespace yoga
} // namespace facebook

View File

@ -18,13 +18,21 @@ namespace yoga {
namespace detail {
struct Log {
static void log(YGNode* node, YGLogLevel level, void*, const char* message,
...) noexcept;
static void log(
YGNode* node,
YGLogLevel level,
void*,
const char* message,
...) noexcept;
static void log(YGConfig* config, YGLogLevel level, void*, const char* format,
...) noexcept;
static void log(
YGConfig* config,
YGLogLevel level,
void*,
const char* format,
...) noexcept;
};
} // namespace detail
} // namespace yoga
} // namespace facebook
} // namespace detail
} // namespace yoga
} // namespace facebook