C++ Cleanup 2/N: Reorganize YGConfig (#39218)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/39218

Pull Request resolved: https://github.com/facebook/react-native/pull/39169

X-link: 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
This commit is contained in:
Nick Gerleman 2023-08-30 16:27:32 -07:00 коммит произвёл Facebook GitHub Bot
Родитель 294a50db93
Коммит a659065840
11 изменённых файлов: 123 добавлений и 110 удалений

Просмотреть файл

@ -19,6 +19,8 @@
// API and use that
#include <yoga/YGNode.h>
using namespace facebook;
using namespace facebook::yoga;
using namespace facebook::yoga::vanillajni;
static inline ScopedLocalRef<jobject> YGNodeJobject(
@ -194,7 +196,7 @@ static void jni_YGConfigSetLoggerJNI(
}
*context = newGlobalRef(env, logger);
config->setLogger(YGJNILogFunc);
static_cast<yoga::Config*>(config)->setLogger(YGJNILogFunc);
} else {
if (context != nullptr) {
delete context;

Просмотреть файл

@ -473,7 +473,7 @@ void YogaLayoutableShadowNode::configureYogaTree(
const auto &child = *yogaLayoutableChildren_[i];
auto childLayoutMetrics = child.getLayoutMetrics();
auto childErrata =
YGConfigGetErrata(const_cast<YGConfigRef>(&child.yogaConfig_));
YGConfigGetErrata(const_cast<yoga::Config *>(&child.yogaConfig_));
if (child.yogaTreeHasBeenConfigured_ &&
childLayoutMetrics.pointScaleFactor == pointScaleFactor &&
@ -834,8 +834,8 @@ YogaLayoutableShadowNode &YogaLayoutableShadowNode::shadowNodeFromContext(
*static_cast<ShadowNode *>(yogaNode->getContext()));
}
YGConfig &YogaLayoutableShadowNode::initializeYogaConfig(
YGConfig &config,
yoga::Config &YogaLayoutableShadowNode::initializeYogaConfig(
yoga::Config &config,
const YGConfigRef previousConfig) {
YGConfigSetCloneNodeFunc(
&config, YogaLayoutableShadowNode::yogaNodeCloneCallbackConnector);

Просмотреть файл

@ -93,7 +93,7 @@ class YogaLayoutableShadowNode : public LayoutableShadowNode {
/*
* Yoga config associated (only) with this particular node.
*/
YGConfig yogaConfig_;
yoga::Config yogaConfig_;
/*
* All Yoga functions only accept non-const arguments, so we have to mark
@ -153,8 +153,8 @@ class YogaLayoutableShadowNode : public LayoutableShadowNode {
*/
YogaLayoutableShadowNode &cloneChildInPlace(int32_t layoutableChildIndex);
static YGConfig &initializeYogaConfig(
YGConfig &config,
static yoga::Config &initializeYogaConfig(
yoga::Config &config,
YGConfigRef previousConfig = nullptr);
static YGNode *yogaNodeCloneCallbackConnector(
YGNode *oldYogaNode,

Просмотреть файл

@ -14,7 +14,7 @@ using namespace facebook;
using namespace facebook::yoga;
using facebook::yoga::CompactValue;
YGNode::YGNode(const YGConfigRef config) : config_{config} {
YGNode::YGNode(yoga::Config* config) : config_{config} {
YGAssert(
config != nullptr, "Attempting to construct YGNode with null config");
@ -264,7 +264,7 @@ void YGNode::insertChild(YGNodeRef child, uint32_t index) {
children_.insert(children_.begin() + index, child);
}
void YGNode::setConfig(YGConfigRef config) {
void YGNode::setConfig(yoga::Config* config) {
YGAssert(config != nullptr, "Attempting to set a null config on a YGNode");
YGAssertWithConfig(
config,

Просмотреть файл

@ -9,15 +9,13 @@
#include <cstdint>
#include <stdio.h>
#include "YGConfig.h"
#include <yoga/config/Config.h>
#include "YGLayout.h"
#include <yoga/Yoga-internal.h>
#include <yoga/style/CompactValue.h>
#include <yoga/style/Style.h>
YGConfigRef YGConfigGetDefault();
#pragma pack(push)
#pragma pack(1)
struct YGNodeFlags {
@ -58,7 +56,7 @@ private:
uint32_t lineIndex_ = 0;
YGNodeRef owner_ = nullptr;
YGVector children_ = {};
YGConfigRef config_;
facebook::yoga::Config* config_;
std::array<YGValue, 2> resolvedDimensions_ = {
{YGValueUndefined, YGValueUndefined}};
@ -84,8 +82,11 @@ private:
using CompactValue = facebook::yoga::CompactValue;
public:
YGNode() : YGNode{YGConfigGetDefault()} { flags_.hasNewLayout = true; }
explicit YGNode(const YGConfigRef config);
YGNode()
: YGNode{static_cast<facebook::yoga::Config*>(YGConfigGetDefault())} {
flags_.hasNewLayout = true;
}
explicit YGNode(facebook::yoga::Config* config);
~YGNode() = default; // cleanup of owner/children relationships in YGNodeFree
YGNode(YGNode&&);
@ -166,7 +167,7 @@ public:
YGNodeRef getChild(uint32_t index) const { return children_.at(index); }
YGConfigRef getConfig() const { return config_; }
facebook::yoga::Config* getConfig() const { return config_; }
bool isDirty() const { return flags_.isDirty; }
@ -290,7 +291,7 @@ public:
// TODO: rvalue override for setChildren
void setConfig(YGConfigRef config);
void setConfig(facebook::yoga::Config* config);
void setDirty(bool isDirty);
void setLayoutLastOwnerDirection(YGDirection direction);

Просмотреть файл

@ -20,6 +20,7 @@
#include <yoga/Yoga-internal.h>
#include "event/event.h"
using namespace facebook;
using namespace facebook::yoga;
using detail::Log;
@ -119,7 +120,7 @@ YOGA_EXPORT YGConfigRef YGNodeGetConfig(YGNodeRef node) {
}
YOGA_EXPORT void YGNodeSetConfig(YGNodeRef node, YGConfigRef config) {
node->setConfig(config);
node->setConfig(static_cast<yoga::Config*>(config));
}
YOGA_EXPORT bool YGNodeHasMeasureFunc(YGNodeRef node) {
@ -161,7 +162,7 @@ YOGA_EXPORT bool YGNodeGetHasNewLayout(YGNodeRef node) {
}
YOGA_EXPORT void YGConfigSetPrintTreeFlag(YGConfigRef config, bool enabled) {
config->setShouldPrintTree(enabled);
static_cast<yoga::Config*>(config)->setShouldPrintTree(enabled);
}
YOGA_EXPORT void YGNodeSetHasNewLayout(YGNodeRef node, bool hasNewLayout) {
@ -188,7 +189,7 @@ YOGA_EXPORT void YGNodeMarkDirtyAndPropagateToDescendants(
int32_t gConfigInstanceCount = 0;
YOGA_EXPORT WIN_EXPORT YGNodeRef YGNodeNewWithConfig(const YGConfigRef config) {
const YGNodeRef node = new YGNode{config};
const YGNodeRef node = new YGNode{static_cast<yoga::Config*>(config)};
YGAssert(config != nullptr, "Tried to construct YGNode with null config");
YGAssertWithConfig(
config, node != nullptr, "Could not allocate memory for node");
@ -272,23 +273,19 @@ YOGA_EXPORT int32_t YGConfigGetInstanceCount(void) {
YOGA_EXPORT YGConfigRef YGConfigNew(void) {
#ifdef ANDROID
const YGConfigRef config = new YGConfig(YGAndroidLog);
const YGConfigRef config = new yoga::Config(YGAndroidLog);
#else
const YGConfigRef config = new YGConfig(YGDefaultLog);
const YGConfigRef config = new yoga::Config(YGDefaultLog);
#endif
gConfigInstanceCount++;
return config;
}
YOGA_EXPORT void YGConfigFree(const YGConfigRef config) {
delete config;
delete static_cast<yoga::Config*>(config);
gConfigInstanceCount--;
}
void YGConfigCopy(const YGConfigRef dest, const YGConfigRef src) {
memcpy(dest, src, sizeof(YGConfig));
}
YOGA_EXPORT void YGNodeSetIsReferenceBaseline(
YGNodeRef node,
bool isReferenceBaseline) {
@ -3715,22 +3712,22 @@ YOGA_EXPORT bool YGNodeCanUseCachedMeasurement(
return false;
}
bool useRoundedComparison =
config != nullptr && config->getPointScaleFactor() != 0;
config != nullptr && YGConfigGetPointScaleFactor(config) != 0;
const float effectiveWidth = useRoundedComparison
? YGRoundValueToPixelGrid(
width, config->getPointScaleFactor(), false, false)
width, YGConfigGetPointScaleFactor(config), false, false)
: width;
const float effectiveHeight = useRoundedComparison
? YGRoundValueToPixelGrid(
height, config->getPointScaleFactor(), false, false)
height, YGConfigGetPointScaleFactor(config), false, false)
: height;
const float effectiveLastWidth = useRoundedComparison
? YGRoundValueToPixelGrid(
lastWidth, config->getPointScaleFactor(), false, false)
lastWidth, YGConfigGetPointScaleFactor(config), false, false)
: lastWidth;
const float effectiveLastHeight = useRoundedComparison
? YGRoundValueToPixelGrid(
lastHeight, config->getPointScaleFactor(), false, false)
lastHeight, YGConfigGetPointScaleFactor(config), false, false)
: lastHeight;
const bool hasSameWidthSpec = lastWidthMode == widthMode &&
@ -4057,14 +4054,14 @@ YOGA_EXPORT void YGConfigSetPointScaleFactor(
// We store points for Pixel as we will use it for rounding
if (pixelsInPoint == 0.0f) {
// Zero is used to skip rounding
config->setPointScaleFactor(0.0f);
static_cast<yoga::Config*>(config)->setPointScaleFactor(0.0f);
} else {
config->setPointScaleFactor(pixelsInPoint);
static_cast<yoga::Config*>(config)->setPointScaleFactor(pixelsInPoint);
}
}
YOGA_EXPORT float YGConfigGetPointScaleFactor(const YGConfigRef config) {
return config->getPointScaleFactor();
return static_cast<yoga::Config*>(config)->getPointScaleFactor();
}
static void YGRoundToPixelGrid(
@ -4239,12 +4236,12 @@ YOGA_EXPORT void YGNodeCalculateLayout(
YOGA_EXPORT void YGConfigSetLogger(const YGConfigRef config, YGLogger logger) {
if (logger != nullptr) {
config->setLogger(logger);
static_cast<yoga::Config*>(config)->setLogger(logger);
} else {
#ifdef ANDROID
config->setLogger(&YGAndroidLog);
static_cast<yoga::Config*>(config)->setLogger(&YGAndroidLog);
#else
config->setLogger(&YGDefaultLog);
static_cast<yoga::Config*>(config)->setLogger(&YGDefaultLog);
#endif
}
}
@ -4271,7 +4268,12 @@ void YGAssertWithConfig(
const bool condition,
const char* message) {
if (!condition) {
Log::log(config, YGLogLevelFatal, nullptr, "%s\n", message);
Log::log(
static_cast<yoga::Config*>(config),
YGLogLevelFatal,
nullptr,
"%s\n",
message);
throwLogicalErrorWithMessage(message);
}
}
@ -4280,58 +4282,61 @@ YOGA_EXPORT void YGConfigSetExperimentalFeatureEnabled(
const YGConfigRef config,
const YGExperimentalFeature feature,
const bool enabled) {
config->setExperimentalFeatureEnabled(feature, enabled);
static_cast<yoga::Config*>(config)->setExperimentalFeatureEnabled(
feature, enabled);
}
YOGA_EXPORT bool YGConfigIsExperimentalFeatureEnabled(
const YGConfigRef config,
const YGExperimentalFeature feature) {
return config->isExperimentalFeatureEnabled(feature);
return static_cast<yoga::Config*>(config)->isExperimentalFeatureEnabled(
feature);
}
YOGA_EXPORT void YGConfigSetUseWebDefaults(
const YGConfigRef config,
const bool enabled) {
config->setUseWebDefaults(enabled);
static_cast<yoga::Config*>(config)->setUseWebDefaults(enabled);
}
YOGA_EXPORT bool YGConfigGetUseLegacyStretchBehaviour(
const YGConfigRef config) {
return config->hasErrata(YGErrataStretchFlexBasis);
return static_cast<yoga::Config*>(config)->hasErrata(
YGErrataStretchFlexBasis);
}
YOGA_EXPORT void YGConfigSetUseLegacyStretchBehaviour(
const YGConfigRef config,
const bool useLegacyStretchBehaviour) {
if (useLegacyStretchBehaviour) {
config->addErrata(YGErrataStretchFlexBasis);
static_cast<yoga::Config*>(config)->addErrata(YGErrataStretchFlexBasis);
} else {
config->removeErrata(YGErrataStretchFlexBasis);
static_cast<yoga::Config*>(config)->removeErrata(YGErrataStretchFlexBasis);
}
}
bool YGConfigGetUseWebDefaults(const YGConfigRef config) {
return config->useWebDefaults();
return static_cast<yoga::Config*>(config)->useWebDefaults();
}
YOGA_EXPORT void YGConfigSetContext(const YGConfigRef config, void* context) {
config->setContext(context);
static_cast<yoga::Config*>(config)->setContext(context);
}
YOGA_EXPORT void* YGConfigGetContext(const YGConfigRef config) {
return config->getContext();
return static_cast<yoga::Config*>(config)->getContext();
}
YOGA_EXPORT void YGConfigSetErrata(YGConfigRef config, YGErrata errata) {
config->setErrata(errata);
static_cast<yoga::Config*>(config)->setErrata(errata);
}
YOGA_EXPORT YGErrata YGConfigGetErrata(YGConfigRef config) {
return config->getErrata();
return static_cast<yoga::Config*>(config)->getErrata();
}
YOGA_EXPORT void YGConfigSetCloneNodeFunc(
const YGConfigRef config,
const YGCloneNodeFunc callback) {
config->setCloneNodeCallback(callback);
static_cast<yoga::Config*>(config)->setCloneNodeCallback(callback);
}

Просмотреть файл

@ -343,7 +343,6 @@ void YGConfigSetUseLegacyStretchBehaviour(
// YGConfig
WIN_EXPORT YGConfigRef YGConfigNew(void);
WIN_EXPORT void YGConfigFree(YGConfigRef config);
WIN_EXPORT void YGConfigCopy(YGConfigRef dest, YGConfigRef src);
WIN_EXPORT int32_t YGConfigGetInstanceCount(void);
WIN_EXPORT void YGConfigSetExperimentalFeatureEnabled(

Просмотреть файл

@ -5,133 +5,129 @@
* LICENSE file in the root directory of this source tree.
*/
#include "YGConfig.h"
using namespace facebook::yoga;
#include <yoga/config/Config.h>
namespace facebook::yoga {
bool configUpdateInvalidatesLayout(YGConfigRef a, YGConfigRef b) {
bool configUpdateInvalidatesLayout(Config* a, Config* b) {
return a->getErrata() != b->getErrata() ||
a->getEnabledExperiments() != b->getEnabledExperiments() ||
a->getPointScaleFactor() != b->getPointScaleFactor() ||
a->useWebDefaults() != b->useWebDefaults();
}
} // namespace facebook::yoga
YGConfig::YGConfig(YGLogger logger) : cloneNodeCallback_{nullptr} {
Config::Config(YGLogger logger) : cloneNodeCallback_{nullptr} {
setLogger(logger);
}
void YGConfig::setUseWebDefaults(bool useWebDefaults) {
void Config::setUseWebDefaults(bool useWebDefaults) {
flags_.useWebDefaults = useWebDefaults;
}
bool YGConfig::useWebDefaults() const {
bool Config::useWebDefaults() const {
return flags_.useWebDefaults;
}
void YGConfig::setShouldPrintTree(bool printTree) {
void Config::setShouldPrintTree(bool printTree) {
flags_.printTree = printTree;
}
bool YGConfig::shouldPrintTree() const {
bool Config::shouldPrintTree() const {
return flags_.printTree;
}
void YGConfig::setExperimentalFeatureEnabled(
void Config::setExperimentalFeatureEnabled(
YGExperimentalFeature feature,
bool enabled) {
experimentalFeatures_.set(feature, enabled);
}
bool YGConfig::isExperimentalFeatureEnabled(
YGExperimentalFeature feature) const {
bool Config::isExperimentalFeatureEnabled(YGExperimentalFeature feature) const {
return experimentalFeatures_.test(feature);
}
ExperimentalFeatureSet YGConfig::getEnabledExperiments() const {
ExperimentalFeatureSet Config::getEnabledExperiments() const {
return experimentalFeatures_;
}
void YGConfig::setErrata(YGErrata errata) {
void Config::setErrata(YGErrata errata) {
errata_ = errata;
}
void YGConfig::addErrata(YGErrata errata) {
void Config::addErrata(YGErrata errata) {
errata_ |= errata;
}
void YGConfig::removeErrata(YGErrata errata) {
void Config::removeErrata(YGErrata errata) {
errata_ &= (~errata);
}
YGErrata YGConfig::getErrata() const {
YGErrata Config::getErrata() const {
return errata_;
}
bool YGConfig::hasErrata(YGErrata errata) const {
bool Config::hasErrata(YGErrata errata) const {
return (errata_ & errata) != YGErrataNone;
}
void YGConfig::setPointScaleFactor(float pointScaleFactor) {
void Config::setPointScaleFactor(float pointScaleFactor) {
pointScaleFactor_ = pointScaleFactor;
}
float YGConfig::getPointScaleFactor() const {
float Config::getPointScaleFactor() const {
return pointScaleFactor_;
}
void YGConfig::setContext(void* context) {
void Config::setContext(void* context) {
context_ = context;
}
void* YGConfig::getContext() const {
void* Config::getContext() const {
return context_;
}
void YGConfig::setLogger(YGLogger logger) {
void Config::setLogger(YGLogger logger) {
logger_.noContext = logger;
flags_.loggerUsesContext = false;
}
void YGConfig::setLogger(LogWithContextFn logger) {
void Config::setLogger(LogWithContextFn logger) {
logger_.withContext = logger;
flags_.loggerUsesContext = true;
}
void YGConfig::setLogger(std::nullptr_t) {
void Config::setLogger(std::nullptr_t) {
setLogger(YGLogger{nullptr});
}
void YGConfig::log(
YGConfig* config,
YGNode* node,
void Config::log(
YGNodeRef node,
YGLogLevel logLevel,
void* logContext,
const char* format,
va_list args) const {
va_list args) {
if (flags_.loggerUsesContext) {
logger_.withContext(config, node, logLevel, logContext, format, args);
logger_.withContext(this, node, logLevel, logContext, format, args);
} else {
logger_.noContext(config, node, logLevel, format, args);
logger_.noContext(this, node, logLevel, format, args);
}
}
void YGConfig::setCloneNodeCallback(YGCloneNodeFunc cloneNode) {
void Config::setCloneNodeCallback(YGCloneNodeFunc cloneNode) {
cloneNodeCallback_.noContext = cloneNode;
flags_.cloneNodeUsesContext = false;
}
void YGConfig::setCloneNodeCallback(CloneWithContextFn cloneNode) {
void Config::setCloneNodeCallback(CloneWithContextFn cloneNode) {
cloneNodeCallback_.withContext = cloneNode;
flags_.cloneNodeUsesContext = true;
}
void YGConfig::setCloneNodeCallback(std::nullptr_t) {
void Config::setCloneNodeCallback(std::nullptr_t) {
setCloneNodeCallback(YGCloneNodeFunc{nullptr});
}
YGNodeRef YGConfig::cloneNode(
YGNodeRef Config::cloneNode(
YGNodeRef node,
YGNodeRef owner,
int childIndex,
@ -147,3 +143,5 @@ YGNodeRef YGConfig::cloneNode(
}
return clone;
}
} // namespace facebook::yoga

Просмотреть файл

@ -12,11 +12,16 @@
#include <yoga/BitUtils.h>
#include <yoga/Yoga-internal.h>
// Tag struct used to form the opaque YGConfigRef for the public C API
struct YGConfig {};
namespace facebook::yoga {
class Config;
// Whether moving a node from config "a" to config "b" should dirty previously
// calculated layout results.
bool configUpdateInvalidatesLayout(YGConfigRef a, YGConfigRef b);
bool configUpdateInvalidatesLayout(Config* a, Config* b);
// Internal variants of log functions, currently used only by JNI bindings.
// TODO: Reconcile this with the public API
@ -33,13 +38,12 @@ using CloneWithContextFn = YGNodeRef (*)(
int childIndex,
void* cloneContext);
using ExperimentalFeatureSet =
facebook::yoga::detail::EnumBitset<YGExperimentalFeature>;
using ExperimentalFeatureSet = detail::EnumBitset<YGExperimentalFeature>;
#pragma pack(push)
#pragma pack(1)
// Packed structure of <32-bit options to miminize size per node.
struct YGConfigFlags {
struct ConfigFlags {
bool useWebDefaults : 1;
bool printTree : 1;
bool cloneNodeUsesContext : 1;
@ -47,10 +51,9 @@ struct YGConfigFlags {
};
#pragma pack(pop)
} // namespace facebook::yoga
struct YOGA_EXPORT YGConfig {
YGConfig(YGLogger logger);
class YOGA_EXPORT Config : public ::YGConfig {
public:
Config(YGLogger logger);
void setUseWebDefaults(bool useWebDefaults);
bool useWebDefaults() const;
@ -62,7 +65,7 @@ struct YOGA_EXPORT YGConfig {
YGExperimentalFeature feature,
bool enabled);
bool isExperimentalFeatureEnabled(YGExperimentalFeature feature) const;
facebook::yoga::ExperimentalFeatureSet getEnabledExperiments() const;
ExperimentalFeatureSet getEnabledExperiments() const;
void setErrata(YGErrata errata);
void addErrata(YGErrata errata);
@ -77,12 +80,12 @@ struct YOGA_EXPORT YGConfig {
void* getContext() const;
void setLogger(YGLogger logger);
void setLogger(facebook::yoga::LogWithContextFn logger);
void setLogger(LogWithContextFn logger);
void setLogger(std::nullptr_t);
void log(YGConfig*, YGNode*, YGLogLevel, void*, const char*, va_list) const;
void log(YGNodeRef, YGLogLevel, void*, const char*, va_list);
void setCloneNodeCallback(YGCloneNodeFunc cloneNode);
void setCloneNodeCallback(facebook::yoga::CloneWithContextFn cloneNode);
void setCloneNodeCallback(CloneWithContextFn cloneNode);
void setCloneNodeCallback(std::nullptr_t);
YGNodeRef cloneNode(
YGNodeRef node,
@ -92,17 +95,19 @@ struct YOGA_EXPORT YGConfig {
private:
union {
facebook::yoga::CloneWithContextFn withContext;
CloneWithContextFn withContext;
YGCloneNodeFunc noContext;
} cloneNodeCallback_;
union {
facebook::yoga::LogWithContextFn withContext;
LogWithContextFn withContext;
YGLogger noContext;
} logger_;
facebook::yoga::YGConfigFlags flags_{};
facebook::yoga::ExperimentalFeatureSet experimentalFeatures_{};
ConfigFlags flags_{};
ExperimentalFeatureSet experimentalFeatures_{};
YGErrata errata_ = YGErrataNone;
float pointScaleFactor_ = 1.0f;
void* context_ = nullptr;
};
} // namespace facebook::yoga

Просмотреть файл

@ -8,7 +8,7 @@
#include <yoga/Yoga.h>
#include "log.h"
#include "YGConfig.h"
#include <yoga/config/Config.h>
#include "YGNode.h"
namespace facebook::yoga::detail {
@ -16,14 +16,16 @@ namespace facebook::yoga::detail {
namespace {
void vlog(
YGConfig* config,
yoga::Config* config,
YGNode* node,
YGLogLevel level,
void* context,
const char* format,
va_list args) {
YGConfig* logConfig = config != nullptr ? config : YGConfigGetDefault();
logConfig->log(logConfig, node, level, context, format, args);
yoga::Config* logConfig = config != nullptr
? config
: static_cast<yoga::Config*>(YGConfigGetDefault());
logConfig->log(node, level, context, format, args);
}
} // namespace
@ -46,7 +48,7 @@ YOGA_EXPORT void Log::log(
}
void Log::log(
YGConfig* config,
yoga::Config* config,
YGLogLevel level,
void* context,
const char* format,

Просмотреть файл

@ -8,6 +8,7 @@
#pragma once
#include <yoga/YGEnums.h>
#include <yoga/config/Config.h>
struct YGNode;
struct YGConfig;
@ -23,7 +24,7 @@ struct Log {
...) noexcept;
static void log(
YGConfig* config,
yoga::Config* config,
YGLogLevel level,
void*,
const char* format,