Optimize log print by using html format

Summary:
See facebook/yoga#453. Optimizes the node log print by generating some enum text via ```enum.py``` and moving printing to new functions to reduce boilerplate code.

Changes the log output to format the nodes in html to be able to copy paste it  into browsers for quick debugging.

Hides all default values.
Closes https://github.com/facebook/yoga/pull/479

Reviewed By: gkassabli

Differential Revision: D4802184

Pulled By: emilsjolander

fbshipit-source-id: 143bd63cbc31fb0755d711062cb4e6a448049ba3
This commit is contained in:
Lukas Wöhrl
2017-04-03 09:34:42 -07:00
committed by Facebook Github Bot
parent 5112564f08
commit 586b57009a
8 changed files with 443 additions and 153 deletions

View File

@@ -255,7 +255,7 @@ namespace Facebook.Yoga
parent.Insert(0, child0); parent.Insert(0, child0);
parent.Insert(0, child1); parent.Insert(0, child1);
parent.CalculateLayout(); parent.CalculateLayout();
Assert.AreEqual("{layout: {width: 100, height: 120, top: 0, left: 0}, flexDirection: 'column', alignItems: 'stretch', flexGrow: 0, flexShrink: 0, flexBasis: nan%, overflow: 'visible', width: 100pt, height: 120pt, children: [\n {layout: {width: 35, height: 45, top: 0, left: 0}, flexDirection: 'column', alignItems: 'stretch', flexGrow: 0, flexShrink: 0, flexBasis: nan%, overflow: 'visible', width: 35pt, height: 45pt, },\n {layout: {width: 30, height: 40, top: 45, left: 0}, flexDirection: 'column', alignItems: 'stretch', flexGrow: 0, flexShrink: 0, flexBasis: nan%, overflow: 'visible', width: 30pt, height: 40pt, },\n]},\n", parent.Print()); Assert.AreEqual("<div layout=\"width: 100; height: 120; top: 0; left: 0;\" style=\"width: 100px; height: 120px; \" >\n <div layout=\"width: 35; height: 45; top: 0; left: 0;\" style=\"width: 35px; height: 45px; \" ></div>\n <div layout=\"width: 30; height: 40; top: 45; left: 0;\" style=\"width: 30px; height: 40px; \" ></div>\n</div>", parent.Print());
} }
[Test] [Test]

View File

@@ -125,6 +125,16 @@ def to_java_upper(symbol):
out += c.upper() out += c.upper()
return out return out
def to_log_lower(symbol):
symbol = str(symbol)
out = ''
for i in range(0, len(symbol)):
c = symbol[i]
if str.istitle(c) and i is not 0 and not str.istitle(symbol[i - 1]):
out += '-'
out += c.lower()
return out
root = os.path.dirname(os.path.abspath(__file__)) root = os.path.dirname(os.path.abspath(__file__))
@@ -143,9 +153,28 @@ with open(root + '/yoga/YGEnums.h', 'w') as f:
else: else:
f.write(' YG%s%s,\n' % (name, value)) f.write(' YG%s%s,\n' % (name, value))
f.write('} YG_ENUM_END(YG%s);\n' % name) f.write('} YG_ENUM_END(YG%s);\n' % name)
f.write('WIN_EXPORT const char *YG%sToString(const YG%s value);\n' % (name, name))
f.write('\n') f.write('\n')
f.write('YG_EXTERN_C_END\n') f.write('YG_EXTERN_C_END\n')
# write out C body for printing
with open(root + '/yoga/YGEnums.c', 'w') as f:
f.write(LICENSE)
f.write('#include "YGEnums.h"\n\n')
for name, values in sorted(ENUMS.items()):
f.write('const char *YG%sToString(const YG%s value){\n' % (name, name))
f.write(' switch(value){\n')
for value in values:
if isinstance(value, tuple):
f.write(' case YG%s%s:\n' % (name, value[0]))
f.write(' return "%s";\n' % to_log_lower(value[0]))
else:
f.write(' case YG%s%s:\n' % (name, value))
f.write(' return "%s";\n' % to_log_lower(value))
f.write(' }\n')
f.write(' return "unknown";\n')
f.write('}\n\n')
# write out java files # write out java files
for name, values in sorted(ENUMS.items()): for name, values in sorted(ENUMS.items()):
with open(root + '/java/com/facebook/yoga/Yoga%s.java' % name, 'w') as f: with open(root + '/java/com/facebook/yoga/Yoga%s.java' % name, 'w') as f:

68
tests/YGLoggerTest.cpp Normal file
View File

