Add YGErrata integration within C ABI (#37075)

Summary:
X-link: https://github.com/facebook/react-native/pull/37075

Pull Request resolved: https://github.com/facebook/yoga/pull/1255

This diff wires up YGErrata to a public API, along with existing functions to set UseLegacyStretchBehaviour.

The `UseLegacyStretchBehaviour` functions will be removed after the world internally is transitioned to `YGConfigSetErrata`. This is intentionally breaking, since most users previously enabling `UseLegacyStretchBehaviour` will want to pick a new appropriate errata setting. Internally, users of the API will be moved to`YGErrataAll`.

The overall change looks like:
1. Clean up YGConfig to use accessors/setters
2. Change up YGconfig internal storage
    1. Fabric has a config per ShadowNode, so it makes sense to do some size optimization before adding more (free-form bools to bitfield, `std::array<bool,>` to `std::bitset` since not specialized)
3. Wire accessor/setter of UseLegacyStretchBehaviour to errata while both APIs exist
4. Add errata APIs to C ABI

After this we will need to expose the ABI to more language projections, and (more involved), add usages of the API to internal consumption of Yoga before adding more errata and removing `UseLegacyStretchBehaviour`.

Note that this API representation is similar, but distinct to `YGExperimentalFeature`. I think that API may also have made sense as an enum bitset, like we explicitly want for the new API, but it's not really worth changing the existing API to make that happen.

Reviewed By: rshest

Differential Revision: D45254097

fbshipit-source-id: 5c725ce5a77b25c1356f753d11c468587dbd8ded
This commit is contained in:
Nick Gerleman
2023-04-27 06:48:04 -07:00
committed by Facebook GitHub Bot
parent 36406ce17c
commit fc6485b8cd
6 changed files with 228 additions and 103 deletions

View File

@@ -7,9 +7,75 @@
#include "YGConfig.h"
using namespace facebook::yoga::detail;
YGConfig::YGConfig(YGLogger logger) : cloneNodeCallback_{nullptr} {
setLogger(logger);
}
void YGConfig::setUseWebDefaults(bool useWebDefaults) {
flags_.useWebDefaults = useWebDefaults;
}
bool YGConfig::useWebDefaults() const {
return flags_.useWebDefaults;
}
void YGConfig::setShouldPrintTree(bool printTree) {
flags_.printTree = printTree;
}
bool YGConfig::shouldPrintTree() const {
return flags_.printTree;
}
void YGConfig::setExperimentalFeatureEnabled(
YGExperimentalFeature feature,
bool enabled) {
experimentalFeatures_.set(feature, enabled);
}
bool YGConfig::isExperimentalFeatureEnabled(
YGExperimentalFeature feature) const {
return experimentalFeatures_.test(feature);
}
void YGConfig::setErrata(YGErrata errata) {
errata_ = errata;
}
YGErrata YGConfig::getErrata() const {
return errata_;
}
void YGConfig::setPointScaleFactor(float pointScaleFactor) {
pointScaleFactor_ = pointScaleFactor;
}
float YGConfig::getPointScaleFactor() const {
return pointScaleFactor_;
}
void YGConfig::setContext(void* context) {
context_ = context;
}
void* YGConfig::getContext() const {
return context_;
}
void YGConfig::setLogger(YGLogger logger) {
logger_.noContext = logger;
loggerUsesContext_ = false;
flags_.loggerUsesContext = false;
}
void YGConfig::setLogger(LogWithContextFn logger) {
logger_.withContext = logger;
flags_.loggerUsesContext = true;
}
void YGConfig::setLogger(std::nullptr_t) {
setLogger(YGLogger{nullptr});
}
void YGConfig::log(
@@ -18,22 +84,36 @@ void YGConfig::log(
YGLogLevel logLevel,
void* logContext,
const char* format,
va_list args) {
if (loggerUsesContext_) {
va_list args) const {
if (flags_.loggerUsesContext) {
logger_.withContext(config, node, logLevel, logContext, format, args);
} else {
logger_.noContext(config, node, logLevel, format, args);
}
}
void YGConfig::setCloneNodeCallback(YGCloneNodeFunc cloneNode) {
cloneNodeCallback_.noContext = cloneNode;
flags_.cloneNodeUsesContext = false;
}
void YGConfig::setCloneNodeCallback(CloneWithContextFn cloneNode) {
cloneNodeCallback_.withContext = cloneNode;
flags_.cloneNodeUsesContext = true;
}
void YGConfig::setCloneNodeCallback(std::nullptr_t) {
setCloneNodeCallback(YGCloneNodeFunc{nullptr});
}
YGNodeRef YGConfig::cloneNode(
YGNodeRef node,
YGNodeRef owner,
int childIndex,
void* cloneContext) {
void* cloneContext) const {
YGNodeRef clone = nullptr;
if (cloneNodeCallback_.noContext != nullptr) {
clone = cloneNodeUsesContext_
clone = flags_.cloneNodeUsesContext
? cloneNodeCallback_.withContext(node, owner, childIndex, cloneContext)
: cloneNodeCallback_.noContext(node, owner, childIndex);
}