2019-06-06 19:36:56 -07:00
|
|
|
/*
|
2021-12-30 15:08:43 -08:00
|
|
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
2017-12-19 11:18:00 -08:00
|
|
|
*
|
2019-10-15 10:30:08 -07:00
|
|
|
* This source code is licensed under the MIT license found in the
|
|
|
|
* LICENSE file in the root directory of this source tree.
|
2017-12-19 11:18:00 -08:00
|
|
|
*/
|
2019-10-15 10:30:08 -07:00
|
|
|
|
2017-12-19 11:18:00 -08:00
|
|
|
#pragma once
|
2020-04-14 16:39:32 -07:00
|
|
|
|
2023-09-13 20:12:55 -07:00
|
|
|
#include <cstdint>
|
2024-03-04 02:28:02 -08:00
|
|
|
#include <cstdio>
|
C++ Cleanup 8/N: Yoga-internal (#1355)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1355
X-link: https://github.com/facebook/react-native/pull/39198
## This diff
This splits up `Yoga-internal.h` which has become a grab bag. The actual header is left, with the purpose of being a private C ABI for bindings, but everything else is moved to a place more appropriate or removed.
A few notes:
1. `yoga::isUndefined` is replaced with `std::isnan` to avoid a layer of indirection (we will never be able to change its representation anyway). Internal usages of `YGFloatIsUndefined` are also replaced with `std::isnan` since the previous being at a library boundary means I'm not sure it can be inlined/.
2. `leading`, `trailing` arrays are factored into proper functions
3. `Values` is replaced entirely with `std::array`, since most of it was unused.
## This stack
The organization of the C++ internals of Yoga are in need of attention.
1. Some of the C++ internals are namespaced, but others not.
2. Some of the namespaces include `detail`, but are meant to be used outside of the translation unit (FB Clang Tidy rules warn on any usage of these)
2. Most of the files are in a flat hierarchy, except for event tracing in its own folder
3. Some files and functions begin with YG, others don’t
4. Some functions are uppercase, others are not
5. Almost all of the interesting logic is in Yoga.cpp, and the file is too large to reason about
6. There are multiple grab bag files where folks put random functions they need in (Utils, BitUtils, Yoga-Internal.h)
7. There is no clear indication from file structure or type naming what is private vs not
8. Handles like `YGNodeRef` and `YGConfigRef` can be used to access internals just by importing headers
This stack does some much needed spring cleaning:
1. All non-public headers and C++ implementation details are in separate folders from the root level `yoga`. This will give us room to split up logic and add more files without too large a flat hierarchy
3. All private C++ internals are under the `facebook::yoga` namespace. Details namespaces are only ever used within the same header, as they are intended
4. Utils files are split
5. Most C++ internals drop the YG prefix
6. Most C++ internal function names are all lower camel case
7. We start to split up Yoga.cpp
8. Every header beginning with YG or at the top-level directory is public and C only, with the exception of Yoga-Internal.h which has non-public functions for bindings
9. It is not possible to use private APIs without static casting handles to internal classes
This will give us more leeway to continue splitting monolithic files, and consistent guidelines for style in new files as well.
These changes should not be breaking to any project using only public Yoga headers. This includes every usage of Yoga in fbsource except for RN Fabric which is currently tied to internals. This refactor should make that boundary clearer.
Reviewed By: rshest
Differential Revision: D48769241
fbshipit-source-id: 5b8e2192309539e7c133c3b3b29b445b59dd5835
2023-09-04 11:20:17 -07:00
|
|
|
#include <vector>
|
|
|
|
|
2023-09-11 19:51:40 -07:00
|
|
|
#include <yoga/Yoga.h>
|
|
|
|
|
C++ Cleanup 2/N: Reorganize YGConfig (#1348)
Summary:
X-link: https://github.com/facebook/react-native/pull/39218
X-link: https://github.com/facebook/react-native/pull/39169
Pull Request resolved: https://github.com/facebook/yoga/pull/1348
## This diff
This diff adds a top level `config` directory for code related to configuring Yoga and Yoga Nodes.
The public API for config handles is `YGConfigRef`, which is forward declared to be a pointer to a struct named `YGConfig`. The existing `YGConfig` is split into `yoga::Config`, as the private C++ implementation, inheriting from `YGConfig`, a marker type represented as an empty struct. The public API continues to accept `YGConfigRef`, which continues to be `YGConfig *`, but it must be cast to its concrete internal representation at the API boundary before doing work on it.
## This stack
The organization of the C++ internals of Yoga are in need of attention.
1. Some of the C++ internals are namespaced, but others not.
2. Some of the namespaces include `detail`, but are meant to be used outside of the translation unit (FB Clang Tidy rules warn on any usage of these)
2. Most of the files are in a flat hierarchy, except for event tracing in its own folder
3. Some files and functions begin with YG, others don’t
4. Some functions are uppercase, others are not
5. Almost all of the interesting logic is in Yoga.cpp, and the file is too large to reason about
6. There are multiple grab bag files where folks put random functions they need in (Utils, BitUtils, Yoga-Internal.h)
7. There is no clear indication from file structure or type naming what is private vs not
8. Handles like `YGNodeRef` and `YGConfigRef` can be used to access internals just by importing headers
This stack does some much needed spring cleaning:
1. All non-public headers and C++ implementation details are in separate folders from the root level `yoga`. This will give us room to split up logic and add more files without too large a flat hierarchy
3. All private C++ internals are under the `facebook::yoga` namespace. Details namespaces are only ever used within the same header, as they are intended
4. Utils files are split
5. Most C++ internals drop the YG prefix
6. Most C++ internal function names are all lower camel case
7. We start to split up Yoga.cpp
8. Every header beginning with YG or at the top-level directory is public and C only, with the exception of Yoga-Internal.h which has non-public functions for bindings
9. It is not possible to use private APIs without static casting handles to internal classes
This will give us more leeway to continue splitting monolithic files, and consistent guidelines for style in new files as well.
These changes should not be breaking to any project using only public Yoga headers. This includes every usage of Yoga in fbsource except for RN Fabric which is currently tied to internals. This refactor should make that boundary clearer.
Changelog: [Internal]
Reviewed By: shwanton
Differential Revision: D48847257
fbshipit-source-id: 7a2157d169ba80a6f79620693ae45bb10dfca5a3
2023-08-30 16:27:32 -07:00
|
|
|
#include <yoga/config/Config.h>
|
2023-09-29 00:06:34 -07:00
|
|
|
#include <yoga/enums/Dimension.h>
|
2023-09-19 16:30:02 -07:00
|
|
|
#include <yoga/enums/Direction.h>
|
2023-11-25 20:41:22 -08:00
|
|
|
#include <yoga/enums/Edge.h>
|
2023-09-14 23:06:34 -07:00
|
|
|
#include <yoga/enums/Errata.h>
|
2023-09-14 23:06:34 -07:00
|
|
|
#include <yoga/enums/MeasureMode.h>
|
2023-09-14 23:06:34 -07:00
|
|
|
#include <yoga/enums/NodeType.h>
|
2024-01-19 11:28:06 -08:00
|
|
|
#include <yoga/enums/PhysicalEdge.h>
|
C++ Cleanup 3/N: Reorganize YGNode (#1350)
Summary:
X-link: https://github.com/facebook/react-native/pull/39219
Pull Request resolved: https://github.com/facebook/yoga/pull/1350
X-link: https://github.com/facebook/react-native/pull/39170
## This diff
This diff adds a top level `node` directory for code related to Yoga nodes and data structures on them (inc moving `YGLayout` to `LayoutResults`).
The public API for config handles is `YGNodeRef`, which is forward declared to be a pointer to a struct named `YGNode`. The existing `YGNode` is split into `yoga::Node`, as the private C++ implementation, inheriting from `YGNode`, a marker type represented as an empty struct. The public API continues to accept `YGNodeRef`, which continues to be `YGNode *`, but it must be cast to its concrete internal representation at the API boundary before doing work on it.
This change ends up needing to touch quite a bit, due to the amount of code that mixed and matched private and public APIs. Don't be scared though, because these changes are very mechanical, and Phabricator's line-count is 3x the actual amount due to mirrors and dirsyncs.
## This stack
The organization of the C++ internals of Yoga are in need of attention.
1. Some of the C++ internals are namespaced, but others not.
2. Some of the namespaces include `detail`, but are meant to be used outside of the translation unit (FB Clang Tidy rules warn on any usage of these)
2. Most of the files are in a flat hierarchy, except for event tracing in its own folder
3. Some files and functions begin with YG, others don’t
4. Some functions are uppercase, others are not
5. Almost all of the interesting logic is in Yoga.cpp, and the file is too large to reason about
6. There are multiple grab bag files where folks put random functions they need in (Utils, BitUtils, Yoga-Internal.h)
7. There is no clear indication from file structure or type naming what is private vs not
8. Handles like `YGNodeRef` and `YGConfigRef` can be used to access internals just by importing headers
This stack does some much needed spring cleaning:
1. All non-public headers and C++ implementation details are in separate folders from the root level `yoga`. This will give us room to split up logic and add more files without too large a flat hierarchy
3. All private C++ internals are under the `facebook::yoga` namespace. Details namespaces are only ever used within the same header, as they are intended
4. Utils files are split
5. Most C++ internals drop the YG prefix
6. Most C++ internal function names are all lower camel case
7. We start to split up Yoga.cpp
8. Every header beginning with YG or at the top-level directory is public and C only, with the exception of Yoga-Internal.h which has non-public functions for bindings
9. It is not possible to use private APIs without static casting handles to internal classes
This will give us more leeway to continue splitting monolithic files, and consistent guidelines for style in new files as well.
These changes should not be breaking to any project using only public Yoga headers. This includes every usage of Yoga in fbsource except for RN Fabric which is currently tied to internals. This refactor should make that boundary clearer.
Changelog: [Internal]
bypass-github-export-checks
Reviewed By: shwanton
Differential Revision: D48847258
fbshipit-source-id: fc560893533b55a5c2d52c37d8e9a59f7369f174
2023-08-30 19:57:16 -07:00
|
|
|
#include <yoga/node/LayoutResults.h>
|
C++ Cleanup 1/N: Reorganize YGStyle (#1349)
Summary:
X-link: https://github.com/facebook/react-native/pull/39221
Pull Request resolved: https://github.com/facebook/yoga/pull/1349
X-link: https://github.com/facebook/react-native/pull/39171
## This diff
This diff adds a `style` directory for code related to storing and manipulating styles. `YGStyle`, which is not a public API, is renamed to `yoga::Style` and moved into this folder, alongside `CompactValue`. We will eventually add `ValuePool` alongside this for the next generation style representation.
## This stack
The organization of the C++ internals of Yoga are in need of attention.
1. Some of the C++ internals are namespaced, but others not.
2. Some of the namespaces include `detail`, but are meant to be used outside of the translation unit (FB Clang Tidy rules warn on any usage of these)
2. Most of the files are in a flat hierarchy, except for event tracing in its own folder
3. Some files and functions begin with YG, others don’t
4. Some functions are uppercase, others are not
5. Almost all of the interesting logic is in Yoga.cpp, and the file is too large to reason about
6. There are multiple grab bag files where folks put random functions they need in (Utils, BitUtils, Yoga-Internal.h)
7. There is no clear indication from file structure or type naming what is private vs not
8. Handles like `YGNodeRef` and `YGConfigRef` can be used to access internals just by importing headers
This stack does some much needed spring cleaning:
1. All non-public headers and C++ implementation details are in separate folders from the root level `yoga`. This will give us room to split up logic and add more files without too large a flat hierarchy
3. All private C++ internals are under the `facebook::yoga` namespace. Details namespaces are only ever used within the same header, as they are intended
4. Utils files are split
5. Most C++ internals drop the YG prefix
6. Most C++ internal function names are all lower camel case
7. We start to split up Yoga.cpp
8. Every header beginning with YG or at the top-level directory is public and C only, with the exception of Yoga-Internal.h which has non-public functions for bindings
9. It is not possible to use private APIs without static casting handles to internal classes
This will give us more leeway to continue splitting monolithic files, and consistent guidelines for style in new files as well.
These changes should not be breaking to any project using only public Yoga headers. This includes every usage of Yoga in fbsource except for RN Fabric which is currently tied to internals. This refactor should make that boundary clearer.
Changelog: [Internal]
Reviewed By: shwanton
Differential Revision: D48847261
fbshipit-source-id: 0fc8c6991e19079f3f0d55d368574757e453fe93
2023-08-30 16:27:32 -07:00
|
|
|
#include <yoga/style/Style.h>
|
2017-12-19 11:18:00 -08:00
|
|
|
|
C++ Cleanup 3/N: Reorganize YGNode (#1350)
Summary:
X-link: https://github.com/facebook/react-native/pull/39219
Pull Request resolved: https://github.com/facebook/yoga/pull/1350
X-link: https://github.com/facebook/react-native/pull/39170
## This diff
This diff adds a top level `node` directory for code related to Yoga nodes and data structures on them (inc moving `YGLayout` to `LayoutResults`).
The public API for config handles is `YGNodeRef`, which is forward declared to be a pointer to a struct named `YGNode`. The existing `YGNode` is split into `yoga::Node`, as the private C++ implementation, inheriting from `YGNode`, a marker type represented as an empty struct. The public API continues to accept `YGNodeRef`, which continues to be `YGNode *`, but it must be cast to its concrete internal representation at the API boundary before doing work on it.
This change ends up needing to touch quite a bit, due to the amount of code that mixed and matched private and public APIs. Don't be scared though, because these changes are very mechanical, and Phabricator's line-count is 3x the actual amount due to mirrors and dirsyncs.
## This stack
The organization of the C++ internals of Yoga are in need of attention.
1. Some of the C++ internals are namespaced, but others not.
2. Some of the namespaces include `detail`, but are meant to be used outside of the translation unit (FB Clang Tidy rules warn on any usage of these)
2. Most of the files are in a flat hierarchy, except for event tracing in its own folder
3. Some files and functions begin with YG, others don’t
4. Some functions are uppercase, others are not
5. Almost all of the interesting logic is in Yoga.cpp, and the file is too large to reason about
6. There are multiple grab bag files where folks put random functions they need in (Utils, BitUtils, Yoga-Internal.h)
7. There is no clear indication from file structure or type naming what is private vs not
8. Handles like `YGNodeRef` and `YGConfigRef` can be used to access internals just by importing headers
This stack does some much needed spring cleaning:
1. All non-public headers and C++ implementation details are in separate folders from the root level `yoga`. This will give us room to split up logic and add more files without too large a flat hierarchy
3. All private C++ internals are under the `facebook::yoga` namespace. Details namespaces are only ever used within the same header, as they are intended
4. Utils files are split
5. Most C++ internals drop the YG prefix
6. Most C++ internal function names are all lower camel case
7. We start to split up Yoga.cpp
8. Every header beginning with YG or at the top-level directory is public and C only, with the exception of Yoga-Internal.h which has non-public functions for bindings
9. It is not possible to use private APIs without static casting handles to internal classes
This will give us more leeway to continue splitting monolithic files, and consistent guidelines for style in new files as well.
These changes should not be breaking to any project using only public Yoga headers. This includes every usage of Yoga in fbsource except for RN Fabric which is currently tied to internals. This refactor should make that boundary clearer.
Changelog: [Internal]
bypass-github-export-checks
Reviewed By: shwanton
Differential Revision: D48847258
fbshipit-source-id: fc560893533b55a5c2d52c37d8e9a59f7369f174
2023-08-30 19:57:16 -07:00
|
|
|
// Tag struct used to form the opaque YGNodeRef for the public C API
|
|
|
|
struct YGNode {};
|
|
|
|
|
|
|
|
namespace facebook::yoga {
|
|
|
|
|
2023-09-11 19:51:40 -07:00
|
|
|
class YG_EXPORT Node : public ::YGNode {
|
2023-09-13 20:12:55 -07:00
|
|
|
public:
|
2023-09-11 19:51:40 -07:00
|
|
|
Node();
|
|
|
|
explicit Node(const Config* config);
|
2019-03-01 04:18:42 -08:00
|
|
|
|
2024-03-04 02:28:02 -08:00
|
|
|
Node(Node&& node) noexcept;
|
2019-03-01 04:18:42 -08:00
|
|
|
|
|
|
|
// Does not expose true value semantics, as children are not cloned eagerly.
|
|
|
|
// Should we remove this?
|
C++ Cleanup 3/N: Reorganize YGNode (#1350)
Summary:
X-link: https://github.com/facebook/react-native/pull/39219
Pull Request resolved: https://github.com/facebook/yoga/pull/1350
X-link: https://github.com/facebook/react-native/pull/39170
## This diff
This diff adds a top level `node` directory for code related to Yoga nodes and data structures on them (inc moving `YGLayout` to `LayoutResults`).
The public API for config handles is `YGNodeRef`, which is forward declared to be a pointer to a struct named `YGNode`. The existing `YGNode` is split into `yoga::Node`, as the private C++ implementation, inheriting from `YGNode`, a marker type represented as an empty struct. The public API continues to accept `YGNodeRef`, which continues to be `YGNode *`, but it must be cast to its concrete internal representation at the API boundary before doing work on it.
This change ends up needing to touch quite a bit, due to the amount of code that mixed and matched private and public APIs. Don't be scared though, because these changes are very mechanical, and Phabricator's line-count is 3x the actual amount due to mirrors and dirsyncs.
## This stack
The organization of the C++ internals of Yoga are in need of attention.
1. Some of the C++ internals are namespaced, but others not.
2. Some of the namespaces include `detail`, but are meant to be used outside of the translation unit (FB Clang Tidy rules warn on any usage of these)
2. Most of the files are in a flat hierarchy, except for event tracing in its own folder
3. Some files and functions begin with YG, others don’t
4. Some functions are uppercase, others are not
5. Almost all of the interesting logic is in Yoga.cpp, and the file is too large to reason about
6. There are multiple grab bag files where folks put random functions they need in (Utils, BitUtils, Yoga-Internal.h)
7. There is no clear indication from file structure or type naming what is private vs not
8. Handles like `YGNodeRef` and `YGConfigRef` can be used to access internals just by importing headers
This stack does some much needed spring cleaning:
1. All non-public headers and C++ implementation details are in separate folders from the root level `yoga`. This will give us room to split up logic and add more files without too large a flat hierarchy
3. All private C++ internals are under the `facebook::yoga` namespace. Details namespaces are only ever used within the same header, as they are intended
4. Utils files are split
5. Most C++ internals drop the YG prefix
6. Most C++ internal function names are all lower camel case
7. We start to split up Yoga.cpp
8. Every header beginning with YG or at the top-level directory is public and C only, with the exception of Yoga-Internal.h which has non-public functions for bindings
9. It is not possible to use private APIs without static casting handles to internal classes
This will give us more leeway to continue splitting monolithic files, and consistent guidelines for style in new files as well.
These changes should not be breaking to any project using only public Yoga headers. This includes every usage of Yoga in fbsource except for RN Fabric which is currently tied to internals. This refactor should make that boundary clearer.
Changelog: [Internal]
bypass-github-export-checks
Reviewed By: shwanton
Differential Revision: D48847258
fbshipit-source-id: fc560893533b55a5c2d52c37d8e9a59f7369f174
2023-08-30 19:57:16 -07:00
|
|
|
Node(const Node& node) = default;
|
2019-03-01 04:18:42 -08:00
|
|
|
|
|
|
|
// assignment means potential leaks of existing children, or alternatively
|
|
|
|
// freeing unowned memory, double free, or freeing stack memory.
|
C++ Cleanup 3/N: Reorganize YGNode (#1350)
Summary:
X-link: https://github.com/facebook/react-native/pull/39219
Pull Request resolved: https://github.com/facebook/yoga/pull/1350
X-link: https://github.com/facebook/react-native/pull/39170
## This diff
This diff adds a top level `node` directory for code related to Yoga nodes and data structures on them (inc moving `YGLayout` to `LayoutResults`).
The public API for config handles is `YGNodeRef`, which is forward declared to be a pointer to a struct named `YGNode`. The existing `YGNode` is split into `yoga::Node`, as the private C++ implementation, inheriting from `YGNode`, a marker type represented as an empty struct. The public API continues to accept `YGNodeRef`, which continues to be `YGNode *`, but it must be cast to its concrete internal representation at the API boundary before doing work on it.
This change ends up needing to touch quite a bit, due to the amount of code that mixed and matched private and public APIs. Don't be scared though, because these changes are very mechanical, and Phabricator's line-count is 3x the actual amount due to mirrors and dirsyncs.
## This stack
The organization of the C++ internals of Yoga are in need of attention.
1. Some of the C++ internals are namespaced, but others not.
2. Some of the namespaces include `detail`, but are meant to be used outside of the translation unit (FB Clang Tidy rules warn on any usage of these)
2. Most of the files are in a flat hierarchy, except for event tracing in its own folder
3. Some files and functions begin with YG, others don’t
4. Some functions are uppercase, others are not
5. Almost all of the interesting logic is in Yoga.cpp, and the file is too large to reason about
6. There are multiple grab bag files where folks put random functions they need in (Utils, BitUtils, Yoga-Internal.h)
7. There is no clear indication from file structure or type naming what is private vs not
8. Handles like `YGNodeRef` and `YGConfigRef` can be used to access internals just by importing headers
This stack does some much needed spring cleaning:
1. All non-public headers and C++ implementation details are in separate folders from the root level `yoga`. This will give us room to split up logic and add more files without too large a flat hierarchy
3. All private C++ internals are under the `facebook::yoga` namespace. Details namespaces are only ever used within the same header, as they are intended
4. Utils files are split
5. Most C++ internals drop the YG prefix
6. Most C++ internal function names are all lower camel case
7. We start to split up Yoga.cpp
8. Every header beginning with YG or at the top-level directory is public and C only, with the exception of Yoga-Internal.h which has non-public functions for bindings
9. It is not possible to use private APIs without static casting handles to internal classes
This will give us more leeway to continue splitting monolithic files, and consistent guidelines for style in new files as well.
These changes should not be breaking to any project using only public Yoga headers. This includes every usage of Yoga in fbsource except for RN Fabric which is currently tied to internals. This refactor should make that boundary clearer.
Changelog: [Internal]
bypass-github-export-checks
Reviewed By: shwanton
Differential Revision: D48847258
fbshipit-source-id: fc560893533b55a5c2d52c37d8e9a59f7369f174
2023-08-30 19:57:16 -07:00
|
|
|
Node& operator=(const Node&) = delete;
|
2017-12-19 11:18:00 -08:00
|
|
|
|
|
|
|
// Getters
|
2023-09-13 20:12:55 -07:00
|
|
|
void* getContext() const {
|
|
|
|
return context_;
|
|
|
|
}
|
2018-07-11 08:51:33 -07:00
|
|
|
|
2024-01-08 20:28:49 -08:00
|
|
|
bool alwaysFormsContainingBlock() const {
|
|
|
|
return alwaysFormsContainingBlock_;
|
|
|
|
}
|
|
|
|
|
2023-09-13 20:12:55 -07:00
|
|
|
bool getHasNewLayout() const {
|
2023-09-19 01:28:35 -07:00
|
|
|
return hasNewLayout_;
|
2023-09-13 20:12:55 -07:00
|
|
|
}
|
2018-07-19 09:51:23 -07:00
|
|
|
|
2023-09-14 23:06:34 -07:00
|
|
|
NodeType getNodeType() const {
|
2023-09-19 01:28:35 -07:00
|
|
|
return nodeType_;
|
2019-11-27 14:16:42 -08:00
|
|
|
}
|
2018-07-19 09:51:23 -07:00
|
|
|
|
2023-09-13 20:12:55 -07:00
|
|
|
bool hasMeasureFunc() const noexcept {
|
|
|
|
return measureFunc_ != nullptr;
|
|
|
|
}
|
2018-07-19 09:51:23 -07:00
|
|
|
|
2024-03-04 02:28:02 -08:00
|
|
|
YGSize measure(
|
Reland: Sanitize measure function results
Summary:
D57285584 was reverted because we have service code with a faulty measure function, and adding logging to Yoga when invalid measurements were received was enough to spike error rate to elevated levels and block release.
This is a reland of the below change, with a couple modifications:
1. We log warnings instead of errors, which from what I heard, shouldn't block release, but should still make signal
2. We only zero the dimension which was NaN, to preserve exact behavior
## Original
We've started seeing assertion failures in Yoga where a `NaN` value makes its way to an `availableHeight` constraint when measuring Litho tree.
Because it's only happening on Litho, I have some suspicion this might be originating from a Litho-specific measure function. This adds sanitization in Yoga to measure function results, where we will log an error, and set size to zero, if either dimension ends up being negative of `NaN`.
This doesn't really help track down where the error was happening, but Yoga doesn't have great context to show this to begin with. If we see this is issue, next steps would be Litho internal intrumentation to find culprit.
Changelog: [Internal]
Reviewed By: sbuggay
Differential Revision: D57473295
fbshipit-source-id: 979f1b9a51f5550a8d3ca534276ec191a3cb7b9e
2024-05-17 19:12:13 -07:00
|
|
|
float availableWidth,
|
2024-03-04 02:28:02 -08:00
|
|
|
MeasureMode widthMode,
|
Reland: Sanitize measure function results
Summary:
D57285584 was reverted because we have service code with a faulty measure function, and adding logging to Yoga when invalid measurements were received was enough to spike error rate to elevated levels and block release.
This is a reland of the below change, with a couple modifications:
1. We log warnings instead of errors, which from what I heard, shouldn't block release, but should still make signal
2. We only zero the dimension which was NaN, to preserve exact behavior
## Original
We've started seeing assertion failures in Yoga where a `NaN` value makes its way to an `availableHeight` constraint when measuring Litho tree.
Because it's only happening on Litho, I have some suspicion this might be originating from a Litho-specific measure function. This adds sanitization in Yoga to measure function results, where we will log an error, and set size to zero, if either dimension ends up being negative of `NaN`.
This doesn't really help track down where the error was happening, but Yoga doesn't have great context to show this to begin with. If we see this is issue, next steps would be Litho internal intrumentation to find culprit.
Changelog: [Internal]
Reviewed By: sbuggay
Differential Revision: D57473295
fbshipit-source-id: 979f1b9a51f5550a8d3ca534276ec191a3cb7b9e
2024-05-17 19:12:13 -07:00
|
|
|
float availableHeight,
|
2024-03-04 02:28:02 -08:00
|
|
|
MeasureMode heightMode);
|
2019-02-19 09:54:45 -08:00
|
|
|
|
2023-09-13 20:12:55 -07:00
|
|
|
bool hasBaselineFunc() const noexcept {
|
|
|
|
return baselineFunc_ != nullptr;
|
|
|
|
}
|
2019-02-19 09:54:45 -08:00
|
|
|
|
2023-09-12 19:08:55 -07:00
|
|
|
float baseline(float width, float height) const;
|
2018-07-19 09:51:23 -07:00
|
|
|
|
2024-03-04 02:28:02 -08:00
|
|
|
float dimensionWithMargin(FlexDirection axis, float widthSize);
|
2023-12-04 19:35:30 -08:00
|
|
|
|
2024-03-04 02:28:02 -08:00
|
|
|
bool isLayoutDimensionDefined(FlexDirection axis);
|
2023-12-04 19:35:30 -08:00
|
|
|
|
2023-12-19 13:38:40 -08:00
|
|
|
/**
|
|
|
|
* Whether the node has a "definite length" along the given axis.
|
|
|
|
* https://www.w3.org/TR/css-sizing-3/#definite
|
|
|
|
*/
|
|
|
|
inline bool hasDefiniteLength(Dimension dimension, float ownerSize) {
|
2024-10-01 15:19:22 -07:00
|
|
|
auto usedValue = getProcessedDimension(dimension).resolve(ownerSize);
|
2023-12-19 13:38:40 -08:00
|
|
|
return usedValue.isDefined() && usedValue.unwrap() >= 0.0f;
|
|
|
|
}
|
2023-12-04 19:35:30 -08:00
|
|
|
|
2023-09-14 23:06:34 -07:00
|
|
|
bool hasErrata(Errata errata) const {
|
2023-09-13 20:12:55 -07:00
|
|
|
return config_->hasErrata(errata);
|
|
|
|
}
|
2023-05-11 05:30:57 -07:00
|
|
|
|
2023-09-13 20:12:55 -07:00
|
|
|
YGDirtiedFunc getDirtiedFunc() const {
|
|
|
|
return dirtiedFunc_;
|
|
|
|
}
|
2018-07-19 09:51:23 -07:00
|
|
|
|
2018-01-12 22:03:51 -08:00
|
|
|
// For Performance reasons passing as reference.
|
2024-01-19 11:28:06 -08:00
|
|
|
Style& style() {
|
2023-09-13 20:12:55 -07:00
|
|
|
return style_;
|
|
|
|
}
|
2018-07-11 08:51:33 -07:00
|
|
|
|
2024-01-19 11:28:06 -08:00
|
|
|
const Style& style() const {
|
2023-09-13 20:12:55 -07:00
|
|
|
return style_;
|
|
|
|
}
|
2018-07-11 08:51:33 -07:00
|
|
|
|
2018-01-12 22:03:51 -08:00
|
|
|
// For Performance reasons passing as reference.
|
2023-09-13 20:12:55 -07:00
|
|
|
LayoutResults& getLayout() {
|
|
|
|
return layout_;
|
|
|
|
}
|
2018-07-11 08:51:33 -07:00
|
|
|
|
2023-09-13 20:12:55 -07:00
|
|
|
const LayoutResults& getLayout() const {
|
|
|
|
return layout_;
|
|
|
|
}
|
2018-07-19 09:51:23 -07:00
|
|
|
|
2023-09-13 20:12:55 -07:00
|
|
|
size_t getLineIndex() const {
|
|
|
|
return lineIndex_;
|
|
|
|
}
|
2018-07-19 09:51:23 -07:00
|
|
|
|
2023-09-13 20:12:55 -07:00
|
|
|
bool isReferenceBaseline() const {
|
2023-09-19 01:28:35 -07:00
|
|
|
return isReferenceBaseline_;
|
2023-09-13 20:12:55 -07:00
|
|
|
}
|
2018-11-14 02:49:27 -08:00
|
|
|
|
C++ Cleanup 3/N: Reorganize YGNode (#1350)
Summary:
X-link: https://github.com/facebook/react-native/pull/39219
Pull Request resolved: https://github.com/facebook/yoga/pull/1350
X-link: https://github.com/facebook/react-native/pull/39170
## This diff
This diff adds a top level `node` directory for code related to Yoga nodes and data structures on them (inc moving `YGLayout` to `LayoutResults`).
The public API for config handles is `YGNodeRef`, which is forward declared to be a pointer to a struct named `YGNode`. The existing `YGNode` is split into `yoga::Node`, as the private C++ implementation, inheriting from `YGNode`, a marker type represented as an empty struct. The public API continues to accept `YGNodeRef`, which continues to be `YGNode *`, but it must be cast to its concrete internal representation at the API boundary before doing work on it.
This change ends up needing to touch quite a bit, due to the amount of code that mixed and matched private and public APIs. Don't be scared though, because these changes are very mechanical, and Phabricator's line-count is 3x the actual amount due to mirrors and dirsyncs.
## This stack
The organization of the C++ internals of Yoga are in need of attention.
1. Some of the C++ internals are namespaced, but others not.
2. Some of the namespaces include `detail`, but are meant to be used outside of the translation unit (FB Clang Tidy rules warn on any usage of these)
2. Most of the files are in a flat hierarchy, except for event tracing in its own folder
3. Some files and functions begin with YG, others don’t
4. Some functions are uppercase, others are not
5. Almost all of the interesting logic is in Yoga.cpp, and the file is too large to reason about
6. There are multiple grab bag files where folks put random functions they need in (Utils, BitUtils, Yoga-Internal.h)
7. There is no clear indication from file structure or type naming what is private vs not
8. Handles like `YGNodeRef` and `YGConfigRef` can be used to access internals just by importing headers
This stack does some much needed spring cleaning:
1. All non-public headers and C++ implementation details are in separate folders from the root level `yoga`. This will give us room to split up logic and add more files without too large a flat hierarchy
3. All private C++ internals are under the `facebook::yoga` namespace. Details namespaces are only ever used within the same header, as they are intended
4. Utils files are split
5. Most C++ internals drop the YG prefix
6. Most C++ internal function names are all lower camel case
7. We start to split up Yoga.cpp
8. Every header beginning with YG or at the top-level directory is public and C only, with the exception of Yoga-Internal.h which has non-public functions for bindings
9. It is not possible to use private APIs without static casting handles to internal classes
This will give us more leeway to continue splitting monolithic files, and consistent guidelines for style in new files as well.
These changes should not be breaking to any project using only public Yoga headers. This includes every usage of Yoga in fbsource except for RN Fabric which is currently tied to internals. This refactor should make that boundary clearer.
Changelog: [Internal]
bypass-github-export-checks
Reviewed By: shwanton
Differential Revision: D48847258
fbshipit-source-id: fc560893533b55a5c2d52c37d8e9a59f7369f174
2023-08-30 19:57:16 -07:00
|
|
|
// returns the Node that owns this Node. An owner is used to identify
|
|
|
|
// the YogaTree that a Node belongs to. This method will return the parent
|
|
|
|
// of the Node when a Node only belongs to one YogaTree or nullptr when
|
|
|
|
// the Node is shared between two or more YogaTrees.
|
2023-09-13 20:12:55 -07:00
|
|
|
Node* getOwner() const {
|
|
|
|
return owner_;
|
|
|
|
}
|
2018-07-19 09:51:23 -07:00
|
|
|
|
2023-09-13 20:12:55 -07:00
|
|
|
const std::vector<Node*>& getChildren() const {
|
|
|
|
return children_;
|
|
|
|
}
|
2018-07-19 09:51:23 -07:00
|
|
|
|
2023-09-13 20:12:55 -07:00
|
|
|
Node* getChild(size_t index) const {
|
|
|
|
return children_.at(index);
|
|
|
|
}
|
C++ Cleanup 10/N: YGNodeCalculateLayout (#1352)
Summary:
X-link: https://github.com/facebook/react-native/pull/39195
Pull Request resolved: https://github.com/facebook/yoga/pull/1352
## This diff
This splits out all of the logic under `YGNodeCalculateLayout` to a couple of different files, does some mechanical renaming, and starts to split up the implementation a tiny bit. After this, core layout functions are all C++ convention and namespaced.
Each new file is marked as a move for the sake of blame history. It means Phabricator has a very inaccurate count of lines removed though.
## This stack
The organization of the C++ internals of Yoga are in need of attention.
1. Some of the C++ internals are namespaced, but others not.
2. Some of the namespaces include `detail`, but are meant to be used outside of the translation unit (FB Clang Tidy rules warn on any usage of these)
2. Most of the files are in a flat hierarchy, except for event tracing in its own folder
3. Some files and functions begin with YG, others don’t
4. Some functions are uppercase, others are not
5. Almost all of the interesting logic is in Yoga.cpp, and the file is too large to reason about
6. There are multiple grab bag files where folks put random functions they need in (Utils, BitUtils, Yoga-Internal.h)
7. There is no clear indication from file structure or type naming what is private vs not
8. Handles like `YGNodeRef` and `YGConfigRef` can be used to access internals just by importing headers
This stack does some much needed spring cleaning:
1. All non-public headers and C++ implementation details are in separate folders from the root level `yoga`. This will give us room to split up logic and add more files without too large a flat hierarchy
3. All private C++ internals are under the `facebook::yoga` namespace. Details namespaces are only ever used within the same header, as they are intended
4. Utils files are split
5. Most C++ internals drop the YG prefix
6. Most C++ internal function names are all lower camel case
7. We start to split up Yoga.cpp
8. Every header beginning with YG or at the top-level directory is public and C only, with the exception of Yoga-Internal.h which has non-public functions for bindings
9. It is not possible to use private APIs without static casting handles to internal classes
This will give us more leeway to continue splitting monolithic files, and consistent guidelines for style in new files as well.
These changes should not be breaking to any project using only public Yoga headers. This includes every usage of Yoga in fbsource except for RN Fabric which is currently tied to internals. This refactor should make that boundary clearer.
Reviewed By: rshest
Differential Revision: D48770478
fbshipit-source-id: 2a74b86441c3352de03ae193c98fc3a3573047ed
2023-09-05 05:24:54 -07:00
|
|
|
|
2023-09-13 20:12:55 -07:00
|
|
|
size_t getChildCount() const {
|
|
|
|
return children_.size();
|
|
|
|
}
|
2018-07-11 08:51:33 -07:00
|
|
|
|
2023-09-13 20:12:55 -07:00
|
|
|
const Config* getConfig() const {
|
|
|
|
return config_;
|
|
|
|
}
|
2018-07-19 09:51:23 -07:00
|
|
|
|
2023-09-13 20:12:55 -07:00
|
|
|
bool isDirty() const {
|
2023-09-19 01:28:35 -07:00
|
|
|
return isDirty_;
|
2023-09-13 20:12:55 -07:00
|
|
|
}
|
2018-07-19 09:51:23 -07:00
|
|
|
|
2024-10-01 15:19:22 -07:00
|
|
|
Style::Length getProcessedDimension(Dimension dimension) const {
|
|
|
|
return processedDimensions_[static_cast<size_t>(dimension)];
|
2018-07-11 08:51:33 -07:00
|
|
|
}
|
2018-01-11 04:47:45 -08:00
|
|
|
|
2024-10-01 15:19:22 -07:00
|
|
|
FloatOptional getResolvedDimension(
|
|
|
|
Direction direction,
|
|
|
|
Dimension dimension,
|
2024-10-04 17:07:05 -07:00
|
|
|
float referenceLength,
|
|
|
|
float ownerWidth) const {
|
2024-10-01 15:19:22 -07:00
|
|
|
FloatOptional value =
|
|
|
|
getProcessedDimension(dimension).resolve(referenceLength);
|
|
|
|
if (style_.boxSizing() == BoxSizing::BorderBox) {
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
|
|
|
FloatOptional dimensionPaddingAndBorder =
|
|
|
|
FloatOptional{style_.computePaddingAndBorderForDimension(
|
2024-10-04 17:07:05 -07:00
|
|
|
direction, dimension, ownerWidth)};
|
2024-10-01 15:19:22 -07:00
|
|
|
|
|
|
|
return value +
|
|
|
|
(dimensionPaddingAndBorder.isDefined() ? dimensionPaddingAndBorder
|
|
|
|
: FloatOptional{0.0});
|
|
|
|
}
|
|
|
|
|
2017-12-19 11:18:00 -08:00
|
|
|
// Setters
|
|
|
|
|
2023-09-13 20:12:55 -07:00
|
|
|
void setContext(void* context) {
|
|
|
|
context_ = context;
|
|
|
|
}
|
2018-07-11 08:51:33 -07:00
|
|
|
|
2024-01-08 20:28:49 -08:00
|
|
|
void setAlwaysFormsContainingBlock(bool alwaysFormsContainingBlock) {
|
|
|
|
alwaysFormsContainingBlock_ = alwaysFormsContainingBlock;
|
|
|
|
}
|
|
|
|
|
2019-08-07 16:17:00 -07:00
|
|
|
void setHasNewLayout(bool hasNewLayout) {
|
2023-09-19 01:28:35 -07:00
|
|
|
hasNewLayout_ = hasNewLayout;
|
2019-08-07 16:17:00 -07:00
|
|
|
}
|
2018-07-19 09:51:23 -07:00
|
|
|
|
2023-09-14 23:06:34 -07:00
|
|
|
void setNodeType(NodeType nodeType) {
|
2023-09-19 01:28:35 -07:00
|
|
|
nodeType_ = nodeType;
|
2019-11-27 14:16:42 -08:00
|
|
|
}
|
2018-07-11 08:51:33 -07:00
|
|
|
|
2017-12-19 11:18:00 -08:00
|
|
|
void setMeasureFunc(YGMeasureFunc measureFunc);
|
2018-07-11 08:51:33 -07:00
|
|
|
|
2019-02-21 05:35:52 -08:00
|
|
|
void setBaselineFunc(YGBaselineFunc baseLineFunc) {
|
2023-09-12 19:08:55 -07:00
|
|
|
baselineFunc_ = baseLineFunc;
|
2018-07-11 08:51:33 -07:00
|
|
|
}
|
|
|
|
|
2023-09-13 20:12:55 -07:00
|
|
|
void setDirtiedFunc(YGDirtiedFunc dirtiedFunc) {
|
|
|
|
dirtiedFunc_ = dirtiedFunc;
|
|
|
|
}
|
2018-07-11 08:51:33 -07:00
|
|
|
|
2023-09-13 20:12:55 -07:00
|
|
|
void setStyle(const Style& style) {
|
|
|
|
style_ = style;
|
|
|
|
}
|
2018-07-19 09:51:23 -07:00
|
|
|
|
2023-09-13 20:12:55 -07:00
|
|
|
void setLayout(const LayoutResults& layout) {
|
|
|
|
layout_ = layout;
|
|
|
|
}
|
2018-07-19 09:51:23 -07:00
|
|
|
|
2023-09-13 20:12:55 -07:00
|
|
|
void setLineIndex(size_t lineIndex) {
|
|
|
|
lineIndex_ = lineIndex;
|
|
|
|
}
|
2018-07-19 09:51:23 -07:00
|
|
|
|
2018-11-14 02:49:27 -08:00
|
|
|
void setIsReferenceBaseline(bool isReferenceBaseline) {
|
2023-09-19 01:28:35 -07:00
|
|
|
isReferenceBaseline_ = isReferenceBaseline;
|
2018-11-14 02:49:27 -08:00
|
|
|
}
|
|
|
|
|
2023-09-13 20:12:55 -07:00
|
|
|
void setOwner(Node* owner) {
|
|
|
|
owner_ = owner;
|
|
|
|
}
|
2018-07-11 08:51:33 -07:00
|
|
|
|
2023-09-13 20:12:55 -07:00
|
|
|
void setChildren(const std::vector<Node*>& children) {
|
|
|
|
children_ = children;
|
|
|
|
}
|
2018-07-11 08:51:33 -07:00
|
|
|
|
|
|
|
// TODO: rvalue override for setChildren
|
2018-07-19 09:51:23 -07:00
|
|
|
|
C++ Cleanup 3/N: Reorganize YGNode (#1350)
Summary:
X-link: https://github.com/facebook/react-native/pull/39219
Pull Request resolved: https://github.com/facebook/yoga/pull/1350
X-link: https://github.com/facebook/react-native/pull/39170
## This diff
This diff adds a top level `node` directory for code related to Yoga nodes and data structures on them (inc moving `YGLayout` to `LayoutResults`).
The public API for config handles is `YGNodeRef`, which is forward declared to be a pointer to a struct named `YGNode`. The existing `YGNode` is split into `yoga::Node`, as the private C++ implementation, inheriting from `YGNode`, a marker type represented as an empty struct. The public API continues to accept `YGNodeRef`, which continues to be `YGNode *`, but it must be cast to its concrete internal representation at the API boundary before doing work on it.
This change ends up needing to touch quite a bit, due to the amount of code that mixed and matched private and public APIs. Don't be scared though, because these changes are very mechanical, and Phabricator's line-count is 3x the actual amount due to mirrors and dirsyncs.
## This stack
The organization of the C++ internals of Yoga are in need of attention.
1. Some of the C++ internals are namespaced, but others not.
2. Some of the namespaces include `detail`, but are meant to be used outside of the translation unit (FB Clang Tidy rules warn on any usage of these)
2. Most of the files are in a flat hierarchy, except for event tracing in its own folder
3. Some files and functions begin with YG, others don’t
4. Some functions are uppercase, others are not
5. Almost all of the interesting logic is in Yoga.cpp, and the file is too large to reason about
6. There are multiple grab bag files where folks put random functions they need in (Utils, BitUtils, Yoga-Internal.h)
7. There is no clear indication from file structure or type naming what is private vs not
8. Handles like `YGNodeRef` and `YGConfigRef` can be used to access internals just by importing headers
This stack does some much needed spring cleaning:
1. All non-public headers and C++ implementation details are in separate folders from the root level `yoga`. This will give us room to split up logic and add more files without too large a flat hierarchy
3. All private C++ internals are under the `facebook::yoga` namespace. Details namespaces are only ever used within the same header, as they are intended
4. Utils files are split
5. Most C++ internals drop the YG prefix
6. Most C++ internal function names are all lower camel case
7. We start to split up Yoga.cpp
8. Every header beginning with YG or at the top-level directory is public and C only, with the exception of Yoga-Internal.h which has non-public functions for bindings
9. It is not possible to use private APIs without static casting handles to internal classes
This will give us more leeway to continue splitting monolithic files, and consistent guidelines for style in new files as well.
These changes should not be breaking to any project using only public Yoga headers. This includes every usage of Yoga in fbsource except for RN Fabric which is currently tied to internals. This refactor should make that boundary clearer.
Changelog: [Internal]
bypass-github-export-checks
Reviewed By: shwanton
Differential Revision: D48847258
fbshipit-source-id: fc560893533b55a5c2d52c37d8e9a59f7369f174
2023-08-30 19:57:16 -07:00
|
|
|
void setConfig(Config* config);
|
2018-07-11 08:51:33 -07:00
|
|
|
|
2017-12-19 11:18:00 -08:00
|
|
|
void setDirty(bool isDirty);
|
2023-09-19 16:30:02 -07:00
|
|
|
void setLayoutLastOwnerDirection(Direction direction);
|
2024-03-04 02:28:02 -08:00
|
|
|
void setLayoutComputedFlexBasis(FloatOptional computedFlexBasis);
|
2017-12-19 11:18:00 -08:00
|
|
|
void setLayoutComputedFlexBasisGeneration(
|
|
|
|
uint32_t computedFlexBasisGeneration);
|
2023-09-29 00:06:34 -07:00
|
|
|
void setLayoutMeasuredDimension(float measuredDimension, Dimension dimension);
|
2017-12-19 11:18:00 -08:00
|
|
|
void setLayoutHadOverflow(bool hadOverflow);
|
2023-11-25 20:41:22 -08:00
|
|
|
void setLayoutDimension(float LengthValue, Dimension dimension);
|
2023-09-19 16:30:02 -07:00
|
|
|
void setLayoutDirection(Direction direction);
|
2024-01-19 11:28:06 -08:00
|
|
|
void setLayoutMargin(float margin, PhysicalEdge edge);
|
|
|
|
void setLayoutBorder(float border, PhysicalEdge edge);
|
|
|
|
void setLayoutPadding(float padding, PhysicalEdge edge);
|
|
|
|
void setLayoutPosition(float position, PhysicalEdge edge);
|
2024-06-10 18:25:19 -07:00
|
|
|
void setPosition(Direction direction, float ownerWidth, float ownerHeight);
|
2018-01-11 04:47:48 -08:00
|
|
|
|
2017-12-19 11:18:00 -08:00
|
|
|
// Other methods
|
2024-10-01 15:19:22 -07:00
|
|
|
Style::Length processFlexBasis() const;
|
|
|
|
FloatOptional resolveFlexBasis(
|
|
|
|
Direction direction,
|
|
|
|
FlexDirection flexDirection,
|
2024-10-04 17:07:05 -07:00
|
|
|
float referenceLength,
|
|
|
|
float ownerWidth) const;
|
2024-10-01 15:19:22 -07:00
|
|
|
void processDimensions();
|
2024-03-04 02:28:02 -08:00
|
|
|
Direction resolveDirection(Direction ownerDirection);
|
2017-12-19 11:18:00 -08:00
|
|
|
void clearChildren();
|
2018-01-08 02:48:32 -08:00
|
|
|
/// Replaces the occurrences of oldChild with newChild
|
C++ Cleanup 3/N: Reorganize YGNode (#1350)
Summary:
X-link: https://github.com/facebook/react-native/pull/39219
Pull Request resolved: https://github.com/facebook/yoga/pull/1350
X-link: https://github.com/facebook/react-native/pull/39170
## This diff
This diff adds a top level `node` directory for code related to Yoga nodes and data structures on them (inc moving `YGLayout` to `LayoutResults`).
The public API for config handles is `YGNodeRef`, which is forward declared to be a pointer to a struct named `YGNode`. The existing `YGNode` is split into `yoga::Node`, as the private C++ implementation, inheriting from `YGNode`, a marker type represented as an empty struct. The public API continues to accept `YGNodeRef`, which continues to be `YGNode *`, but it must be cast to its concrete internal representation at the API boundary before doing work on it.
This change ends up needing to touch quite a bit, due to the amount of code that mixed and matched private and public APIs. Don't be scared though, because these changes are very mechanical, and Phabricator's line-count is 3x the actual amount due to mirrors and dirsyncs.
## This stack
The organization of the C++ internals of Yoga are in need of attention.
1. Some of the C++ internals are namespaced, but others not.
2. Some of the namespaces include `detail`, but are meant to be used outside of the translation unit (FB Clang Tidy rules warn on any usage of these)
2. Most of the files are in a flat hierarchy, except for event tracing in its own folder
3. Some files and functions begin with YG, others don’t
4. Some functions are uppercase, others are not
5. Almost all of the interesting logic is in Yoga.cpp, and the file is too large to reason about
6. There are multiple grab bag files where folks put random functions they need in (Utils, BitUtils, Yoga-Internal.h)
7. There is no clear indication from file structure or type naming what is private vs not
8. Handles like `YGNodeRef` and `YGConfigRef` can be used to access internals just by importing headers
This stack does some much needed spring cleaning:
1. All non-public headers and C++ implementation details are in separate folders from the root level `yoga`. This will give us room to split up logic and add more files without too large a flat hierarchy
3. All private C++ internals are under the `facebook::yoga` namespace. Details namespaces are only ever used within the same header, as they are intended
4. Utils files are split
5. Most C++ internals drop the YG prefix
6. Most C++ internal function names are all lower camel case
7. We start to split up Yoga.cpp
8. Every header beginning with YG or at the top-level directory is public and C only, with the exception of Yoga-Internal.h which has non-public functions for bindings
9. It is not possible to use private APIs without static casting handles to internal classes
This will give us more leeway to continue splitting monolithic files, and consistent guidelines for style in new files as well.
These changes should not be breaking to any project using only public Yoga headers. This includes every usage of Yoga in fbsource except for RN Fabric which is currently tied to internals. This refactor should make that boundary clearer.
Changelog: [Internal]
bypass-github-export-checks
Reviewed By: shwanton
Differential Revision: D48847258
fbshipit-source-id: fc560893533b55a5c2d52c37d8e9a59f7369f174
2023-08-30 19:57:16 -07:00
|
|
|
void replaceChild(Node* oldChild, Node* newChild);
|
2023-09-06 08:16:42 -07:00
|
|
|
void replaceChild(Node* child, size_t index);
|
|
|
|
void insertChild(Node* child, size_t index);
|
2017-12-19 11:18:00 -08:00
|
|
|
/// Removes the first occurrence of child
|
C++ Cleanup 3/N: Reorganize YGNode (#1350)
Summary:
X-link: https://github.com/facebook/react-native/pull/39219
Pull Request resolved: https://github.com/facebook/yoga/pull/1350
X-link: https://github.com/facebook/react-native/pull/39170
## This diff
This diff adds a top level `node` directory for code related to Yoga nodes and data structures on them (inc moving `YGLayout` to `LayoutResults`).
The public API for config handles is `YGNodeRef`, which is forward declared to be a pointer to a struct named `YGNode`. The existing `YGNode` is split into `yoga::Node`, as the private C++ implementation, inheriting from `YGNode`, a marker type represented as an empty struct. The public API continues to accept `YGNodeRef`, which continues to be `YGNode *`, but it must be cast to its concrete internal representation at the API boundary before doing work on it.
This change ends up needing to touch quite a bit, due to the amount of code that mixed and matched private and public APIs. Don't be scared though, because these changes are very mechanical, and Phabricator's line-count is 3x the actual amount due to mirrors and dirsyncs.
## This stack
The organization of the C++ internals of Yoga are in need of attention.
1. Some of the C++ internals are namespaced, but others not.
2. Some of the namespaces include `detail`, but are meant to be used outside of the translation unit (FB Clang Tidy rules warn on any usage of these)
2. Most of the files are in a flat hierarchy, except for event tracing in its own folder
3. Some files and functions begin with YG, others don’t
4. Some functions are uppercase, others are not
5. Almost all of the interesting logic is in Yoga.cpp, and the file is too large to reason about
6. There are multiple grab bag files where folks put random functions they need in (Utils, BitUtils, Yoga-Internal.h)
7. There is no clear indication from file structure or type naming what is private vs not
8. Handles like `YGNodeRef` and `YGConfigRef` can be used to access internals just by importing headers
This stack does some much needed spring cleaning:
1. All non-public headers and C++ implementation details are in separate folders from the root level `yoga`. This will give us room to split up logic and add more files without too large a flat hierarchy
3. All private C++ internals are under the `facebook::yoga` namespace. Details namespaces are only ever used within the same header, as they are intended
4. Utils files are split
5. Most C++ internals drop the YG prefix
6. Most C++ internal function names are all lower camel case
7. We start to split up Yoga.cpp
8. Every header beginning with YG or at the top-level directory is public and C only, with the exception of Yoga-Internal.h which has non-public functions for bindings
9. It is not possible to use private APIs without static casting handles to internal classes
This will give us more leeway to continue splitting monolithic files, and consistent guidelines for style in new files as well.
These changes should not be breaking to any project using only public Yoga headers. This includes every usage of Yoga in fbsource except for RN Fabric which is currently tied to internals. This refactor should make that boundary clearer.
Changelog: [Internal]
bypass-github-export-checks
Reviewed By: shwanton
Differential Revision: D48847258
fbshipit-source-id: fc560893533b55a5c2d52c37d8e9a59f7369f174
2023-08-30 19:57:16 -07:00
|
|
|
bool removeChild(Node* child);
|
2023-09-06 08:16:42 -07:00
|
|
|
void removeChild(size_t index);
|
2017-12-19 11:18:00 -08:00
|
|
|
|
2023-09-12 19:08:55 -07:00
|
|
|
void cloneChildrenIfNeeded();
|
2023-03-21 16:29:09 -07:00
|
|
|
void markDirtyAndPropagate();
|
2019-04-23 08:08:51 -07:00
|
|
|
float resolveFlexGrow() const;
|
|
|
|
float resolveFlexShrink() const;
|
2018-01-15 10:09:43 -08:00
|
|
|
bool isNodeFlexible();
|
2019-02-28 06:22:17 -08:00
|
|
|
void reset();
|
2023-12-19 13:38:40 -08:00
|
|
|
|
|
|
|
private:
|
|
|
|
// Used to allow resetting the node
|
2024-03-04 02:28:02 -08:00
|
|
|
Node& operator=(Node&&) noexcept = default;
|
2023-12-19 13:38:40 -08:00
|
|
|
|
|
|
|
float relativePosition(
|
|
|
|
FlexDirection axis,
|
|
|
|
Direction direction,
|
2024-03-04 02:28:02 -08:00
|
|
|
float axisSize) const;
|
2023-12-19 13:38:40 -08:00
|
|
|
|
|
|
|
void useWebDefaults() {
|
|
|
|
style_.setFlexDirection(FlexDirection::Row);
|
|
|
|
style_.setAlignContent(Align::Stretch);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool hasNewLayout_ : 1 = true;
|
|
|
|
bool isReferenceBaseline_ : 1 = false;
|
2024-04-10 22:15:25 -07:00
|
|
|
bool isDirty_ : 1 = true;
|
2024-01-08 20:28:49 -08:00
|
|
|
bool alwaysFormsContainingBlock_ : 1 = false;
|
2023-12-19 13:38:40 -08:00
|
|
|
NodeType nodeType_ : bitCount<NodeType>() = NodeType::Default;
|
|
|
|
void* context_ = nullptr;
|
2024-01-16 10:07:19 -08:00
|
|
|
YGMeasureFunc measureFunc_ = nullptr;
|
|
|
|
YGBaselineFunc baselineFunc_ = nullptr;
|
2023-12-19 13:38:40 -08:00
|
|
|
YGDirtiedFunc dirtiedFunc_ = nullptr;
|
Replace CompactValue with StyleValueHandle and StyleValuePool (#1534)
Summary:
X-link: https://github.com/facebook/react-native/pull/42131
Pull Request resolved: https://github.com/facebook/yoga/pull/1534
Now that the storage method is a hidden implementation detail, this changes the underlying data structure used to store styles, from `CompactValue` (a customized 32-bit float with tag bits), to `StyleValuePool`.
This new structure operates on 16-bit handles, and a shared small buffer. The vast majority of real-world values can be stored directly in the handle, but we allow arbitrary 32 bit (and soon 64-bit) values to be stored, where the handle then becomes an index into the styles buffer.
This results in a real-world memory usage win, while also letting us store the 64-bit values we are wanting to use for math function support (compared to doubling the storage requirements).
This does seem to make style reads slower, which due to their heavy frequency, does have a performance impact observable by synthetics. In an example laying out a tree of 10,000 nodes, we originally read from `StyleValuePool` 2.4 million times.
This originally resulted in a ~10% regression, but when combined with the changes in the last diff, most style reads become simple bitwise operations on the handle, and we are actually 14% faster than before.
| | Before | After | Δ |
| `sizeof(yoga::Style)` | 208B | 144B | -64B/-31% |
| `sizeof(yoga::Node)` | 640B | 576B | -64B/-10% |
| `sizeof(YogaLayoutableShadowNode) ` | 920B | 856B | -64B/-7% |
| `sizeof(YogaLayoutableShadowNode) + sizeof(YogaStylableProps)` | 1296B | 1168B | -128B/-10% |
| `sizeof(ViewShadowNode)` | 920B | 856B | -64B/-7% |
| `sizeof(ViewShadowNode) + sizeof(ViewShadowNodeProps)` | 2000B | 1872B | -128B/-6% |
| "Huge nested layout" microbenchmark (M1 Ultra) | 11.5ms | 9.9ms | -1.6ms/-14% |
| Quest Store C++ heap usage (avg over 10 runs) | 86.2MB | 84.9MB | -1.3MB/-1.5% |
Reviewed By: joevilches
Differential Revision: D52223122
fbshipit-source-id: 990f4b7e991e8e22d198ce20f7da66d9c6ba637b
2024-01-19 18:22:29 -08:00
|
|
|
Style style_;
|
|
|
|
LayoutResults layout_;
|
2023-12-19 13:38:40 -08:00
|
|
|
size_t lineIndex_ = 0;
|
|
|
|
Node* owner_ = nullptr;
|
Replace CompactValue with StyleValueHandle and StyleValuePool (#1534)
Summary:
X-link: https://github.com/facebook/react-native/pull/42131
Pull Request resolved: https://github.com/facebook/yoga/pull/1534
Now that the storage method is a hidden implementation detail, this changes the underlying data structure used to store styles, from `CompactValue` (a customized 32-bit float with tag bits), to `StyleValuePool`.
This new structure operates on 16-bit handles, and a shared small buffer. The vast majority of real-world values can be stored directly in the handle, but we allow arbitrary 32 bit (and soon 64-bit) values to be stored, where the handle then becomes an index into the styles buffer.
This results in a real-world memory usage win, while also letting us store the 64-bit values we are wanting to use for math function support (compared to doubling the storage requirements).
This does seem to make style reads slower, which due to their heavy frequency, does have a performance impact observable by synthetics. In an example laying out a tree of 10,000 nodes, we originally read from `StyleValuePool` 2.4 million times.
This originally resulted in a ~10% regression, but when combined with the changes in the last diff, most style reads become simple bitwise operations on the handle, and we are actually 14% faster than before.
| | Before | After | Δ |
| `sizeof(yoga::Style)` | 208B | 144B | -64B/-31% |
| `sizeof(yoga::Node)` | 640B | 576B | -64B/-10% |
| `sizeof(YogaLayoutableShadowNode) ` | 920B | 856B | -64B/-7% |
| `sizeof(YogaLayoutableShadowNode) + sizeof(YogaStylableProps)` | 1296B | 1168B | -128B/-10% |
| `sizeof(ViewShadowNode)` | 920B | 856B | -64B/-7% |
| `sizeof(ViewShadowNode) + sizeof(ViewShadowNodeProps)` | 2000B | 1872B | -128B/-6% |
| "Huge nested layout" microbenchmark (M1 Ultra) | 11.5ms | 9.9ms | -1.6ms/-14% |
| Quest Store C++ heap usage (avg over 10 runs) | 86.2MB | 84.9MB | -1.3MB/-1.5% |
Reviewed By: joevilches
Differential Revision: D52223122
fbshipit-source-id: 990f4b7e991e8e22d198ce20f7da66d9c6ba637b
2024-01-19 18:22:29 -08:00
|
|
|
std::vector<Node*> children_;
|
2023-12-19 13:38:40 -08:00
|
|
|
const Config* config_;
|
2024-10-01 15:19:22 -07:00
|
|
|
std::array<Style::Length, 2> processedDimensions_{
|
2023-12-19 13:38:40 -08:00
|
|
|
{value::undefined(), value::undefined()}};
|
2017-12-19 11:18:00 -08:00
|
|
|
};
|
C++ Cleanup 3/N: Reorganize YGNode (#1350)
Summary:
X-link: https://github.com/facebook/react-native/pull/39219
Pull Request resolved: https://github.com/facebook/yoga/pull/1350
X-link: https://github.com/facebook/react-native/pull/39170
## This diff
This diff adds a top level `node` directory for code related to Yoga nodes and data structures on them (inc moving `YGLayout` to `LayoutResults`).
The public API for config handles is `YGNodeRef`, which is forward declared to be a pointer to a struct named `YGNode`. The existing `YGNode` is split into `yoga::Node`, as the private C++ implementation, inheriting from `YGNode`, a marker type represented as an empty struct. The public API continues to accept `YGNodeRef`, which continues to be `YGNode *`, but it must be cast to its concrete internal representation at the API boundary before doing work on it.
This change ends up needing to touch quite a bit, due to the amount of code that mixed and matched private and public APIs. Don't be scared though, because these changes are very mechanical, and Phabricator's line-count is 3x the actual amount due to mirrors and dirsyncs.
## This stack
The organization of the C++ internals of Yoga are in need of attention.
1. Some of the C++ internals are namespaced, but others not.
2. Some of the namespaces include `detail`, but are meant to be used outside of the translation unit (FB Clang Tidy rules warn on any usage of these)
2. Most of the files are in a flat hierarchy, except for event tracing in its own folder
3. Some files and functions begin with YG, others don’t
4. Some functions are uppercase, others are not
5. Almost all of the interesting logic is in Yoga.cpp, and the file is too large to reason about
6. There are multiple grab bag files where folks put random functions they need in (Utils, BitUtils, Yoga-Internal.h)
7. There is no clear indication from file structure or type naming what is private vs not
8. Handles like `YGNodeRef` and `YGConfigRef` can be used to access internals just by importing headers
This stack does some much needed spring cleaning:
1. All non-public headers and C++ implementation details are in separate folders from the root level `yoga`. This will give us room to split up logic and add more files without too large a flat hierarchy
3. All private C++ internals are under the `facebook::yoga` namespace. Details namespaces are only ever used within the same header, as they are intended
4. Utils files are split
5. Most C++ internals drop the YG prefix
6. Most C++ internal function names are all lower camel case
7. We start to split up Yoga.cpp
8. Every header beginning with YG or at the top-level directory is public and C only, with the exception of Yoga-Internal.h which has non-public functions for bindings
9. It is not possible to use private APIs without static casting handles to internal classes
This will give us more leeway to continue splitting monolithic files, and consistent guidelines for style in new files as well.
These changes should not be breaking to any project using only public Yoga headers. This includes every usage of Yoga in fbsource except for RN Fabric which is currently tied to internals. This refactor should make that boundary clearer.
Changelog: [Internal]
bypass-github-export-checks
Reviewed By: shwanton
Differential Revision: D48847258
fbshipit-source-id: fc560893533b55a5c2d52c37d8e9a59f7369f174
2023-08-30 19:57:16 -07:00
|
|
|
|
2023-09-11 19:51:40 -07:00
|
|
|
inline Node* resolveRef(const YGNodeRef ref) {
|
|
|
|
return static_cast<Node*>(ref);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline const Node* resolveRef(const YGNodeConstRef ref) {
|
|
|
|
return static_cast<const Node*>(ref);
|
|
|
|
}
|
|
|
|
|
C++ Cleanup 3/N: Reorganize YGNode (#1350)
Summary:
X-link: https://github.com/facebook/react-native/pull/39219
Pull Request resolved: https://github.com/facebook/yoga/pull/1350
X-link: https://github.com/facebook/react-native/pull/39170
## This diff
This diff adds a top level `node` directory for code related to Yoga nodes and data structures on them (inc moving `YGLayout` to `LayoutResults`).
The public API for config handles is `YGNodeRef`, which is forward declared to be a pointer to a struct named `YGNode`. The existing `YGNode` is split into `yoga::Node`, as the private C++ implementation, inheriting from `YGNode`, a marker type represented as an empty struct. The public API continues to accept `YGNodeRef`, which continues to be `YGNode *`, but it must be cast to its concrete internal representation at the API boundary before doing work on it.
This change ends up needing to touch quite a bit, due to the amount of code that mixed and matched private and public APIs. Don't be scared though, because these changes are very mechanical, and Phabricator's line-count is 3x the actual amount due to mirrors and dirsyncs.
## This stack
The organization of the C++ internals of Yoga are in need of attention.
1. Some of the C++ internals are namespaced, but others not.
2. Some of the namespaces include `detail`, but are meant to be used outside of the translation unit (FB Clang Tidy rules warn on any usage of these)
2. Most of the files are in a flat hierarchy, except for event tracing in its own folder
3. Some files and functions begin with YG, others don’t
4. Some functions are uppercase, others are not
5. Almost all of the interesting logic is in Yoga.cpp, and the file is too large to reason about
6. There are multiple grab bag files where folks put random functions they need in (Utils, BitUtils, Yoga-Internal.h)
7. There is no clear indication from file structure or type naming what is private vs not
8. Handles like `YGNodeRef` and `YGConfigRef` can be used to access internals just by importing headers
This stack does some much needed spring cleaning:
1. All non-public headers and C++ implementation details are in separate folders from the root level `yoga`. This will give us room to split up logic and add more files without too large a flat hierarchy
3. All private C++ internals are under the `facebook::yoga` namespace. Details namespaces are only ever used within the same header, as they are intended
4. Utils files are split
5. Most C++ internals drop the YG prefix
6. Most C++ internal function names are all lower camel case
7. We start to split up Yoga.cpp
8. Every header beginning with YG or at the top-level directory is public and C only, with the exception of Yoga-Internal.h which has non-public functions for bindings
9. It is not possible to use private APIs without static casting handles to internal classes
This will give us more leeway to continue splitting monolithic files, and consistent guidelines for style in new files as well.
These changes should not be breaking to any project using only public Yoga headers. This includes every usage of Yoga in fbsource except for RN Fabric which is currently tied to internals. This refactor should make that boundary clearer.
Changelog: [Internal]
bypass-github-export-checks
Reviewed By: shwanton
Differential Revision: D48847258
fbshipit-source-id: fc560893533b55a5c2d52c37d8e9a59f7369f174
2023-08-30 19:57:16 -07:00
|
|
|
} // namespace facebook::yoga
|