@@ -0,0 +1,68 @@
/**
* Copyright (c) 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#include <gtest/gtest.h>
#include <yoga/Yoga.h>
#include <stdarg.h>
namespace {
char writeBuffer[4096];
int _unmanagedLogger(YGLogLevel level, const char *format, va_list args) {
return vsnprintf(writeBuffer + strlen(writeBuffer), sizeof(writeBuffer) - strlen(writeBuffer), format, args);
}
}
TEST(YogaTest, logger_default_node_should_print_no_style_info) {
writeBuffer[0] = '\0';
YGSetLogger(_unmanagedLogger);
const YGNodeRef root = YGNodeNew();
YGNodeCalculateLayout(root, YGUnitUndefined, YGUnitUndefined, YGDirectionLTR);
YGNodePrint(root, (YGPrintOptions)(YGPrintOptionsLayout | YGPrintOptionsChildren | YGPrintOptionsStyle));
YGSetLogger(NULL);
YGNodeFree(root);
const char * expected = "<div layout=\"width: 0; height: 0; top: 0; left: 0;\" style=\"\" ></div>";
ASSERT_STREQ(expected, writeBuffer);
}
TEST(YogaTest, logger_node_with_percentage_absolute_position_and_margin) {
writeBuffer[0] = '\0';
YGSetLogger(_unmanagedLogger);
const YGNodeRef root = YGNodeNew();
YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute);
YGNodeStyleSetWidthPercent(root, 50);
YGNodeStyleSetHeightPercent(root, 75);
YGNodeStyleSetFlex(root, 1);
YGNodeStyleSetMargin(root, YGEdgeRight, 10);
YGNodeStyleSetMarginAuto(root, YGEdgeLeft);
YGNodeCalculateLayout(root, YGUnitUndefined, YGUnitUndefined, YGDirectionLTR);
YGNodePrint(root, (YGPrintOptions)(YGPrintOptionsLayout | YGPrintOptionsChildren | YGPrintOptionsStyle));
YGSetLogger(NULL);
YGNodeFree(root);
const char * expected = "<div layout=\"width: 0; height: 0; top: 0; left: 0;\" style=\"flex: 1; margin-left: auto; margin-right: 10px; width: 50%; height: 75%; position: absolute; \" ></div>";
ASSERT_STREQ(expected, writeBuffer);
}
TEST(YogaTest, logger_node_with_children_should_print_indented) {
writeBuffer[0] = '\0';
YGSetLogger(_unmanagedLogger);
const YGNodeRef root = YGNodeNew();
const YGNodeRef child0 = YGNodeNew();
const YGNodeRef child1 = YGNodeNew();
YGNodeInsertChild(root, child0, 0);
YGNodeInsertChild(root, child1, 1);
YGNodeCalculateLayout(root, YGUnitUndefined, YGUnitUndefined, YGDirectionLTR);
YGNodePrint(root, (YGPrintOptions)(YGPrintOptionsLayout | YGPrintOptionsChildren | YGPrintOptionsStyle));
YGSetLogger(NULL);
YGNodeFreeRecursive(root);
const char * expected = "<div layout=\"width: 0; height: 0; top: 0; left: 0;\" style=\"\" >\n <div layout=\"width: 0; height: 0; top: 0; left: 0;\" style=\"\" ></div>\n <div layout=\"width: 0; height: 0; top: 0; left: 0;\" style=\"\" ></div>\n</div>";
ASSERT_STREQ(expected, writeBuffer);
}

View File

@@ -180,7 +180,7 @@ TEST(YogaTest, dont_measure_when_min_equals_max_mixed_height_percent) {
} }
#if GTEST_HAS_DEATH_TEST #if GTEST_HAS_DEATH_TEST
TEST(YogaTest, cannot_add_child_to_node_with_measure_func) { TEST(YogaDeathTest, cannot_add_child_to_node_with_measure_func) {
const YGNodeRef root = YGNodeNew(); const YGNodeRef root = YGNodeNew();
YGNodeSetMeasureFunc(root, _measure); YGNodeSetMeasureFunc(root, _measure);
@@ -190,7 +190,7 @@ TEST(YogaTest, cannot_add_child_to_node_with_measure_func) {
YGNodeFreeRecursive(root); YGNodeFreeRecursive(root);
} }
TEST(YogaTest, cannot_add_nonnull_measure_func_to_non_leaf_node) { TEST(YogaDeathTest, cannot_add_nonnull_measure_func_to_non_leaf_node) {
const YGNodeRef root = YGNodeNew(); const YGNodeRef root = YGNodeNew();
const YGNodeRef root_child0 = YGNodeNew(); const YGNodeRef root_child0 = YGNodeNew();
YGNodeInsertChild(root, root_child0, 0); YGNodeInsertChild(root, root_child0, 0);
@@ -199,6 +199,8 @@ TEST(YogaTest, cannot_add_nonnull_measure_func_to_non_leaf_node) {
YGNodeFreeRecursive(root); YGNodeFreeRecursive(root);
} }
#endif
TEST(YogaTest, can_nullify_measure_func_on_any_node) { TEST(YogaTest, can_nullify_measure_func_on_any_node) {
const YGNodeRef root = YGNodeNew(); const YGNodeRef root = YGNodeNew();
YGNodeInsertChild(root, YGNodeNew(), 0); YGNodeInsertChild(root, YGNodeNew(), 0);
@@ -208,4 +210,3 @@ TEST(YogaTest, can_nullify_measure_func_on_any_node) {
YGNodeFreeRecursive(root); YGNodeFreeRecursive(root);
} }
#endif

View File

@@ -63,7 +63,7 @@ TEST(YogaTest, memory_func_test_funcs) {
} }
#if GTEST_HAS_DEATH_TEST #if GTEST_HAS_DEATH_TEST
TEST(YogaTest, memory_func_assert_zero_nodes) { TEST(YogaDeathTest, memory_func_assert_zero_nodes) {
gNodeInstanceCount = 0; // Reset YGNode instance count for memory func test gNodeInstanceCount = 0; // Reset YGNode instance count for memory func test
const YGNodeRef root = YGNodeNew(); const YGNodeRef root = YGNodeNew();
ASSERT_DEATH(YGSetMemoryFuncs(&testMalloc, &testCalloc, &testRealloc, &testFree), ASSERT_DEATH(YGSetMemoryFuncs(&testMalloc, &testCalloc, &testRealloc, &testFree),
@@ -71,7 +71,7 @@ TEST(YogaTest, memory_func_assert_zero_nodes) {
YGNodeFreeRecursive(root); YGNodeFreeRecursive(root);
} }
TEST(YogaTest, memory_func_assert_all_non_null) { TEST(YogaDeathTest, memory_func_assert_all_non_null) {
gNodeInstanceCount = 0; // Reset YGNode instance count for memory func test gNodeInstanceCount = 0; // Reset YGNode instance count for memory func test
ASSERT_DEATH(YGSetMemoryFuncs(NULL, &testCalloc, &testRealloc, &testFree), ASSERT_DEATH(YGSetMemoryFuncs(NULL, &testCalloc, &testRealloc, &testFree),
"Cannot set memory functions: functions must be all NULL or Non-NULL"); "Cannot set memory functions: functions must be all NULL or Non-NULL");

219
yoga/YGEnums.c Normal file
View File

@@ -0,0 +1,219 @@
/**
* Copyright (c) 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#include "YGEnums.h"
const char *YGAlignToString(const YGAlign value){
switch(value){
case YGAlignAuto:
return "auto";
case YGAlignFlexStart:
return "flex-start";
case YGAlignCenter:
return "center";
case YGAlignFlexEnd:
return "flex-end";
case YGAlignStretch:
return "stretch";
case YGAlignBaseline:
return "baseline";
case YGAlignSpaceBetween:
return "space-between";
case YGAlignSpaceAround:
return "space-around";
}
return "unknown";
}
const char *YGDimensionToString(const YGDimension value){
switch(value){
case YGDimensionWidth:
return "width";
case YGDimensionHeight:
return "height";
}
return "unknown";
}
const char *YGDirectionToString(const YGDirection value){
switch(value){
case YGDirectionInherit:
return "inherit";
case YGDirectionLTR:
return "ltr";
case YGDirectionRTL:
return "rtl";
}
return "unknown";
}
const char *YGDisplayToString(const YGDisplay value){
switch(value){
case YGDisplayFlex:
return "flex";
case YGDisplayNone:
return "none";
}
return "unknown";
}
const char *YGEdgeToString(const YGEdge value){
switch(value){
case YGEdgeLeft:
return "left";
case YGEdgeTop:
return "top";
case YGEdgeRight:
return "right";
case YGEdgeBottom:
return "bottom";
case YGEdgeStart:
return "start";
case YGEdgeEnd:
return "end";
case YGEdgeHorizontal:
return "horizontal";
case YGEdgeVertical:
return "vertical";
case YGEdgeAll:
return "all";
}
return "unknown";
}
const char *YGExperimentalFeatureToString(const YGExperimentalFeature value){
switch(value){
case YGExperimentalFeatureRounding:
return "rounding";
case YGExperimentalFeatureWebFlexBasis:
return "web-flex-basis";
case YGExperimentalFeatureMinFlexFix:
return "min-flex-fix";
}
return "unknown";
}
const char *YGFlexDirectionToString(const YGFlexDirection value){
switch(value){
case YGFlexDirectionColumn:
return "column";
case YGFlexDirectionColumnReverse:
return "column-reverse";
case YGFlexDirectionRow:
return "row";
case YGFlexDirectionRowReverse:
return "row-reverse";
}
return "unknown";
}
const char *YGJustifyToString(const YGJustify value){
switch(value){
case YGJustifyFlexStart:
return "flex-start";
case YGJustifyCenter:
return "center";
case YGJustifyFlexEnd:
return "flex-end";
case YGJustifySpaceBetween:
return "space-between";
case YGJustifySpaceAround:
return "space-around";
}
return "unknown";
}
const char *YGLogLevelToString(const YGLogLevel value){
switch(value){
case YGLogLevelError:
return "error";
case YGLogLevelWarn:
return "warn";
case YGLogLevelInfo:
return "info";
case YGLogLevelDebug:
return "debug";
case YGLogLevelVerbose:
return "verbose";
}
return "unknown";
}
const char *YGMeasureModeToString(const YGMeasureMode value){
switch(value){
case YGMeasureModeUndefined:
return "undefined";
case YGMeasureModeExactly:
return "exactly";
case YGMeasureModeAtMost:
return "at-most";
}
return "unknown";
}
const char *YGOverflowToString(const YGOverflow value){
switch(value){
case YGOverflowVisible:
return "visible";
case YGOverflowHidden:
return "hidden";
case YGOverflowScroll:
return "scroll";
}
return "unknown";
}
const char *YGPositionTypeToString(const YGPositionType value){
switch(value){
case YGPositionTypeRelative:
return "relative";
case YGPositionTypeAbsolute:
return "absolute";
}
return "unknown";
}
const char *YGPrintOptionsToString(const YGPrintOptions value){
switch(value){
case YGPrintOptionsLayout:
return "layout";
case YGPrintOptionsStyle:
return "style";
case YGPrintOptionsChildren:
return "children";
}
return "unknown";
}
const char *YGUnitToString(const YGUnit value){
switch(value){
case YGUnitUndefined:
return "undefined";
case YGUnitPoint:
return "point";
case YGUnitPercent:
return "percent";
case YGUnitAuto:
return "auto";
}
return "unknown";
}
const char *YGWrapToString(const YGWrap value){
switch(value){
case YGWrapNoWrap:
return "no-wrap";
case YGWrapWrap:
return "wrap";
case YGWrapWrapReverse:
return "wrap-reverse";
}
return "unknown";
}

View File

@@ -24,12 +24,14 @@ typedef YG_ENUM_BEGIN(YGAlign) {
YGAlignSpaceBetween, YGAlignSpaceBetween,
YGAlignSpaceAround, YGAlignSpaceAround,
} YG_ENUM_END(YGAlign); } YG_ENUM_END(YGAlign);
WIN_EXPORT const char *YGAlignToString(const YGAlign value);
#define YGDimensionCount 2 #define YGDimensionCount 2
typedef YG_ENUM_BEGIN(YGDimension) { typedef YG_ENUM_BEGIN(YGDimension) {
YGDimensionWidth, YGDimensionWidth,
YGDimensionHeight, YGDimensionHeight,
} YG_ENUM_END(YGDimension); } YG_ENUM_END(YGDimension);
WIN_EXPORT const char *YGDimensionToString(const YGDimension value);
#define YGDirectionCount 3 #define YGDirectionCount 3
typedef YG_ENUM_BEGIN(YGDirection) { typedef YG_ENUM_BEGIN(YGDirection) {
@@ -37,12 +39,14 @@ typedef YG_ENUM_BEGIN(YGDirection) {
YGDirectionLTR, YGDirectionLTR,
YGDirectionRTL, YGDirectionRTL,
} YG_ENUM_END(YGDirection); } YG_ENUM_END(YGDirection);
WIN_EXPORT const char *YGDirectionToString(const YGDirection value);
#define YGDisplayCount 2 #define YGDisplayCount 2
typedef YG_ENUM_BEGIN(YGDisplay) { typedef YG_ENUM_BEGIN(YGDisplay) {
YGDisplayFlex, YGDisplayFlex,
YGDisplayNone, YGDisplayNone,
} YG_ENUM_END(YGDisplay); } YG_ENUM_END(YGDisplay);
WIN_EXPORT const char *YGDisplayToString(const YGDisplay value);
#define YGEdgeCount 9 #define YGEdgeCount 9
typedef YG_ENUM_BEGIN(YGEdge) { typedef YG_ENUM_BEGIN(YGEdge) {
@@ -56,6 +60,7 @@ typedef YG_ENUM_BEGIN(YGEdge) {
YGEdgeVertical, YGEdgeVertical,
YGEdgeAll, YGEdgeAll,
} YG_ENUM_END(YGEdge); } YG_ENUM_END(YGEdge);
WIN_EXPORT const char *YGEdgeToString(const YGEdge value);
#define YGExperimentalFeatureCount 3 #define YGExperimentalFeatureCount 3
typedef YG_ENUM_BEGIN(YGExperimentalFeature) { typedef YG_ENUM_BEGIN(YGExperimentalFeature) {
@@ -63,6 +68,7 @@ typedef YG_ENUM_BEGIN(YGExperimentalFeature) {
YGExperimentalFeatureWebFlexBasis, YGExperimentalFeatureWebFlexBasis,
YGExperimentalFeatureMinFlexFix, YGExperimentalFeatureMinFlexFix,
} YG_ENUM_END(YGExperimentalFeature); } YG_ENUM_END(YGExperimentalFeature);
WIN_EXPORT const char *YGExperimentalFeatureToString(const YGExperimentalFeature value);
#define YGFlexDirectionCount 4 #define YGFlexDirectionCount 4
typedef YG_ENUM_BEGIN(YGFlexDirection) { typedef YG_ENUM_BEGIN(YGFlexDirection) {
@@ -71,6 +77,7 @@ typedef YG_ENUM_BEGIN(YGFlexDirection) {
YGFlexDirectionRow, YGFlexDirectionRow,
YGFlexDirectionRowReverse, YGFlexDirectionRowReverse,
} YG_ENUM_END(YGFlexDirection); } YG_ENUM_END(YGFlexDirection);
WIN_EXPORT const char *YGFlexDirectionToString(const YGFlexDirection value);
#define YGJustifyCount 5 #define YGJustifyCount 5
typedef YG_ENUM_BEGIN(YGJustify) { typedef YG_ENUM_BEGIN(YGJustify) {
@@ -80,6 +87,7 @@ typedef YG_ENUM_BEGIN(YGJustify) {
YGJustifySpaceBetween, YGJustifySpaceBetween,
YGJustifySpaceAround, YGJustifySpaceAround,
} YG_ENUM_END(YGJustify); } YG_ENUM_END(YGJustify);
WIN_EXPORT const char *YGJustifyToString(const YGJustify value);
#define YGLogLevelCount 5 #define YGLogLevelCount 5
typedef YG_ENUM_BEGIN(YGLogLevel) { typedef YG_ENUM_BEGIN(YGLogLevel) {
@@ -89,6 +97,7 @@ typedef YG_ENUM_BEGIN(YGLogLevel) {
YGLogLevelDebug, YGLogLevelDebug,
YGLogLevelVerbose, YGLogLevelVerbose,
} YG_ENUM_END(YGLogLevel); } YG_ENUM_END(YGLogLevel);
WIN_EXPORT const char *YGLogLevelToString(const YGLogLevel value);
#define YGMeasureModeCount 3 #define YGMeasureModeCount 3
typedef YG_ENUM_BEGIN(YGMeasureMode) { typedef YG_ENUM_BEGIN(YGMeasureMode) {
@@ -96,6 +105,7 @@ typedef YG_ENUM_BEGIN(YGMeasureMode) {
YGMeasureModeExactly, YGMeasureModeExactly,
YGMeasureModeAtMost, YGMeasureModeAtMost,
} YG_ENUM_END(YGMeasureMode); } YG_ENUM_END(YGMeasureMode);
WIN_EXPORT const char *YGMeasureModeToString(const YGMeasureMode value);
#define YGOverflowCount 3 #define YGOverflowCount 3
typedef YG_ENUM_BEGIN(YGOverflow) { typedef YG_ENUM_BEGIN(YGOverflow) {
@@ -103,12 +113,14 @@ typedef YG_ENUM_BEGIN(YGOverflow) {
YGOverflowHidden, YGOverflowHidden,
YGOverflowScroll, YGOverflowScroll,
} YG_ENUM_END(YGOverflow); } YG_ENUM_END(YGOverflow);
WIN_EXPORT const char *YGOverflowToString(const YGOverflow value);
#define YGPositionTypeCount 2 #define YGPositionTypeCount 2
typedef YG_ENUM_BEGIN(YGPositionType) { typedef YG_ENUM_BEGIN(YGPositionType) {
YGPositionTypeRelative, YGPositionTypeRelative,
YGPositionTypeAbsolute, YGPositionTypeAbsolute,
} YG_ENUM_END(YGPositionType); } YG_ENUM_END(YGPositionType);
WIN_EXPORT const char *YGPositionTypeToString(const YGPositionType value);
#define YGPrintOptionsCount 3 #define YGPrintOptionsCount 3
typedef YG_ENUM_BEGIN(YGPrintOptions) { typedef YG_ENUM_BEGIN(YGPrintOptions) {
@@ -116,6 +128,7 @@ typedef YG_ENUM_BEGIN(YGPrintOptions) {
YGPrintOptionsStyle = 2, YGPrintOptionsStyle = 2,
YGPrintOptionsChildren = 4, YGPrintOptionsChildren = 4,
} YG_ENUM_END(YGPrintOptions); } YG_ENUM_END(YGPrintOptions);
WIN_EXPORT const char *YGPrintOptionsToString(const YGPrintOptions value);
#define YGUnitCount 4 #define YGUnitCount 4
typedef YG_ENUM_BEGIN(YGUnit) { typedef YG_ENUM_BEGIN(YGUnit) {
@@ -124,6 +137,7 @@ typedef YG_ENUM_BEGIN(YGUnit) {
YGUnitPercent, YGUnitPercent,
YGUnitAuto, YGUnitAuto,
} YG_ENUM_END(YGUnit); } YG_ENUM_END(YGUnit);
WIN_EXPORT const char *YGUnitToString(const YGUnit value);
#define YGWrapCount 3 #define YGWrapCount 3
typedef YG_ENUM_BEGIN(YGWrap) { typedef YG_ENUM_BEGIN(YGWrap) {
@@ -131,5 +145,6 @@ typedef YG_ENUM_BEGIN(YGWrap) {
YGWrapWrap, YGWrapWrap,
YGWrapWrapReverse, YGWrapWrapReverse,
} YG_ENUM_END(YGWrap); } YG_ENUM_END(YGWrap);
WIN_EXPORT const char *YGWrapToString(const YGWrap value);
YG_EXTERN_C_END YG_EXTERN_C_END

View File

@@ -768,29 +768,36 @@ static void YGIndent(const uint32_t n) {
} }
} }
static void YGPrintNumberIfNotZero(const char *str, const YGValue *const number) {
if (!YGFloatsEqual(number->value, 0)) {
YGLog(YGLogLevelDebug,
"%s: %g%s, ",
str,
number->value,
number->unit == YGUnitPoint ? "pt" : "%");
}
}
static void YGPrintNumberIfNotUndefinedf(const char *str, const float number) { static void YGPrintNumberIfNotUndefinedf(const char *str, const float number) {
if (!YGFloatIsUndefined(number)) { if (!YGFloatIsUndefined(number)) {
YGLog(YGLogLevelDebug, "%s: %g, ", str, number); YGLog(YGLogLevelDebug, "%s: %g; ", str, number);
} }
} }
static void YGPrintNumberIfNotUndefined(const char *str, const YGValue *const number) { static void YGPrintNumberIfNotUndefined(const char *str, const YGValue *const number) {
if (number->unit != YGUnitUndefined) { if (number->unit != YGUnitUndefined) {
YGLog(YGLogLevelDebug, if (number->unit == YGUnitAuto) {
"%s: %g%s, ", YGLog(YGLogLevelDebug, "%s: auto; ", str);
str, } else {
number->value, const char *unit = number->unit == YGUnitPoint ? "px" : "%";
number->unit == YGUnitPoint ? "pt" : "%"); YGLog(YGLogLevelDebug, "%s: %g%s; ", str, number->value, unit);
}
}
}
static void YGPrintNumberIfNotAuto(const char *str, const YGValue *const number) {
if (number->unit != YGUnitAuto) {
YGPrintNumberIfNotUndefined(str, number);
}
}
static void YGPrintEdgeIfNotUndefined(const char *str, const YGValue *edges, const YGEdge edge) {
YGPrintNumberIfNotUndefined(str, YGComputedEdgeValue(edges, YGEdgeLeft, &YGValueUndefined));
}
static void YGPrintNumberIfNotZero(const char *str, const YGValue *const number) {
if (!YGFloatsEqual(number->value, 0)) {
YGPrintNumberIfNotUndefined(str, number);
} }
} }
@@ -799,170 +806,113 @@ static bool YGFourValuesEqual(const YGValue four[4]) {
YGValueEqual(four[0], four[3]); YGValueEqual(four[0], four[3]);
} }
static void YGPrintEdges(const char *str, const YGValue *edges) {
if (YGFourValuesEqual(edges)) {
YGPrintNumberIfNotZero(str, &edges[YGEdgeLeft]);
} else {
for (YGEdge edge = YGEdgeLeft; edge < YGEdgeCount; edge++) {
char buf[30];
snprintf(buf, sizeof(buf), "%s-%s", str, YGEdgeToString(edge));
YGPrintNumberIfNotZero(buf, &edges[edge]);
}
}
}
static void YGNodePrintInternal(const YGNodeRef node, static void YGNodePrintInternal(const YGNodeRef node,
const YGPrintOptions options, const YGPrintOptions options,
const uint32_t level) { const uint32_t level) {
YGIndent(level); YGIndent(level);
YGLog(YGLogLevelDebug, "{"); YGLog(YGLogLevelDebug, "<div ");
if (node->print) { if (node->print) {
node->print(node); node->print(node);
} }
if (options & YGPrintOptionsLayout) { if (options & YGPrintOptionsLayout) {
YGLog(YGLogLevelDebug, "layout: {"); YGLog(YGLogLevelDebug, "layout=\"");
YGLog(YGLogLevelDebug, "width: %g, ", node->layout.dimensions[YGDimensionWidth]); YGLog(YGLogLevelDebug, "width: %g; ", node->layout.dimensions[YGDimensionWidth]);
YGLog(YGLogLevelDebug, "height: %g, ", node->layout.dimensions[YGDimensionHeight]); YGLog(YGLogLevelDebug, "height: %g; ", node->layout.dimensions[YGDimensionHeight]);
YGLog(YGLogLevelDebug, "top: %g, ", node->layout.position[YGEdgeTop]); YGLog(YGLogLevelDebug, "top: %g; ", node->layout.position[YGEdgeTop]);
YGLog(YGLogLevelDebug, "left: %g", node->layout.position[YGEdgeLeft]); YGLog(YGLogLevelDebug, "left: %g;", node->layout.position[YGEdgeLeft]);
YGLog(YGLogLevelDebug, "}, "); YGLog(YGLogLevelDebug, "\" ");
} }
if (options & YGPrintOptionsStyle) { if (options & YGPrintOptionsStyle) {
if (node->style.flexDirection == YGFlexDirectionColumn) { YGLog(YGLogLevelDebug, "style=\"");
YGLog(YGLogLevelDebug, "flexDirection: 'column', "); if (node->style.flexDirection != gYGNodeDefaults.style.flexDirection) {
} else if (node->style.flexDirection == YGFlexDirectionColumnReverse) { YGLog(YGLogLevelDebug,
YGLog(YGLogLevelDebug, "flexDirection: 'column-reverse', "); "flex-direction: %s; ",
} else if (node->style.flexDirection == YGFlexDirectionRow) { YGFlexDirectionToString(node->style.flexDirection));
YGLog(YGLogLevelDebug, "flexDirection: 'row', "); }
} else if (node->style.flexDirection == YGFlexDirectionRowReverse) { if (node->style.justifyContent != gYGNodeDefaults.style.justifyContent) {
YGLog(YGLogLevelDebug, "flexDirection: 'row-reverse', "); YGLog(YGLogLevelDebug,
"justify-content: %s; ",
YGJustifyToString(node->style.justifyContent));
}
if (node->style.alignItems != gYGNodeDefaults.style.alignItems) {
YGLog(YGLogLevelDebug, "align-items: %s; ", YGAlignToString(node->style.alignItems));
}
if (node->style.alignContent != gYGNodeDefaults.style.alignContent) {
YGLog(YGLogLevelDebug, "align-content: %s; ", YGAlignToString(node->style.alignContent));
}
if (node->style.alignSelf != gYGNodeDefaults.style.alignSelf) {
YGLog(YGLogLevelDebug, "align-self: %s; ", YGAlignToString(node->style.alignSelf));
} }
if (node->style.justifyContent == YGJustifyCenter) { YGPrintNumberIfNotUndefinedf("flex-grow", node->style.flexGrow);
YGLog(YGLogLevelDebug, "justifyContent: 'center', "); YGPrintNumberIfNotUndefinedf("flex-shrink", node->style.flexShrink);
} else if (node->style.justifyContent == YGJustifyFlexEnd) { YGPrintNumberIfNotAuto("flex-basis", &node->style.flexBasis);
YGLog(YGLogLevelDebug, "justifyContent: 'flex-end', "); YGPrintNumberIfNotUndefinedf("flex", node->style.flex);
} else if (node->style.justifyContent == YGJustifySpaceAround) {
YGLog(YGLogLevelDebug, "justifyContent: 'space-around', "); if (node->style.flexWrap != gYGNodeDefaults.style.flexWrap) {
} else if (node->style.justifyContent == YGJustifySpaceBetween) { YGLog(YGLogLevelDebug, "flexWrap: %s; ", YGWrapToString(node->style.flexWrap));
YGLog(YGLogLevelDebug, "justifyContent: 'space-between', ");
} }
if (node->style.alignItems == YGAlignCenter) { if (node->style.overflow != gYGNodeDefaults.style.overflow) {
YGLog(YGLogLevelDebug, "alignItems: 'center', "); YGLog(YGLogLevelDebug, "overflow: %s; ", YGOverflowToString(node->style.overflow));
} else if (node->style.alignItems == YGAlignFlexEnd) {
YGLog(YGLogLevelDebug, "alignItems: 'flex-end', ");
} else if (node->style.alignItems == YGAlignStretch) {
YGLog(YGLogLevelDebug, "alignItems: 'stretch', ");
} }
if (node->style.alignContent == YGAlignCenter) { if (node->style.display != gYGNodeDefaults.style.display) {
YGLog(YGLogLevelDebug, "alignContent: 'center', "); YGLog(YGLogLevelDebug, "display: %s; ", YGDisplayToString(node->style.display));
} else if (node->style.alignContent == YGAlignFlexEnd) {
YGLog(YGLogLevelDebug, "alignContent: 'flex-end', ");
} else if (node->style.alignContent == YGAlignStretch) {
YGLog(YGLogLevelDebug, "alignContent: 'stretch', ");
} }
if (node->style.alignSelf == YGAlignFlexStart) { YGPrintEdges("margin", node->style.margin);
YGLog(YGLogLevelDebug, "alignSelf: 'flex-start', "); YGPrintEdges("padding", node->style.padding);
} else if (node->style.alignSelf == YGAlignCenter) { YGPrintEdges("border", node->style.border);
YGLog(YGLogLevelDebug, "alignSelf: 'center', ");
} else if (node->style.alignSelf == YGAlignFlexEnd) { YGPrintNumberIfNotAuto("width", &node->style.dimensions[YGDimensionWidth]);
YGLog(YGLogLevelDebug, "alignSelf: 'flex-end', "); YGPrintNumberIfNotAuto("height", &node->style.dimensions[YGDimensionHeight]);
} else if (node->style.alignSelf == YGAlignStretch) { YGPrintNumberIfNotAuto("max-width", &node->style.maxDimensions[YGDimensionWidth]);
YGLog(YGLogLevelDebug, "alignSelf: 'stretch', "); YGPrintNumberIfNotAuto("max-height", &node->style.maxDimensions[YGDimensionHeight]);
YGPrintNumberIfNotAuto("min-width", &node->style.minDimensions[YGDimensionWidth]);
YGPrintNumberIfNotAuto("min-height", &node->style.minDimensions[YGDimensionHeight]);
if (node->style.positionType != gYGNodeDefaults.style.positionType) {
YGLog(YGLogLevelDebug, "position: %s; ", YGPositionTypeToString(node->style.positionType));
} }
YGPrintNumberIfNotUndefinedf("flexGrow", YGResolveFlexGrow(node)); YGPrintEdgeIfNotUndefined("left", node->style.position, YGEdgeLeft);
YGPrintNumberIfNotUndefinedf("flexShrink", YGNodeResolveFlexShrink(node)); YGPrintEdgeIfNotUndefined("right", node->style.position, YGEdgeRight);
YGPrintNumberIfNotUndefined("flexBasis", YGNodeResolveFlexBasisPtr(node)); YGPrintEdgeIfNotUndefined("top", node->style.position, YGEdgeTop);
YGPrintEdgeIfNotUndefined("bottom", node->style.position, YGEdgeBottom);
YGLog(YGLogLevelDebug, "\" ");
if (node->style.overflow == YGOverflowHidden) { if (node->measure != NULL) {
YGLog(YGLogLevelDebug, "overflow: 'hidden', "); YGLog(YGLogLevelDebug, "has-custom-measure=\"true\"");
} else if (node->style.overflow == YGOverflowVisible) {
YGLog(YGLogLevelDebug, "overflow: 'visible', ");
} else if (node->style.overflow == YGOverflowScroll) {
YGLog(YGLogLevelDebug, "overflow: 'scroll', ");
} }
if (YGFourValuesEqual(node->style.margin)) {
YGPrintNumberIfNotZero("margin",
YGComputedEdgeValue(node->style.margin, YGEdgeLeft, &YGValueZero));
} else {
YGPrintNumberIfNotZero("marginLeft",
YGComputedEdgeValue(node->style.margin, YGEdgeLeft, &YGValueZero));
YGPrintNumberIfNotZero("marginRight",
YGComputedEdgeValue(node->style.margin, YGEdgeRight, &YGValueZero));
YGPrintNumberIfNotZero("marginTop",
YGComputedEdgeValue(node->style.margin, YGEdgeTop, &YGValueZero));
YGPrintNumberIfNotZero("marginBottom",
YGComputedEdgeValue(node->style.margin, YGEdgeBottom, &YGValueZero));
YGPrintNumberIfNotZero("marginStart",
YGComputedEdgeValue(node->style.margin, YGEdgeStart, &YGValueZero));
YGPrintNumberIfNotZero("marginEnd",
YGComputedEdgeValue(node->style.margin, YGEdgeEnd, &YGValueZero));
}
if (YGFourValuesEqual(node->style.padding)) {
YGPrintNumberIfNotZero("padding",
YGComputedEdgeValue(node->style.padding, YGEdgeLeft, &YGValueZero));
} else {
YGPrintNumberIfNotZero("paddingLeft",
YGComputedEdgeValue(node->style.padding, YGEdgeLeft, &YGValueZero));
YGPrintNumberIfNotZero("paddingRight",
YGComputedEdgeValue(node->style.padding, YGEdgeRight, &YGValueZero));
YGPrintNumberIfNotZero("paddingTop",
YGComputedEdgeValue(node->style.padding, YGEdgeTop, &YGValueZero));
YGPrintNumberIfNotZero("paddingBottom",
YGComputedEdgeValue(node->style.padding, YGEdgeBottom, &YGValueZero));
YGPrintNumberIfNotZero("paddingStart",
YGComputedEdgeValue(node->style.padding, YGEdgeStart, &YGValueZero));
YGPrintNumberIfNotZero("paddingEnd",
YGComputedEdgeValue(node->style.padding, YGEdgeEnd, &YGValueZero));
}
if (YGFourValuesEqual(node->style.border)) {
YGPrintNumberIfNotZero("borderWidth",
YGComputedEdgeValue(node->style.border, YGEdgeLeft, &YGValueZero));
} else {
YGPrintNumberIfNotZero("borderLeftWidth",
YGComputedEdgeValue(node->style.border, YGEdgeLeft, &YGValueZero));
YGPrintNumberIfNotZero("borderRightWidth",
YGComputedEdgeValue(node->style.border, YGEdgeRight, &YGValueZero));
YGPrintNumberIfNotZero("borderTopWidth",
YGComputedEdgeValue(node->style.border, YGEdgeTop, &YGValueZero));
YGPrintNumberIfNotZero("borderBottomWidth",
YGComputedEdgeValue(node->style.border, YGEdgeBottom, &YGValueZero));
YGPrintNumberIfNotZero("borderStartWidth",
YGComputedEdgeValue(node->style.border, YGEdgeStart, &YGValueZero));
YGPrintNumberIfNotZero("borderEndWidth",
YGComputedEdgeValue(node->style.border, YGEdgeEnd, &YGValueZero));
}
YGPrintNumberIfNotUndefined("width", &node->style.dimensions[YGDimensionWidth]);
YGPrintNumberIfNotUndefined("height", &node->style.dimensions[YGDimensionHeight]);
YGPrintNumberIfNotUndefined("maxWidth", &node->style.maxDimensions[YGDimensionWidth]);
YGPrintNumberIfNotUndefined("maxHeight", &node->style.maxDimensions[YGDimensionHeight]);
YGPrintNumberIfNotUndefined("minWidth", &node->style.minDimensions[YGDimensionWidth]);
YGPrintNumberIfNotUndefined("minHeight", &node->style.minDimensions[YGDimensionHeight]);
if (node->style.positionType == YGPositionTypeAbsolute) {
YGLog(YGLogLevelDebug, "position: 'absolute', ");
}
YGPrintNumberIfNotUndefined(
"left", YGComputedEdgeValue(node->style.position, YGEdgeLeft, &YGValueUndefined));
YGPrintNumberIfNotUndefined(
"right", YGComputedEdgeValue(node->style.position, YGEdgeRight, &YGValueUndefined));
YGPrintNumberIfNotUndefined(
"top", YGComputedEdgeValue(node->style.position, YGEdgeTop, &YGValueUndefined));
YGPrintNumberIfNotUndefined(
"bottom", YGComputedEdgeValue(node->style.position, YGEdgeBottom, &YGValueUndefined));
} }
YGLog(YGLogLevelDebug, ">");
const uint32_t childCount = YGNodeListCount(node->children); const uint32_t childCount = YGNodeListCount(node->children);
if (options & YGPrintOptionsChildren && childCount > 0) { if (options & YGPrintOptionsChildren && childCount > 0) {
YGLog(YGLogLevelDebug, "children: [\n");
for (uint32_t i = 0; i < childCount; i++) { for (uint32_t i = 0; i < childCount; i++) {
YGLog(YGLogLevelDebug, "\n");
YGNodePrintInternal(YGNodeGetChild(node, i), options, level + 1); YGNodePrintInternal(YGNodeGetChild(node, i), options, level + 1);
} }
YGIndent(level); YGIndent(level);
YGLog(YGLogLevelDebug, "]},\n"); YGLog(YGLogLevelDebug, "\n");
} else {
YGLog(YGLogLevelDebug, "},\n");
} }
YGLog(YGLogLevelDebug, "</div>");
} }
void YGNodePrint(const YGNodeRef node, const YGPrintOptions options) { void YGNodePrint(const YGNodeRef node, const YGPrintOptions options) {
@@ -3438,7 +3388,15 @@ void YGNodeCalculateLayout(const YGNodeRef node,
} }
void YGSetLogger(YGLogger logger) { void YGSetLogger(YGLogger logger) {
gLogger = logger; if (logger != NULL) {
gLogger = logger;
} else {
#ifdef ANDROID
gLogger = &YGAndroidLog;
#else
gLogger = &YGDefaultLog;
#endif
}
} }
void YGLog(YGLogLevel level, const char *format, ...) { void YGLog(YGLogLevel level, const char *format, ...) {