From 73b8cb212cf1d5ed2f966c224210e7dae8dd09f0 Mon Sep 17 00:00:00 2001 From: Nick Gerleman Date: Tue, 29 Aug 2023 21:30:39 -0700 Subject: [PATCH] C++ Cleanup 4/N: Reorganize Log and YGNodePrint (#1354) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: Pull Request resolved: https://github.com/facebook/yoga/pull/1354 X-link: https://github.com/facebook/react-native/pull/39197 ## This diff Moves these files to a `yoga/debug` subdirectory and does some mild renaming, namespace adjustment, and removes Yoga internal log function from list of library exports. ## 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: D48763820 fbshipit-source-id: 0db57ac19cea25806a914635eddc1eb1a760f783 --- yoga/Yoga.cpp | 30 +++++++------- yoga/{log.cpp => debug/Log.cpp} | 14 +++---- yoga/debug/Log.h | 30 ++++++++++++++ .../NodeToString.cpp} | 41 +++++++++---------- yoga/{YGNodePrint.h => debug/NodeToString.h} | 2 +- yoga/log.h | 32 --------------- 6 files changed, 71 insertions(+), 78 deletions(-) rename yoga/{log.cpp => debug/Log.cpp} (83%) create mode 100644 yoga/debug/Log.h rename yoga/{YGNodePrint.cpp => debug/NodeToString.cpp} (90%) rename yoga/{YGNodePrint.h => debug/NodeToString.h} (95%) delete mode 100644 yoga/log.h diff --git a/yoga/Yoga.cpp b/yoga/Yoga.cpp index eb84c47a40..c150be61da 100644 --- a/yoga/Yoga.cpp +++ b/yoga/Yoga.cpp @@ -13,16 +13,15 @@ #include -#include "log.h" +#include +#include #include #include -#include "YGNodePrint.h" #include #include "event/event.h" using namespace facebook; using namespace facebook::yoga; -using detail::Log; #ifdef ANDROID static int YGAndroidLog( @@ -1005,8 +1004,8 @@ YOGA_EXPORT void YGNodePrint( const YGPrintOptions options) { const auto node = static_cast(nodeRef); std::string str; - facebook::yoga::YGNodeToString(str, node, options, 0); - Log::log(node, YGLogLevelDebug, nullptr, str.c_str()); + yoga::nodeToString(str, node, options, 0); + yoga::log(node, YGLogLevelDebug, nullptr, str.c_str()); } #endif @@ -3939,7 +3938,7 @@ bool YGLayoutNodeInternal( : layoutMarkerData.cachedMeasures) += 1; if (gPrintChanges && gPrintSkips) { - Log::log( + yoga::log( node, YGLogLevelVerbose, nullptr, @@ -3947,7 +3946,7 @@ bool YGLayoutNodeInternal( YGSpacer(depth), depth); node->print(layoutContext); - Log::log( + yoga::log( node, YGLogLevelVerbose, nullptr, @@ -3962,7 +3961,7 @@ bool YGLayoutNodeInternal( } } else { if (gPrintChanges) { - Log::log( + yoga::log( node, YGLogLevelVerbose, nullptr, @@ -3971,7 +3970,7 @@ bool YGLayoutNodeInternal( depth, needToVisitNode ? "*" : ""); node->print(layoutContext); - Log::log( + yoga::log( node, YGLogLevelVerbose, nullptr, @@ -4001,7 +4000,7 @@ bool YGLayoutNodeInternal( reason); if (gPrintChanges) { - Log::log( + yoga::log( node, YGLogLevelVerbose, nullptr, @@ -4010,7 +4009,7 @@ bool YGLayoutNodeInternal( depth, needToVisitNode ? "*" : ""); node->print(layoutContext); - Log::log( + yoga::log( node, YGLogLevelVerbose, nullptr, @@ -4032,7 +4031,8 @@ bool YGLayoutNodeInternal( } if (layout->nextCachedMeasurementsIndex == YG_MAX_CACHED_RESULT_COUNT) { if (gPrintChanges) { - Log::log(node, YGLogLevelVerbose, nullptr, "Out of cache entries!\n"); + yoga::log( + node, YGLogLevelVerbose, nullptr, "Out of cache entries!\n"); } layout->nextCachedMeasurementsIndex = 0; } @@ -4290,7 +4290,7 @@ YOGA_EXPORT void YGConfigSetLogger(const YGConfigRef config, YGLogger logger) { void YGAssert(const bool condition, const char* message) { if (!condition) { - Log::log( + yoga::log( static_cast(nullptr), YGLogLevelFatal, nullptr, @@ -4305,7 +4305,7 @@ void YGAssertWithNode( const bool condition, const char* message) { if (!condition) { - Log::log( + yoga::log( static_cast(node), YGLogLevelFatal, nullptr, @@ -4320,7 +4320,7 @@ void YGAssertWithConfig( const bool condition, const char* message) { if (!condition) { - Log::log( + yoga::log( static_cast(config), YGLogLevelFatal, nullptr, diff --git a/yoga/log.cpp b/yoga/debug/Log.cpp similarity index 83% rename from yoga/log.cpp rename to yoga/debug/Log.cpp index 3dc62c517d..f3d704aa71 100644 --- a/yoga/log.cpp +++ b/yoga/debug/Log.cpp @@ -5,13 +5,9 @@ * LICENSE file in the root directory of this source tree. */ -#include +#include -#include "log.h" -#include -#include - -namespace facebook::yoga::detail { +namespace facebook::yoga { namespace { @@ -29,7 +25,7 @@ void vlog( } } // namespace -YOGA_EXPORT void Log::log( +void log( yoga::Node* node, YGLogLevel level, void* context, @@ -47,7 +43,7 @@ YOGA_EXPORT void Log::log( va_end(args); } -void Log::log( +void log( yoga::Config* config, YGLogLevel level, void* context, @@ -59,4 +55,4 @@ void Log::log( va_end(args); } -} // namespace facebook::yoga::detail +} // namespace facebook::yoga diff --git a/yoga/debug/Log.h b/yoga/debug/Log.h new file mode 100644 index 0000000000..dd4db2f4d1 --- /dev/null +++ b/yoga/debug/Log.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include +#include + +namespace facebook::yoga { + +void log( + yoga::Node* node, + YGLogLevel level, + void*, + const char* message, + ...) noexcept; + +void log( + yoga::Config* config, + YGLogLevel level, + void*, + const char* format, + ...) noexcept; + +} // namespace facebook::yoga diff --git a/yoga/YGNodePrint.cpp b/yoga/debug/NodeToString.cpp similarity index 90% rename from yoga/YGNodePrint.cpp rename to yoga/debug/NodeToString.cpp index d76aa26fb9..b3d6986dbe 100644 --- a/yoga/YGNodePrint.cpp +++ b/yoga/debug/NodeToString.cpp @@ -11,14 +11,13 @@ #include -#include "YGNodePrint.h" +#include #include #include namespace facebook::yoga { -typedef std::string string; -static void indent(string& base, uint32_t level) { +static void indent(std::string& base, uint32_t level) { for (uint32_t i = 0; i < level; ++i) { base.append(" "); } @@ -29,7 +28,7 @@ static bool areFourValuesEqual(const Style::Edges& four) { YGValueEqual(four[0], four[3]); } -static void appendFormattedString(string& str, const char* fmt, ...) { +static void appendFormattedString(std::string& str, const char* fmt, ...) { va_list args; va_start(args, fmt); va_list argsCopy; @@ -38,13 +37,13 @@ static void appendFormattedString(string& str, const char* fmt, ...) { va_end(args); vsnprintf(buf.data(), buf.size(), fmt, argsCopy); va_end(argsCopy); - string result = string(buf.begin(), buf.end() - 1); + std::string result = std::string(buf.begin(), buf.end() - 1); str.append(result); } static void appendFloatOptionalIfDefined( - string& base, - const string key, + std::string& base, + const std::string key, const YGFloatOptional num) { if (!num.isUndefined()) { appendFormattedString(base, "%s: %g; ", key.c_str(), num.unwrap()); @@ -52,14 +51,14 @@ static void appendFloatOptionalIfDefined( } static void appendNumberIfNotUndefined( - string& base, - const string key, + std::string& base, + const std::string key, const YGValue number) { if (number.unit != YGUnitUndefined) { if (number.unit == YGUnitAuto) { base.append(key + ": auto; "); } else { - string unit = number.unit == YGUnitPoint ? "px" : "%%"; + std::string unit = number.unit == YGUnitPoint ? "px" : "%%"; appendFormattedString( base, "%s: %g%s; ", key.c_str(), number.value, unit.c_str()); } @@ -67,8 +66,8 @@ static void appendNumberIfNotUndefined( } static void appendNumberIfNotAuto( - string& base, - const string& key, + std::string& base, + const std::string& key, const YGValue number) { if (number.unit != YGUnitAuto) { appendNumberIfNotUndefined(base, key, number); @@ -76,8 +75,8 @@ static void appendNumberIfNotAuto( } static void appendNumberIfNotZero( - string& base, - const string& str, + std::string& base, + const std::string& str, const YGValue number) { if (number.unit == YGUnitAuto) { base.append(str + ": auto; "); @@ -87,8 +86,8 @@ static void appendNumberIfNotZero( } static void appendEdges( - string& base, - const string& key, + std::string& base, + const std::string& key, const Style::Edges& edges) { if (areFourValuesEqual(edges)) { auto edgeValue = yoga::Node::computeEdgeValueForColumn( @@ -96,15 +95,15 @@ static void appendEdges( appendNumberIfNotZero(base, key, edgeValue); } else { for (int edge = YGEdgeLeft; edge != YGEdgeAll; ++edge) { - string str = key + "-" + YGEdgeToString(static_cast(edge)); + std::string str = key + "-" + YGEdgeToString(static_cast(edge)); appendNumberIfNotZero(base, str, edges[edge]); } } } static void appendEdgeIfNotUndefined( - string& base, - const string& str, + std::string& base, + const std::string& str, const Style::Edges& edges, const YGEdge edge) { // TODO: this doesn't take RTL / YGEdgeStart / YGEdgeEnd into account @@ -116,7 +115,7 @@ static void appendEdgeIfNotUndefined( appendNumberIfNotUndefined(base, str, value); } -void YGNodeToString( +void nodeToString( std::string& str, yoga::Node* node, YGPrintOptions options, @@ -232,7 +231,7 @@ void YGNodeToString( if (options & YGPrintOptionsChildren && childCount > 0) { for (uint32_t i = 0; i < childCount; i++) { appendFormattedString(str, "\n"); - YGNodeToString(str, node->getChild(i), options, level + 1); + nodeToString(str, node->getChild(i), options, level + 1); } appendFormattedString(str, "\n"); indent(str, level); diff --git a/yoga/YGNodePrint.h b/yoga/debug/NodeToString.h similarity index 95% rename from yoga/YGNodePrint.h rename to yoga/debug/NodeToString.h index b991c41a7f..c00439b33a 100644 --- a/yoga/YGNodePrint.h +++ b/yoga/debug/NodeToString.h @@ -16,7 +16,7 @@ namespace facebook::yoga { -void YGNodeToString( +void nodeToString( std::string& str, yoga::Node* node, YGPrintOptions options, diff --git a/yoga/log.h b/yoga/log.h deleted file mode 100644 index 3d468ae10c..0000000000 --- a/yoga/log.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#pragma once - -#include -#include -#include - -namespace facebook::yoga::detail { - -struct Log { - static void log( - yoga::Node* node, - YGLogLevel level, - void*, - const char* message, - ...) noexcept; - - static void log( - yoga::Config* config, - YGLogLevel level, - void*, - const char* format, - ...) noexcept; -}; - -} // namespace facebook::yoga::detail