diff --git a/.gitignore b/.gitignore index dcefcc3e9..461e6f6a0 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ node_modules *.log build dist -.vscode \ No newline at end of file +.vscode +.cache \ No newline at end of file diff --git a/config/deps.gypi b/config/deps.gypi index 0370389ec..298b2e0e6 100644 --- a/config/deps.gypi +++ b/config/deps.gypi @@ -4,18 +4,18 @@ "include_dirs": ['../deps/'], "cflags": ['-DSPDLOG_COMPILED_LIB'], "sources": [ - "../deps/yoga/Yoga.cpp", - "../deps/yoga/YGValue.cpp", - "../deps/yoga/YGStyle.cpp", - "../deps/yoga/YGNodePrint.cpp", - "../deps/yoga/YGNode.cpp", - "../deps/yoga/YGMarker.cpp", - "../deps/yoga/YGLayout.cpp", - "../deps/yoga/YGEnums.cpp", - "../deps/yoga/YGConfig.cpp", - "../deps/yoga/Utils.cpp", - "../deps/yoga/log.cpp", - "../deps/yoga/event/event.cpp", + "../deps/yoga/log.cpp", + "../deps/yoga/Utils.cpp", + "../deps/yoga/YGConfig.cpp", + "../deps/yoga/YGEnums.cpp", + "../deps/yoga/YGLayout.cpp", + "../deps/yoga/YGNode.cpp", + "../deps/yoga/YGNodePrint.cpp", + "../deps/yoga/YGStyle.cpp", + "../deps/yoga/YGValue.cpp", + "../deps/yoga/Yoga.cpp", + "../deps/yoga/event/event.cpp", + "../deps/yoga/internal/experiments.cpp" ], } } diff --git a/deps/yoga/CompactValue.h b/deps/yoga/CompactValue.h index 204517795..899dcc58c 100644 --- a/deps/yoga/CompactValue.h +++ b/deps/yoga/CompactValue.h @@ -1,4 +1,4 @@ -/** +/* * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the LICENSE diff --git a/deps/yoga/README.md b/deps/yoga/README.md deleted file mode 100644 index b577159c3..000000000 --- a/deps/yoga/README.md +++ /dev/null @@ -1,278 +0,0 @@ -## Copy of old doc - -This doc was originally found at: `https://github.com/facebook/yoga/blob/d66239bea8dc74526343d414a4923237081d7b5c/docs/_docs/api/c.md` - -`YGNodeRef` is the main object you will be interfacing with when using Yoga in C. `YGNodeRef` is a pointer to an internal `YGNode` struct. - -### Lifecycle - -The following functions control the lifecycle of a `YGNodeRef`. - -```c -YGNodeRef YGNodeNew(); -void YGNodeReset(YGNodeRef node); -void YGNodeFree(YGNodeRef node); -void YGNodeFreeRecursive(YGNodeRef node); -``` - -- `YGNodeReset` will reset a node to its initial state so it can be re-used without needing to re-allocate a new node. -- `YGNodeFreeRecursive` is mostly used for testing and will free not only the node itself but also its children. - -### Children - -The following functions help manage the children of a node. - -```c -void YGNodeInsertChild(YGNodeRef node, YGNodeRef child, uint32_t index); -void YGNodeRemoveChild(YGNodeRef node, YGNodeRef child); -YGNodeRef YGNodeGetChild(YGNodeRef node, uint32_t index); -uint32_t YGNodeGetChildCount(YGNodeRef node); -``` - -### Style getters & setters - -The large part of Yoga's API consists of setters and getters for styles. These all follow the same general structure. Bellow are the function and enums used to control the various styles. For an in depth guide to how each style works see the getting started guide. - -```c -typedef enum YGDirection { - YGDirectionInherit, - YGDirectionLTR, - YGDirectionRTL, -} YGDirection; - -void YGNodeStyleSetDirection(YGNodeRef node, YGDirection direction); -YGDirection YGNodeStyleGetDirection(YGNodeRef node); - -typedef enum YGFlexDirection { - YGFlexDirectionColumn, - YGFlexDirectionColumnReverse, - YGFlexDirectionRow, - YGFlexDirectionRowReverse, -} YGFlexDirection; - -void YGNodeStyleSetFlexDirection(YGNodeRef node, - YGFlexDirection flexDirection); -YGFlexDirection YGNodeStyleGetFlexDirection(YGNodeRef node); - -typedef enum YGJustify { - YGJustifyFlexStart, - YGJustifyCenter, - YGJustifyFlexEnd, - YGJustifySpaceBetween, - YGJustifySpaceAround, -} YGJustify; - -void YGNodeStyleSetJustifyContent(YGNodeRef node, - YGJustify justifyContent); -YGJustify YGNodeStyleGetJustifyContent(YGNodeRef node); - -typedef enum YGAlign { - YGAlignAuto, - YGAlignFlexStart, - YGAlignCenter, - YGAlignFlexEnd, - YGAlignStretch, -} YGAlign; - -void YGNodeStyleSetAlignContent(YGNodeRef node, YGAlign alignContent); -YGAlign YGNodeStyleGetAlignContent(YGNodeRef node); - -void YGNodeStyleSetAlignItems(YGNodeRef node, YGAlign alignItems); -YGAlign YGNodeStyleGetAlignItems(YGNodeRef node); - -void YGNodeStyleSetAlignSelf(YGNodeRef node, YGAlign alignSelf); -YGAlign YGNodeStyleGetAlignSelf(YGNodeRef node); - -typedef enum YGPositionType { - YGPositionTypeRelative, - YGPositionTypeAbsolute, -} YGPositionType; - -void YGNodeStyleSetPositionType(YGNodeRef node, - YGPositionType positionType); -YGPositionType YGNodeStyleGetPositionType(YGNodeRef node); - -typedef enum YGWrap { - YGWrapNoWrap, - YGWrapWrap, -} YGWrap; - -void YGNodeStyleSetFlexWrap(YGNodeRef node, YGWrap flexWrap); -YGWrap YGNodeStyleGetFlexWrap(YGNodeRef node); - -typedef enum YGOverflow { - YGOverflowVisible, - YGOverflowHidden, - YGOverflowScroll, -} YGOverflow; - -void YGNodeStyleSetOverflow(YGNodeRef node, YGOverflow overflow); -YGOverflow YGNodeStyleGetOverflow(YGNodeRef node); - -void YGNodeStyleSetFlex(YGNodeRef node, float flex); - -void YGNodeStyleSetFlexGrow(YGNodeRef node, float flexGrow); -float YGNodeStyleGetFlexGrow(YGNodeRef node); - -void YGNodeStyleSetFlexShrink(YGNodeRef node, float flexShrink); -float YGNodeStyleGetFlexShrink(YGNodeRef node); - -void YGNodeStyleSetFlexBasis(YGNodeRef node, float flexBasis); -float YGNodeStyleGetFlexBasis(YGNodeRef node); - -typedef enum YGEdge { - YGEdgeLeft, - YGEdgeTop, - YGEdgeRight, - YGEdgeBottom, - YGEdgeStart, - YGEdgeEnd, - YGEdgeHorizontal, - YGEdgeVertical, - YGEdgeAll, -} YGEdge; - -void YGNodeStyleSetPosition(YGNodeRef node, YGEdge edge, float position); -float YGNodeStyleGetPosition(YGNodeRef node, YGEdge edge); - -void YGNodeStyleSetMargin(YGNodeRef node, YGEdge edge, float margin); -float YGNodeStyleGetMargin(YGNodeRef node, YGEdge edge); - -void YGNodeStyleSetPadding(YGNodeRef node, YGEdge edge, float padding); -float YGNodeStyleGetPadding(YGNodeRef node, YGEdge edge); - -void YGNodeStyleSetBorder(YGNodeRef node, YGEdge edge, float border); -float YGNodeStyleGetBorder(YGNodeRef node, YGEdge edge); - -void YGNodeStyleSetWidth(YGNodeRef node, float width); -float YGNodeStyleGetWidth(YGNodeRef node); - -void YGNodeStyleSetHeight(YGNodeRef node, float height); -float YGNodeStyleGetHeight(YGNodeRef node); - -void YGNodeStyleSetMinWidth(YGNodeRef node, float minWidth); -float YGNodeStyleGetMinWidth(YGNodeRef node); - -void YGNodeStyleSetMinHeight(YGNodeRef node, float minHeight); -float YGNodeStyleGetMinHeight(YGNodeRef node); - -void YGNodeStyleSetMaxWidth(YGNodeRef node, float maxWidth); -float YGNodeStyleGetMaxWidth(YGNodeRef node); - -void YGNodeStyleSetMaxHeight(YGNodeRef node, float maxHeight); -float YGNodeStyleGetMaxHeight(YGNodeRef node); - -void YGNodeStyleSetAspectRatio(YGNodeRef node, float aspectRatio); -float YGNodeStyleGetAspectRatio(YGNodeRef node); -``` - -### Layout results - -Once you have set up a tree of nodes with styles you will want to get the result of a layout calculation. Call `YGNodeCalculateLayout` with the desired width and height or `YGUndefined` to perform the layout calculation. Once this function returns the results of the layout calculation is stored on each node. Traverse the tree and retrieve the values from each node. - -```c -void YGNodeCalculateLayout(YGNodeRef node, - float availableWidth, - float availableHeight, - YGDirection parentDirection); -float YGNodeLayoutGetLeft(YGNodeRef node); -float YGNodeLayoutGetTop(YGNodeRef node); -float YGNodeLayoutGetRight(YGNodeRef node); -float YGNodeLayoutGetBottom(YGNodeRef node); -float YGNodeLayoutGetWidth(YGNodeRef node); -float YGNodeLayoutGetHeight(YGNodeRef node); -YGDirection YGNodeLayoutGetDirection(YGNodeRef node); -``` - -### Custom measurements - -Certain nodes need the ability to measure themselves, the most common example is nodes which represent text. Text has an intrinsic size and requires measuring itself to determine that size. This is not something Yoga can do as it requires relying on the host system's text rendering engine. - -- Call `YGNodeMarkDirty` if a node with a custom text measurement function needs to be re-measured during the next layout pass. - -> A measure function can only be attached to a leaf node in the hierarchy. - -```c -typedef enum YGMeasureMode { - YGMeasureModeUndefined, - YGMeasureModeExactly, - YGMeasureModeAtMost, -} YGMeasureMode; - -typedef struct YGSize { - float width; - float height; -} YGSize; - -typedef YGSize (*YGMeasureFunc)(YGNodeRef node, - float width, - YGMeasureMode widthMode, - float height, - YGMeasureMode heightMode); - -void YGNodeSetMeasureFunc(YGNodeRef node, YGMeasureFunc measureFunc); -YGMeasureFunc YGNodeGetMeasureFunc(YGNodeRef node); - -void YGNodeMarkDirty(YGNodeRef node); -bool YGNodeIsDirty(YGNodeRef node); -``` - -### Context - -Context is important when integrating Yoga into another layout system. Context allows you to associate another object with a `YGNodeRef`. This context can then be retrieved from a `YGNodeRef` when for example its measure function is called. This is what enables Yoga to rely on the Android and iOS system implementations of text measurement in React Native. - -```c -void YGNodeSetContext(YGNodeRef node, void *context); -void *YGNodeGetContext(YGNodeRef node); -``` - -### Logging - -Yoga will by default log to stdout and stderr. You may however customize this to instead log to your own logger. - -```c -typedef enum YGLogLevel { - YGLogLevelError, - YGLogLevelWarn, - YGLogLevelInfo, - YGLogLevelDebug, - YGLogLevelVerbose, -} YGLogLevel; - -typedef int (*YGLogger)(YGLogLevel level, char *format, va_list args); -void YGSetLogger(YGLogger logger); -void YGLog(YGLogLevel level, char *message, ...); -``` - -### Experiments - -Yoga has the concept of experiments. An experiment is a feature which is not yet stable. To enable a feature use the following functions. Once a feature has been tested and is ready to be released as a stable API we will remove its feature flag. - -```c -typedef enum YGExperimentalFeature { - // Current experiments -} YGExperimentalFeature; - -void YGSetExperimentalFeatureEnabled(YGExperimentalFeature feature, - bool enabled); -bool YGIsExperimentalFeatureEnabled(YGExperimentalFeature feature); -``` - -### Printing - -Yoga has some hooks to print debug information while calculating layout. With the printing APIs you can add additional information to a node when it is printed. - -```c -typedef enum YGPrintOptions { - YGPrintOptionsLayout = 1, - YGPrintOptionsStyle = 2, - YGPrintOptionsChildren = 4, -} YGPrintOptions; - -typedef void (*YGPrintFunc)(YGNodeRef node); - -void YGNodeSetPrintFunc(YGNodeRef node, YGPrintFunc printFunc); -YGPrintFunc YGNodeGetPrintFunc(YGNodeRef node); - -void YGNodePrint(YGNodeRef node, YGPrintOptions options); -``` diff --git a/deps/yoga/Utils.cpp b/deps/yoga/Utils.cpp index 38b686c58..8864155bd 100644 --- a/deps/yoga/Utils.cpp +++ b/deps/yoga/Utils.cpp @@ -1,4 +1,4 @@ -/** +/* * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the LICENSE diff --git a/deps/yoga/Utils.h b/deps/yoga/Utils.h index 900ccb1be..899e832a6 100644 --- a/deps/yoga/Utils.h +++ b/deps/yoga/Utils.h @@ -1,4 +1,4 @@ -/** +/* * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the LICENSE @@ -30,7 +30,7 @@ // // - endOfLineIndex: Its the end index of the last flex item which was examined // and it may or may not be part of the current line(as it may be absolutely -// positioned or inculding it may have caused to overshoot availableInnerDim) +// positioned or including it may have caused to overshoot availableInnerDim) // // - relativeChildren: Maintain a vector of the child nodes that can shrink // and/or grow. @@ -71,8 +71,8 @@ YGFloatOptional YGFloatOptionalMax( float YGFloatMin(const float a, const float b); -// This custom float comparision function compares the array of float with -// YGFloatsEqual, as the default float comparision operator will not work(Look +// This custom float comparison function compares the array of float with +// YGFloatsEqual, as the default float comparison operator will not work(Look // at the comments of YGFloatsEqual function). template bool YGFloatArrayEqual( diff --git a/deps/yoga/YGConfig.cpp b/deps/yoga/YGConfig.cpp index 773ad24ab..4e805823d 100644 --- a/deps/yoga/YGConfig.cpp +++ b/deps/yoga/YGConfig.cpp @@ -1,4 +1,4 @@ -/** +/* * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the LICENSE diff --git a/deps/yoga/YGConfig.h b/deps/yoga/YGConfig.h index 311c15970..b1bce6120 100644 --- a/deps/yoga/YGConfig.h +++ b/deps/yoga/YGConfig.h @@ -1,11 +1,10 @@ -/** +/* * 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 "YGMarker.h" #include "Yoga-internal.h" #include "Yoga.h" @@ -44,7 +43,6 @@ public: std::array()> experimentalFeatures = {}; void* context = nullptr; - YGMarkerCallbacks markerCallbacks = {nullptr, nullptr}; YGConfig(YGLogger logger); void log(YGConfig*, YGNode*, YGLogLevel, void*, const char*, va_list); diff --git a/deps/yoga/YGEnums.cpp b/deps/yoga/YGEnums.cpp index ff4b13076..bf5844c57 100644 --- a/deps/yoga/YGEnums.cpp +++ b/deps/yoga/YGEnums.cpp @@ -1,4 +1,4 @@ -/** +/* * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the LICENSE diff --git a/deps/yoga/YGEnums.h b/deps/yoga/YGEnums.h index f06b0e045..b3c57fb83 100644 --- a/deps/yoga/YGEnums.h +++ b/deps/yoga/YGEnums.h @@ -1,4 +1,4 @@ -/** +/* * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the LICENSE diff --git a/deps/yoga/YGFloatOptional.h b/deps/yoga/YGFloatOptional.h index 7ca1fc121..60fcad99b 100644 --- a/deps/yoga/YGFloatOptional.h +++ b/deps/yoga/YGFloatOptional.h @@ -1,4 +1,4 @@ -/** +/* * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the LICENSE diff --git a/deps/yoga/YGLayout.cpp b/deps/yoga/YGLayout.cpp index 6f55d862c..d1144ea6f 100644 --- a/deps/yoga/YGLayout.cpp +++ b/deps/yoga/YGLayout.cpp @@ -1,4 +1,4 @@ -/** +/* * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the LICENSE diff --git a/deps/yoga/YGLayout.h b/deps/yoga/YGLayout.h index 0e559d742..74082a764 100644 --- a/deps/yoga/YGLayout.h +++ b/deps/yoga/YGLayout.h @@ -1,4 +1,4 @@ -/** +/* * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the LICENSE @@ -8,12 +8,9 @@ #include "YGFloatOptional.h" #include "Yoga-internal.h" -constexpr std::array kYGDefaultDimensionValues = { - {YGUndefined, YGUndefined}}; - struct YGLayout { std::array position = {}; - std::array dimensions = kYGDefaultDimensionValues; + std::array dimensions = {{YGUndefined, YGUndefined}}; std::array margin = {}; std::array border = {}; std::array padding = {}; @@ -33,7 +30,7 @@ struct YGLayout { uint32_t nextCachedMeasurementsIndex = 0; std::array cachedMeasurements = {}; - std::array measuredDimensions = kYGDefaultDimensionValues; + std::array measuredDimensions = {{YGUndefined, YGUndefined}}; YGCachedMeasurement cachedLayout = YGCachedMeasurement(); diff --git a/deps/yoga/YGMacros.h b/deps/yoga/YGMacros.h index 9c2989acb..d56f3aeb7 100644 --- a/deps/yoga/YGMacros.h +++ b/deps/yoga/YGMacros.h @@ -1,4 +1,4 @@ -/** +/* * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the LICENSE @@ -30,3 +30,15 @@ #define YG_ENUM_BEGIN(name) enum name #define YG_ENUM_END(name) name #endif + +#ifdef __GNUC__ +#define YG_DEPRECATED __attribute__((deprecated)) +#elif defined(_MSC_VER) +#define YG_DEPRECATED __declspec(deprecated) +#elif __cplusplus >= 201402L +#if defined(__has_cpp_attribute) +#if __has_cpp_attribute(deprecated) +#define YG_DEPRECATED [[deprecated]] +#endif +#endif +#endif diff --git a/deps/yoga/YGMarker.cpp b/deps/yoga/YGMarker.cpp deleted file mode 100644 index 21a8d1f6c..000000000 --- a/deps/yoga/YGMarker.cpp +++ /dev/null @@ -1,14 +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. - */ -#include "YGMarker.h" -#include "YGConfig.h" - -void YGConfigSetMarkerCallbacks( - YGConfigRef config, - YGMarkerCallbacks markerCallbacks) { - config->markerCallbacks = markerCallbacks; -} diff --git a/deps/yoga/YGMarker.h b/deps/yoga/YGMarker.h deleted file mode 100644 index 89b036843..000000000 --- a/deps/yoga/YGMarker.h +++ /dev/null @@ -1,90 +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 "YGMacros.h" - -YG_EXTERN_C_BEGIN - -typedef struct YGNode* YGNodeRef; -typedef struct YGConfig* YGConfigRef; - -typedef YG_ENUM_BEGIN(YGMarker){ - YGMarkerLayout, - YGMarkerMeasure, - YGMarkerBaselineFn, -} YG_ENUM_END(YGMarker); - -typedef struct { - int layouts; - int measures; - int maxMeasureCache; - int cachedLayouts; - int cachedMeasures; -} YGMarkerLayoutData; - -typedef struct { - bool _unused; -} YGMarkerNoData; - -typedef union { - YGMarkerLayoutData* layout; - YGMarkerNoData* noData; -} YGMarkerData; - -typedef struct { - // accepts marker type, a node ref, and marker data (depends on marker type) - // can return a handle or id that Yoga will pass to endMarker - void* (*startMarker)(YGMarker, YGNodeRef, YGMarkerData); - // accepts marker type, a node ref, marker data, and marker id as returned by - // startMarker - void (*endMarker)(YGMarker, YGNodeRef, YGMarkerData, void* id); -} YGMarkerCallbacks; - -void YGConfigSetMarkerCallbacks(YGConfigRef, YGMarkerCallbacks); - -YG_EXTERN_C_END - -#ifdef __cplusplus - -namespace facebook { -namespace yoga { -namespace marker { -namespace detail { - -template -struct MarkerData; - -template <> -struct MarkerData { - using type = YGMarkerLayoutData; - static type*& get(YGMarkerData& d) { return d.layout; } -}; - -struct NoMarkerData { - using type = YGMarkerNoData; - static type*& get(YGMarkerData& d) { return d.noData; } -}; - -template <> -struct MarkerData : NoMarkerData {}; - -template <> -struct MarkerData : NoMarkerData {}; - -} // namespace detail - -template -typename detail::MarkerData::type* data(YGMarkerData d) { - return detail::MarkerData::get(d); -} - -} // namespace marker -} // namespace yoga -} // namespace facebook - -#endif // __cplusplus diff --git a/deps/yoga/YGNode.cpp b/deps/yoga/YGNode.cpp index 81a4216eb..8941487fb 100644 --- a/deps/yoga/YGNode.cpp +++ b/deps/yoga/YGNode.cpp @@ -1,4 +1,4 @@ -/** +/* * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the LICENSE diff --git a/deps/yoga/YGNode.h b/deps/yoga/YGNode.h index e5f1da3ca..cc11cc88d 100644 --- a/deps/yoga/YGNode.h +++ b/deps/yoga/YGNode.h @@ -1,4 +1,4 @@ -/** +/* * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the LICENSE @@ -11,6 +11,7 @@ #include "YGConfig.h" #include "YGLayout.h" #include "YGStyle.h" +#include "YGMacros.h" #include "Yoga-internal.h" YGConfigRef YGConfigGetDefault(); @@ -272,7 +273,7 @@ public: // TODO: rvalue override for setChildren - void setConfig(YGConfigRef config) { config_ = config; } + YG_DEPRECATED void setConfig(YGConfigRef config) { config_ = config; } void setDirty(bool isDirty); void setLayoutLastOwnerDirection(YGDirection direction); diff --git a/deps/yoga/YGNodePrint.cpp b/deps/yoga/YGNodePrint.cpp index 301e72a2e..f91d03746 100644 --- a/deps/yoga/YGNodePrint.cpp +++ b/deps/yoga/YGNodePrint.cpp @@ -1,4 +1,4 @@ -/** +/* * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the LICENSE diff --git a/deps/yoga/YGNodePrint.h b/deps/yoga/YGNodePrint.h index 13cf367b5..8df30e2cc 100644 --- a/deps/yoga/YGNodePrint.h +++ b/deps/yoga/YGNodePrint.h @@ -1,4 +1,4 @@ -/** +/* * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the LICENSE diff --git a/deps/yoga/YGStyle.cpp b/deps/yoga/YGStyle.cpp index 6672c81fa..a4a7a0473 100644 --- a/deps/yoga/YGStyle.cpp +++ b/deps/yoga/YGStyle.cpp @@ -1,4 +1,4 @@ -/** +/* * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the LICENSE diff --git a/deps/yoga/YGStyle.h b/deps/yoga/YGStyle.h index 77c7e0386..ce3816040 100644 --- a/deps/yoga/YGStyle.h +++ b/deps/yoga/YGStyle.h @@ -1,4 +1,4 @@ -/** +/* * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the LICENSE @@ -102,6 +102,11 @@ public: } }; +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wbitfield-constant-conversion" +#endif + YGStyle() : direction_(YGDirectionInherit), flexDirection_(YGFlexDirectionColumn), @@ -113,6 +118,11 @@ public: flexWrap_(YGWrapNoWrap), overflow_(YGOverflowVisible), display_(YGDisplayFlex) {} + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + ~YGStyle() = default; static constexpr int directionBit = 0; diff --git a/deps/yoga/YGValue.cpp b/deps/yoga/YGValue.cpp index fcdd0c693..995f21139 100644 --- a/deps/yoga/YGValue.cpp +++ b/deps/yoga/YGValue.cpp @@ -1,4 +1,4 @@ -/** +/* * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the LICENSE diff --git a/deps/yoga/YGValue.h b/deps/yoga/YGValue.h index 170047ea5..0405bc628 100644 --- a/deps/yoga/YGValue.h +++ b/deps/yoga/YGValue.h @@ -1,4 +1,4 @@ -/** +/* * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the LICENSE diff --git a/deps/yoga/Yoga-internal.h b/deps/yoga/Yoga-internal.h index 4d32a96bc..e08027da5 100644 --- a/deps/yoga/Yoga-internal.h +++ b/deps/yoga/Yoga-internal.h @@ -1,4 +1,4 @@ -/** +/* * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the LICENSE @@ -16,12 +16,6 @@ using YGVector = std::vector; YG_EXTERN_C_BEGIN -WIN_EXPORT float YGRoundValueToPixelGrid( - const float value, - const float pointScaleFactor, - const bool forceCeil, - const bool forceFloor); - void YGNodeCalculateLayoutWithContext( YGNodeRef node, float availableWidth, diff --git a/deps/yoga/Yoga.cpp b/deps/yoga/Yoga.cpp index 93ad4148c..e87fa3251 100644 --- a/deps/yoga/Yoga.cpp +++ b/deps/yoga/Yoga.cpp @@ -1,4 +1,4 @@ -/** +/* * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the LICENSE @@ -15,7 +15,7 @@ #include "YGNodePrint.h" #include "Yoga-internal.h" #include "event/event.h" -#include "instrumentation.h" +#include "internal/experiments-inl.h" #ifdef _MSC_VER #include @@ -213,9 +213,7 @@ WIN_EXPORT YGNodeRef YGNodeNewWithConfig(const YGConfigRef config) { const YGNodeRef node = new YGNode{config}; YGAssertWithConfig( config, node != nullptr, "Could not allocate memory for node"); -#ifdef YG_ENABLE_EVENTS Event::publish(node, {config}); -#endif return node; } @@ -235,9 +233,7 @@ YGNodeRef YGNodeClone(YGNodeRef oldNode) { oldNode->getConfig(), node != nullptr, "Could not allocate memory for node"); -#ifdef YG_ENABLE_EVENTS Event::publish(node, {node->getConfig()}); -#endif node->setOwner(nullptr); return node; } @@ -253,7 +249,11 @@ static YGConfigRef YGConfigClone(const YGConfig& oldConfig) { } static YGNodeRef YGNodeDeepClone(YGNodeRef oldNode) { - YGNodeRef node = YGNodeClone(oldNode); + auto config = YGConfigClone(*oldNode->getConfig()); + auto node = new YGNode{*oldNode, config}; + node->setOwner(nullptr); + Event::publish(node, {node->getConfig()}); + YGVector vec = YGVector(); vec.reserve(oldNode->getChildren().size()); YGNodeRef childNode = nullptr; @@ -264,10 +264,6 @@ static YGNodeRef YGNodeDeepClone(YGNodeRef oldNode) { } node->setChildren(vec); - if (oldNode->getConfig() != nullptr) { - node->setConfig(YGConfigClone(*(oldNode->getConfig()))); - } - return node; } @@ -284,9 +280,7 @@ void YGNodeFree(const YGNodeRef node) { } node->clearChildren(); -#ifdef YG_ENABLE_EVENTS Event::publish(node, {node->getConfig()}); -#endif delete node; } @@ -945,10 +939,12 @@ bool YGLayoutNodeInternal( const float ownerWidth, const float ownerHeight, const bool performLayout, - const char* reason, + const LayoutPassReason reason, const YGConfigRef config, - YGMarkerLayoutData& layoutMarkerData, - void* const layoutContext); + LayoutData& layoutMarkerData, + void* const layoutContext, + const uint32_t depth, + const uint32_t generationCount); #ifdef DEBUG static void YGNodePrintInternal( @@ -1001,12 +997,16 @@ static inline YGAlign YGNodeAlignItem(const YGNode* node, const YGNode* child) { static float YGBaseline(const YGNodeRef node, void* layoutContext) { if (node->hasBaselineFunc()) { - const float baseline = marker::MarkerSection::wrap( - node, - &YGNode::baseline, + + Event::publish(node); + + const float baseline = node->baseline( node->getLayout().measuredDimensions[YGDimensionWidth], node->getLayout().measuredDimensions[YGDimensionHeight], layoutContext); + + Event::publish(node); + YGAssertWithNode( node, !YGFloatIsUndefined(baseline), @@ -1191,8 +1191,10 @@ static void YGNodeComputeFlexBasisForChild( const YGMeasureMode heightMode, const YGDirection direction, const YGConfigRef config, - YGMarkerLayoutData& layoutMarkerData, - void* const layoutContext) { + LayoutData& layoutMarkerData, + void* const layoutContext, + const uint32_t depth, + const uint32_t generationCount) { const YGFlexDirection mainAxis = YGResolveFlexDirection(node->getStyle().flexDirection(), direction); const bool isMainAxisRow = YGFlexDirectionIsRow(mainAxis); @@ -1215,8 +1217,7 @@ static void YGNodeComputeFlexBasisForChild( if (child->getLayout().computedFlexBasis.isUndefined() || (YGConfigIsExperimentalFeatureEnabled( child->getConfig(), YGExperimentalFeatureWebFlexBasis) && - child->getLayout().computedFlexBasisGeneration != - gCurrentGenerationCount)) { + child->getLayout().computedFlexBasisGeneration != generationCount)) { const YGFloatOptional paddingAndBorder = YGFloatOptional( YGNodePaddingAndBorderForAxis(child, mainAxis, ownerWidth)); child->setLayoutComputedFlexBasis( @@ -1364,16 +1365,18 @@ static void YGNodeComputeFlexBasisForChild( ownerWidth, ownerHeight, false, - "measure", + LayoutPassReason::kMeasureChild, config, layoutMarkerData, - layoutContext); + layoutContext, + depth, + generationCount); child->setLayoutComputedFlexBasis(YGFloatOptional(YGFloatMax( child->getLayout().measuredDimensions[dim[mainAxis]], YGNodePaddingAndBorderForAxis(child, mainAxis, ownerWidth)))); } - child->setLayoutComputedFlexBasisGeneration(gCurrentGenerationCount); + child->setLayoutComputedFlexBasisGeneration(generationCount); } static void YGNodeAbsoluteLayoutChild( @@ -1384,8 +1387,10 @@ static void YGNodeAbsoluteLayoutChild( const float height, const YGDirection direction, const YGConfigRef config, - YGMarkerLayoutData& layoutMarkerData, - void* const layoutContext) { + LayoutData& layoutMarkerData, + void* const layoutContext, + const uint32_t depth, + const uint32_t generationCount) { const YGFlexDirection mainAxis = YGResolveFlexDirection(node->getStyle().flexDirection(), direction); const YGFlexDirection crossAxis = YGFlexDirectionCross(mainAxis, direction); @@ -1488,10 +1493,12 @@ static void YGNodeAbsoluteLayoutChild( childWidth, childHeight, false, - "abs-measure", + LayoutPassReason::kAbsMeasureChild, config, layoutMarkerData, - layoutContext); + layoutContext, + depth, + generationCount); childWidth = child->getLayout().measuredDimensions[YGDimensionWidth] + child->getMarginForAxis(YGFlexDirectionRow, width).unwrap(); childHeight = child->getLayout().measuredDimensions[YGDimensionHeight] + @@ -1508,10 +1515,12 @@ static void YGNodeAbsoluteLayoutChild( childWidth, childHeight, true, - "abs-layout", + LayoutPassReason::kAbsLayout, config, layoutMarkerData, - layoutContext); + layoutContext, + depth, + generationCount); if (child->isTrailingPosDefined(mainAxis) && !child->isLeadingPositionDefined(mainAxis)) { @@ -1579,7 +1588,9 @@ static void YGNodeWithMeasureFuncSetMeasuredDimensions( const YGMeasureMode heightMeasureMode, const float ownerWidth, const float ownerHeight, - void* const layoutContext) { + LayoutData& layoutMarkerData, + void* const layoutContext, + const LayoutPassReason reason) { YGAssertWithNode( node, node->hasMeasureFunc(), @@ -1623,16 +1634,38 @@ static void YGNodeWithMeasureFuncSetMeasuredDimensions( ownerWidth), YGDimensionHeight); } else { + Event::publish(node); + // Measure the text under the current constraints. - const YGSize measuredSize = marker::MarkerSection::wrap( - node, - &YGNode::measure, + const YGSize measuredSize = node->measure( innerWidth, widthMeasureMode, innerHeight, heightMeasureMode, layoutContext); + layoutMarkerData.measureCallbacks += 1; + + Event::publish( + node, + {layoutContext, + innerWidth, + widthMeasureMode, + innerHeight, + heightMeasureMode, + measuredSize.width, + measuredSize.height, + reason}); + + if (internal::isEnabled(internal::Experiment::kDoubleMeasureCallbacks)) { + node->measure( + innerWidth, + widthMeasureMode, + innerHeight, + heightMeasureMode, + layoutContext); + } + node->setLayoutMeasuredDimension( YGNodeBoundAxis( node, @@ -1814,8 +1847,10 @@ static float YGNodeComputeFlexBasisForChildren( YGFlexDirection mainAxis, const YGConfigRef config, bool performLayout, - YGMarkerLayoutData& layoutMarkerData, - void* const layoutContext) { + LayoutData& layoutMarkerData, + void* const layoutContext, + const uint32_t depth, + const uint32_t generationCount) { float totalOuterFlexBasis = 0.0f; YGNodeRef singleFlexChild = nullptr; YGVector children = node->getChildren(); @@ -1866,7 +1901,7 @@ static float YGNodeComputeFlexBasisForChildren( continue; } if (child == singleFlexChild) { - child->setLayoutComputedFlexBasisGeneration(gCurrentGenerationCount); + child->setLayoutComputedFlexBasisGeneration(generationCount); child->setLayoutComputedFlexBasis(YGFloatOptional(0)); } else { YGNodeComputeFlexBasisForChild( @@ -1881,7 +1916,9 @@ static float YGNodeComputeFlexBasisForChildren( direction, config, layoutMarkerData, - layoutContext); + layoutContext, + depth, + generationCount); } totalOuterFlexBasis += @@ -1994,8 +2031,10 @@ static float YGDistributeFreeSpaceSecondPass( const YGMeasureMode measureModeCrossDim, const bool performLayout, const YGConfigRef config, - YGMarkerLayoutData& layoutMarkerData, - void* const layoutContext) { + LayoutData& layoutMarkerData, + void* const layoutContext, + const uint32_t depth, + const uint32_t generationCount) { float childFlexBasis = 0; float flexShrinkScaledFactor = 0; float flexGrowFactor = 0; @@ -2158,10 +2197,12 @@ static float YGDistributeFreeSpaceSecondPass( availableInnerWidth, availableInnerHeight, performLayout && !requiresStretchLayout, - "flex", + LayoutPassReason::kFlex, config, layoutMarkerData, - layoutContext); + layoutContext, + depth, + generationCount); node->setLayoutHadOverflow( node->getLayout().hadOverflow | currentRelativeChild->getLayout().hadOverflow); @@ -2291,8 +2332,10 @@ static void YGResolveFlexibleLength( const YGMeasureMode measureModeCrossDim, const bool performLayout, const YGConfigRef config, - YGMarkerLayoutData& layoutMarkerData, - void* const layoutContext) { + LayoutData& layoutMarkerData, + void* const layoutContext, + const uint32_t depth, + const uint32_t generationCount) { const float originalFreeSpace = collectedFlexItemsValues.remainingFreeSpace; // First pass: detect the flex items whose min/max constraints trigger YGDistributeFreeSpaceFirstPass( @@ -2318,7 +2361,9 @@ static void YGResolveFlexibleLength( performLayout, config, layoutMarkerData, - layoutContext); + layoutContext, + depth, + generationCount); collectedFlexItemsValues.remainingFreeSpace = originalFreeSpace - distributedFreeSpace; @@ -2617,8 +2662,11 @@ static void YGNodelayoutImpl( const float ownerHeight, const bool performLayout, const YGConfigRef config, - YGMarkerLayoutData& layoutMarkerData, - void* const layoutContext) { + LayoutData& layoutMarkerData, + void* const layoutContext, + const uint32_t depth, + const uint32_t generationCount, + const LayoutPassReason reason) { YGAssertWithNode( node, YGFloatIsUndefined(availableWidth) @@ -2686,7 +2734,9 @@ static void YGNodelayoutImpl( heightMeasureMode, ownerWidth, ownerHeight, - layoutContext); + layoutMarkerData, + layoutContext, + reason); return; } @@ -2798,7 +2848,9 @@ static void YGNodelayoutImpl( config, performLayout, layoutMarkerData, - layoutContext); + layoutContext, + depth, + generationCount); const bool flexBasisOverflows = measureModeMainDim == YGMeasureModeUndefined ? false @@ -2859,8 +2911,11 @@ static void YGNodelayoutImpl( availableInnerMainDim = maxInnerMainDim; } else { if (!node->getConfig()->useLegacyStretchBehaviour && - (collectedFlexItemsValues.totalFlexGrowFactors == 0 || - node->resolveFlexGrow() == 0)) { + ((YGFloatIsUndefined( + collectedFlexItemsValues.totalFlexGrowFactors) && + collectedFlexItemsValues.totalFlexGrowFactors == 0) || + (YGFloatIsUndefined(node->resolveFlexGrow()) && + node->resolveFlexGrow() == 0))) { // If we don't have any children to flex or we can't flex the node // itself, space we've used is all space we need. Root node also // should be shrunk to minimum @@ -2903,7 +2958,9 @@ static void YGNodelayoutImpl( performLayout, config, layoutMarkerData, - layoutContext); + layoutContext, + depth, + generationCount); } node->setLayoutHadOverflow( @@ -3074,10 +3131,12 @@ static void YGNodelayoutImpl( availableInnerWidth, availableInnerHeight, true, - "stretch", + LayoutPassReason::kStretch, config, layoutMarkerData, - layoutContext); + layoutContext, + depth, + generationCount); } } else { const float remainingCrossDim = containerCrossAxis - @@ -3282,10 +3341,12 @@ static void YGNodelayoutImpl( availableInnerWidth, availableInnerHeight, true, - "multiline-stretch", + LayoutPassReason::kMultilineStretch, config, layoutMarkerData, - layoutContext); + layoutContext, + depth, + generationCount); } } break; @@ -3425,7 +3486,9 @@ static void YGNodelayoutImpl( direction, config, layoutMarkerData, - layoutContext); + layoutContext, + depth, + generationCount); } // STEP 11: SETTING TRAILING POSITIONS FOR CHILDREN @@ -3453,7 +3516,6 @@ static void YGNodelayoutImpl( } } -uint32_t gDepth = 0; bool gPrintChanges = false; bool gPrintSkips = false; @@ -3656,19 +3718,18 @@ bool YGLayoutNodeInternal( const float ownerWidth, const float ownerHeight, const bool performLayout, - const char* reason, + const LayoutPassReason reason, const YGConfigRef config, - YGMarkerLayoutData& layoutMarkerData, - void* const layoutContext) { -#ifdef YG_ENABLE_EVENTS - Event::publish(node); -#endif + LayoutData& layoutMarkerData, + void* const layoutContext, + uint32_t depth, + const uint32_t generationCount) { YGLayout* layout = &node->getLayout(); - gDepth++; + depth++; const bool needToVisitNode = - (node->isDirty() && layout->generationCount != gCurrentGenerationCount) || + (node->isDirty() && layout->generationCount != generationCount) || layout->lastOwnerDirection != ownerDirection; if (needToVisitNode) { @@ -3770,8 +3831,8 @@ bool YGLayoutNodeInternal( YGLogLevelVerbose, nullptr, "%s%d.{[skipped] ", - YGSpacer(gDepth), - gDepth); + YGSpacer(depth), + depth); node->print(layoutContext); Log::log( node, @@ -3784,7 +3845,7 @@ bool YGLayoutNodeInternal( availableHeight, cachedResults->computedWidth, cachedResults->computedHeight, - reason); + LayoutPassReasonToString(reason)); } } else { if (gPrintChanges) { @@ -3793,8 +3854,8 @@ bool YGLayoutNodeInternal( YGLogLevelVerbose, nullptr, "%s%d.{%s", - YGSpacer(gDepth), - gDepth, + YGSpacer(depth), + depth, needToVisitNode ? "*" : ""); node->print(layoutContext); Log::log( @@ -3806,7 +3867,7 @@ bool YGLayoutNodeInternal( YGMeasureModeName(heightMeasureMode, performLayout), availableWidth, availableHeight, - reason); + LayoutPassReasonToString(reason)); } YGNodelayoutImpl( @@ -3821,7 +3882,10 @@ bool YGLayoutNodeInternal( performLayout, config, layoutMarkerData, - layoutContext); + layoutContext, + depth, + generationCount, + reason); if (gPrintChanges) { Log::log( @@ -3829,8 +3893,8 @@ bool YGLayoutNodeInternal( YGLogLevelVerbose, nullptr, "%s%d.}%s", - YGSpacer(gDepth), - gDepth, + YGSpacer(depth), + depth, needToVisitNode ? "*" : ""); node->print(layoutContext); Log::log( @@ -3842,7 +3906,7 @@ bool YGLayoutNodeInternal( YGMeasureModeName(heightMeasureMode, performLayout), layout->measuredDimensions[YGDimensionWidth], layout->measuredDimensions[YGDimensionHeight], - reason); + LayoutPassReasonToString(reason)); } layout->lastOwnerDirection = ownerDirection; @@ -3894,8 +3958,19 @@ bool YGLayoutNodeInternal( node->setDirty(false); } - gDepth--; - layout->generationCount = gCurrentGenerationCount; + layout->generationCount = generationCount; + + LayoutType layoutType; + if (performLayout) { + layoutType = !needToVisitNode && cachedResults == &layout->cachedLayout + ? LayoutType::kCachedLayout + : LayoutType::kLayout; + } else { + layoutType = cachedResults != nullptr ? LayoutType::kCachedMeasure + : LayoutType::kMeasure; + } + Event::publish(node, {layoutType, layoutContext}); + return (needToVisitNode || cachedResults == nullptr); } @@ -4003,12 +4078,8 @@ void YGNodeCalculateLayoutWithContext( const YGDirection ownerDirection, void* layoutContext) { -#ifdef YG_ENABLE_EVENTS - Event::publish(node); -#endif - // unique pointer to allow ending the marker early - std::unique_ptr> marker{ - new marker::MarkerSection{node}}; + Event::publish(node, {layoutContext}); + LayoutData markerData = {}; // Increment the generation count. This will force the recursive routine to // visit all dirty nodes at least once. Subsequent visits will be skipped if @@ -4065,10 +4136,12 @@ void YGNodeCalculateLayoutWithContext( ownerWidth, ownerHeight, true, - "initial", + LayoutPassReason::kInitial, node->getConfig(), - marker->data, - layoutContext)) { + markerData, + layoutContext, + 0, // tree root + gCurrentGenerationCount)) { node->setPosition( node->getLayout().direction, ownerWidth, ownerHeight, ownerWidth); YGRoundToPixelGrid(node, node->getConfig()->pointScaleFactor, 0.0f, 0.0f); @@ -4084,12 +4157,7 @@ void YGNodeCalculateLayoutWithContext( #endif } - // end marker here - marker = nullptr; - -#ifdef YG_ENABLE_EVENTS - Event::publish(node); -#endif + Event::publish(node, {layoutContext, &markerData}); // We want to get rid off `useLegacyStretchBehaviour` from YGConfig. But we // aren't sure whether client's of yoga have gotten rid off this flag or not. @@ -4107,7 +4175,7 @@ void YGNodeCalculateLayoutWithContext( gCurrentGenerationCount++; // Rerun the layout, and calculate the diff unsetUseLegacyFlagRecursively(nodeWithoutLegacyFlag); - YGMarkerLayoutData layoutMarkerData; + LayoutData layoutMarkerData = {}; if (YGLayoutNodeInternal( nodeWithoutLegacyFlag, width, @@ -4118,10 +4186,12 @@ void YGNodeCalculateLayoutWithContext( ownerWidth, ownerHeight, true, - "initial", + LayoutPassReason::kInitial, nodeWithoutLegacyFlag->getConfig(), layoutMarkerData, - layoutContext)) { + layoutContext, + 0, // tree root + gCurrentGenerationCount)) { nodeWithoutLegacyFlag->setPosition( nodeWithoutLegacyFlag->getLayout().direction, ownerWidth, diff --git a/deps/yoga/Yoga.h b/deps/yoga/Yoga.h index a9dc01dca..493e556cb 100644 --- a/deps/yoga/Yoga.h +++ b/deps/yoga/Yoga.h @@ -1,4 +1,4 @@ -/** +/* * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the LICENSE @@ -330,7 +330,7 @@ WIN_EXPORT bool YGConfigIsExperimentalFeatureEnabled( YGConfigRef config, YGExperimentalFeature feature); -// Using the web defaults is the prefered configuration for new projects. Usage +// 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); diff --git a/deps/yoga/event/event.cpp b/deps/yoga/event/event.cpp index e2fe3588f..326214fc4 100644 --- a/deps/yoga/event/event.cpp +++ b/deps/yoga/event/event.cpp @@ -1,55 +1,82 @@ -/** +/* * 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. */ #include "event.h" +#include #include #include -#include - -#include namespace facebook { namespace yoga { -namespace { - -std::mutex& eventSubscribersMutex() { - static std::mutex subscribersMutex; - return subscribersMutex; +const char* LayoutPassReasonToString(const LayoutPassReason value) { + switch (value) { + case LayoutPassReason::kInitial: + return "initial"; + case LayoutPassReason::kMeasureChild: + return "measure"; + case LayoutPassReason::kAbsMeasureChild: + return "abs_measure"; + case LayoutPassReason::kFlex: + return "flex"; + case LayoutPassReason::kAbsLayout: + return "abs_layout"; + case LayoutPassReason::kStretch: + return "stretch"; + case LayoutPassReason::kMultilineStretch: + return "multiline_stretch"; + default: + return "unknown"; + } } -std::shared_ptr& eventSubscribers() { - static auto subscribers = std::make_shared(); - return subscribers; +namespace { + +struct Node { + std::function subscriber = nullptr; + Node* next = nullptr; + + Node(std::function&& subscriber) + : subscriber{std::move(subscriber)} {} +}; + +std::atomic subscribers{nullptr}; + +Node* push(Node* newHead) { + Node* oldHead; + do { + oldHead = subscribers.load(std::memory_order_relaxed); + if (newHead != nullptr) { + newHead->next = oldHead; + } + } while (!subscribers.compare_exchange_weak( + oldHead, newHead, std::memory_order_release, std::memory_order_relaxed)); + return oldHead; } } // namespace void Event::reset() { - eventSubscribers() = std::make_shared(); + auto head = push(nullptr); + while (head != nullptr) { + auto current = head; + head = head->next; + delete current; + } } void Event::subscribe(std::function&& subscriber) { - std::lock_guard guard(eventSubscribersMutex()); - eventSubscribers() = - std::make_shared(*eventSubscribers()); - eventSubscribers()->push_back(subscriber); + push(new Node{std::move(subscriber)}); } void Event::publish(const YGNode& node, Type eventType, const Data& eventData) { - std::shared_ptr subscribers; - { - std::lock_guard guard(eventSubscribersMutex()); - subscribers = eventSubscribers(); - } - - for (auto& subscriber : *subscribers) { - if (subscriber) { - subscriber(node, eventType, eventData); - } + for (auto subscriber = subscribers.load(std::memory_order_relaxed); + subscriber != nullptr; + subscriber = subscriber->next) { + subscriber->subscriber(node, eventType, eventData); } } diff --git a/deps/yoga/event/event.h b/deps/yoga/event/event.h index 578d2f3a6..618574e8d 100644 --- a/deps/yoga/event/event.h +++ b/deps/yoga/event/event.h @@ -1,4 +1,4 @@ -/** +/* * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the LICENSE @@ -8,6 +8,7 @@ #include #include +#include struct YGConfig; struct YGNode; @@ -15,13 +16,45 @@ struct YGNode; namespace facebook { namespace yoga { +enum struct LayoutType : int { + kLayout = 0, + kMeasure = 1, + kCachedLayout = 2, + kCachedMeasure = 3 +}; + +struct LayoutData { + int layouts; + int measures; + int maxMeasureCache; + int cachedLayouts; + int cachedMeasures; + int measureCallbacks; +}; + +enum struct LayoutPassReason : int { + kInitial = 0, + kMeasureChild = 1, + kAbsMeasureChild = 2, + kFlex = 3, + kAbsLayout = 4, + kStretch = 5, + kMultilineStretch = 6 +}; + +const char* LayoutPassReasonToString(const LayoutPassReason value); + struct Event { enum Type { NodeAllocation, NodeDeallocation, NodeLayout, LayoutPassStart, - LayoutPassEnd + LayoutPassEnd, + MeasureCallbackStart, + MeasureCallbackEnd, + NodeBaselineStart, + NodeBaselineEnd, }; class Data; using Subscriber = void(const YGNode&, Type, Data); @@ -49,7 +82,9 @@ struct Event { template static void publish(const YGNode& node, const TypedData& eventData = {}) { +#ifdef YG_ENABLE_EVENTS publish(node, E, Data{eventData}); +#endif } template @@ -71,5 +106,34 @@ struct Event::TypedData { YGConfig* config; }; +template <> +struct Event::TypedData { + void* layoutContext; +}; + +template <> +struct Event::TypedData { + void* layoutContext; + LayoutData* layoutData; +}; + +template <> +struct Event::TypedData { + void* layoutContext; + float width; + YGMeasureMode widthMeasureMode; + float height; + YGMeasureMode heightMeasureMode; + float measuredWidth; + float measuredHeight; + const LayoutPassReason reason; +}; + +template <> +struct Event::TypedData { + LayoutType layoutType; + void* layoutContext; +}; + } // namespace yoga } // namespace facebook diff --git a/deps/yoga/instrumentation.h b/deps/yoga/instrumentation.h deleted file mode 100644 index b8691c186..000000000 --- a/deps/yoga/instrumentation.h +++ /dev/null @@ -1,63 +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. - */ -#include "YGConfig.h" -#include "YGMarker.h" -#include "YGNode.h" - -namespace facebook { -namespace yoga { -namespace marker { - -template -class MarkerSection { -private: - using Data = detail::MarkerData; - -public: - MarkerSection(YGNodeRef node) : MarkerSection{node, node->getConfig()} {} - ~MarkerSection() { - if (endMarker_) { - endMarker_(MarkerType, node_, markerData(&data), userData_); - } - } - - typename Data::type data = {}; - - template - static Ret wrap( - YGNodeRef node, - Ret (YGNode::*method)(Args...), - Args... args) { - MarkerSection section{node}; - return (node->*method)(std::forward(args)...); - } - -private: - decltype(YGMarkerCallbacks{}.endMarker) endMarker_; - YGNodeRef node_; - void* userData_; - - MarkerSection(YGNodeRef node, YGConfigRef config) - : MarkerSection{node, config ? &config->markerCallbacks : nullptr} {} - MarkerSection(YGNodeRef node, YGMarkerCallbacks* callbacks) - : endMarker_{callbacks ? callbacks->endMarker : nullptr}, - node_{node}, - userData_{ - callbacks && callbacks->startMarker - ? callbacks->startMarker(MarkerType, node, markerData(&data)) - : nullptr} {} - - static YGMarkerData markerData(typename Data::type* d) { - YGMarkerData markerData = {}; - Data::get(markerData) = d; - return markerData; - } -}; - -} // namespace marker -} // namespace yoga -} // namespace facebook diff --git a/deps/yoga/internal/experiments-inl.h b/deps/yoga/internal/experiments-inl.h new file mode 100644 index 000000000..ebbeccbc5 --- /dev/null +++ b/deps/yoga/internal/experiments-inl.h @@ -0,0 +1,31 @@ +/* + * 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 "experiments.h" + +#include + +namespace facebook { +namespace yoga { +namespace internal { + +namespace detail { +extern std::bitset enabledExperiments; +} // namespace detail + +inline bool isEnabled(Experiment experiment) { + return detail::enabledExperiments.test(static_cast(experiment)); +} + +inline void disableAllExperiments() { + detail::enabledExperiments = 0; +} + +} // namespace internal +} // namespace yoga +} // namespace facebook diff --git a/deps/yoga/internal/experiments.cpp b/deps/yoga/internal/experiments.cpp new file mode 100644 index 000000000..4b67eee57 --- /dev/null +++ b/deps/yoga/internal/experiments.cpp @@ -0,0 +1,37 @@ +/* + * 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. + */ +#include "experiments.h" +#include "experiments-inl.h" + +namespace facebook { +namespace yoga { +namespace internal { + +namespace detail { + +std::bitset enabledExperiments = 0; + +} // namespace detail + +void enable(Experiment experiment) { + detail::enabledExperiments.set(static_cast(experiment)); +} + +void disable(Experiment experiment) { + detail::enabledExperiments.reset(static_cast(experiment)); +} + +bool toggle(Experiment experiment) { + auto bit = static_cast(experiment); + auto previousState = detail::enabledExperiments.test(bit); + detail::enabledExperiments.flip(bit); + return previousState; +} + +} // namespace internal +} // namespace yoga +} // namespace facebook diff --git a/deps/yoga/internal/experiments.h b/deps/yoga/internal/experiments.h new file mode 100644 index 000000000..7fd4cb37c --- /dev/null +++ b/deps/yoga/internal/experiments.h @@ -0,0 +1,25 @@ +/* + * 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 + +namespace facebook { +namespace yoga { +namespace internal { + +enum struct Experiment : size_t { + kDoubleMeasureCallbacks, +}; + +void enable(Experiment); +void disable(Experiment); +bool toggle(Experiment); + +} // namespace internal +} // namespace yoga +} // namespace facebook diff --git a/deps/yoga/log.cpp b/deps/yoga/log.cpp index 62b3d4f05..45e5f7b16 100644 --- a/deps/yoga/log.cpp +++ b/deps/yoga/log.cpp @@ -1,4 +1,4 @@ -/** +/* * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the LICENSE diff --git a/deps/yoga/log.h b/deps/yoga/log.h index f25ee1a2b..effe23b5b 100644 --- a/deps/yoga/log.h +++ b/deps/yoga/log.h @@ -1,4 +1,4 @@ -/** +/* * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the LICENSE diff --git a/tsconfig.json b/tsconfig.json index ded6f1b57..8db180b56 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -14,8 +14,8 @@ "outDir": "./dist" /* Redirect output structure to the directory. */, // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ // "composite": true, /* Enable project compilation */ - // "incremental": true, /* Enable incremental compilation */ - // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ + "incremental": true, /* Enable incremental compilation */ + "tsBuildInfoFile": ".cache/tsconfig.tsbuildinfo", /* Specify file to store incremental compilation information */ // "removeComments": true, /* Do not emit comments to output. */ // "noEmit": true, /* Do not emit outputs. */ // "importHelpers": true, /* Import emit helpers from 'tslib'. */