From 2fd7c3a5145cfbf2d1ab8b49caaf3afcc3b56191 Mon Sep 17 00:00:00 2001 From: Nick Gerleman Date: Tue, 25 Apr 2023 21:06:17 -0700 Subject: [PATCH] Add YGErrata Enum (#1256) Summary: X-link: https://github.com/facebook/yoga/pull/1256 Pull Request resolved: https://github.com/facebook/react-native/pull/37076 This adds a `YGErrata` bitset enum matching the API and guarantees described in https://github.com/facebook/yoga/issues/1247. It is hooked up in later diffs. There are a couple of `YGExperimentalFeature` values that belong here, but keeping the current options means that the default `YGErrataNone` corresponds to existing default behavior, letting us stage the series of changes as: 1. Implement errata API 2. Update internal Yoga users we want to de-risk to `YGErrataClassic` or `YGErrataAll` (if setting `UseLegacyStretchBehaviour`) 3. Add new errata, changing Yoga defaults to be conformant, while letting internal apps opt into compatibility modes pending experimentation. I also added a macro to let C++ users of Yoga perform bitwise operations on the enum without casting (already available for C users). Reviewed By: rshest Differential Revision: D45254098 fbshipit-source-id: eb3f00c9827815134927886a26eb26a0c3598727 --- .../java/com/facebook/yoga/YogaErrata.java | 37 +++++++++++++++ .../ReactCommon/yoga/yoga/YGEnums.cpp | 14 ++++++ .../ReactCommon/yoga/yoga/YGEnums.h | 8 ++++ .../ReactCommon/yoga/yoga/YGMacros.h | 46 +++++++++++++++++++ 4 files changed, 105 insertions(+) create mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/yoga/YogaErrata.java diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/yoga/YogaErrata.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/yoga/YogaErrata.java new file mode 100644 index 00000000000000..6ae5ac0e7cbf08 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/yoga/YogaErrata.java @@ -0,0 +1,37 @@ +/* + * 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. + */ + +// @generated by enums.py + +package com.facebook.yoga; + +public enum YogaErrata { + NONE(0), + STRETCH_FLEX_BASIS(1), + ALL(2147483647), + CLASSIC(2147483646); + + private final int mIntValue; + + YogaErrata(int intValue) { + mIntValue = intValue; + } + + public int intValue() { + return mIntValue; + } + + public static YogaErrata fromInt(int value) { + switch (value) { + case 0: return NONE; + case 1: return STRETCH_FLEX_BASIS; + case 2147483647: return ALL; + case 2147483646: return CLASSIC; + default: throw new IllegalArgumentException("Unknown enum value: " + value); + } + } +} diff --git a/packages/react-native/ReactCommon/yoga/yoga/YGEnums.cpp b/packages/react-native/ReactCommon/yoga/yoga/YGEnums.cpp index acb1bd072a8a06..50cc418a9145ad 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/YGEnums.cpp +++ b/packages/react-native/ReactCommon/yoga/yoga/YGEnums.cpp @@ -87,6 +87,20 @@ const char* YGEdgeToString(const YGEdge value) { return "unknown"; } +const char* YGErrataToString(const YGErrata value) { + switch (value) { + case YGErrataNone: + return "none"; + case YGErrataStretchFlexBasis: + return "stretch-flex-basis"; + case YGErrataAll: + return "all"; + case YGErrataClassic: + return "classic"; + } + return "unknown"; +} + const char* YGExperimentalFeatureToString(const YGExperimentalFeature value) { switch (value) { case YGExperimentalFeatureWebFlexBasis: diff --git a/packages/react-native/ReactCommon/yoga/yoga/YGEnums.h b/packages/react-native/ReactCommon/yoga/yoga/YGEnums.h index 834e5f669ca6d8..13840694b91c4d 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/YGEnums.h +++ b/packages/react-native/ReactCommon/yoga/yoga/YGEnums.h @@ -54,6 +54,14 @@ YG_ENUM_SEQ_DECL( YGEdgeVertical, YGEdgeAll) +YG_ENUM_DECL( + YGErrata, + YGErrataNone = 0, + YGErrataStretchFlexBasis = 1, + YGErrataAll = 2147483647, + YGErrataClassic = 2147483646) +YG_DEFINE_ENUM_FLAG_OPERATORS(YGErrata) + YG_ENUM_SEQ_DECL( YGExperimentalFeature, YGExperimentalFeatureWebFlexBasis, diff --git a/packages/react-native/ReactCommon/yoga/yoga/YGMacros.h b/packages/react-native/ReactCommon/yoga/yoga/YGMacros.h index 13b3c9b4f521df..0ce8c2eed4ce10 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/YGMacros.h +++ b/packages/react-native/ReactCommon/yoga/yoga/YGMacros.h @@ -7,6 +7,10 @@ #pragma once +#ifdef __cplusplus +#include +#endif + #ifdef __cplusplus #define YG_EXTERN_C_BEGIN extern "C" { #define YG_EXTERN_C_END } @@ -40,6 +44,48 @@ #define YG_ENUM_END(name) name #endif +#ifdef __cplusplus +#define YG_DEFINE_ENUM_FLAG_OPERATORS(name) \ + extern "C++" { \ + constexpr inline name operator~(name a) { \ + return static_cast( \ + ~static_cast::type>(a)); \ + } \ + constexpr inline name operator|(name a, name b) { \ + return static_cast( \ + static_cast::type>(a) | \ + static_cast::type>(b)); \ + } \ + constexpr inline name operator&(name a, name b) { \ + return static_cast( \ + static_cast::type>(a) & \ + static_cast::type>(b)); \ + } \ + constexpr inline name operator^(name a, name b) { \ + return static_cast( \ + static_cast::type>(a) ^ \ + static_cast::type>(b)); \ + } \ + inline name& operator|=(name& a, name b) { \ + return reinterpret_cast( \ + reinterpret_cast::type&>(a) |= \ + static_cast::type>(b)); \ + } \ + inline name& operator&=(name& a, name b) { \ + return reinterpret_cast( \ + reinterpret_cast::type&>(a) &= \ + static_cast::type>(b)); \ + } \ + inline name& operator^=(name& a, name b) { \ + return reinterpret_cast( \ + reinterpret_cast::type&>(a) ^= \ + static_cast::type>(b)); \ + } \ + } +#else +#define YG_DEFINE_ENUM_FLAG_OPERATORS(name) +#endif + #ifdef __cplusplus namespace facebook { namespace yoga {