Refactor ViewPropsMapBuffer -> general MapBuffer props mechanism

Summary:
Previously, ViewPropsMapBuffer conversions were hardcoded deep in Android infrastructrue. I've generalized this into a different mechanism to allow any Props struct to support MapBuffer props.

There are still some things that need to be cleaned up and this should be treated as experimental. One thing we likely want to do is remove the hardcoded IDs (fine for codegen'd code; less so for handwritten) and use compile-time-hashed IDs instead with human-readable string names.

Changelog: [Internal]

Reviewed By: mdvacca

Differential Revision: D38708719

fbshipit-source-id: 64603dee7f21828be31346c555d99862dab304ea
This commit is contained in:
Ruslan Shestopalyuk 2022-10-03 04:11:02 -07:00 коммит произвёл Facebook GitHub Bot
Родитель 2319f75c8e
Коммит 110b191b14
18 изменённых файлов: 870 добавлений и 351 удалений

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

@ -62,6 +62,8 @@ object ReactMapBufferPropSetter {
private const val VP_POINTER_OUT_CAPTURE = 42 private const val VP_POINTER_OUT_CAPTURE = 42
private const val VP_POINTER_OVER = 43 private const val VP_POINTER_OVER = 43
private const val VP_POINTER_OVER_CAPTURE = 44 private const val VP_POINTER_OVER_CAPTURE = 44
private const val VP_BORDER_CURVES = 45 // iOS only
private const val VP_FG_COLOR = 46 // iOS only?
// Yoga values // Yoga values
private const val YG_BORDER_WIDTH = 100 private const val YG_BORDER_WIDTH = 100
@ -141,6 +143,9 @@ object ReactMapBufferPropSetter {
// TODO: color for some reason can be object in Java but not in C++ // TODO: color for some reason can be object in Java but not in C++
viewManager.backgroundColor(view, entry.intValue) viewManager.backgroundColor(view, entry.intValue)
} }
VP_FG_COLOR -> {
// Prop not used on Android?
}
VP_BORDER_COLOR -> { VP_BORDER_COLOR -> {
viewManager.borderColor(view, entry.mapBufferValue) viewManager.borderColor(view, entry.mapBufferValue)
} }
@ -148,7 +153,10 @@ object ReactMapBufferPropSetter {
viewManager.borderRadius(view, entry.mapBufferValue) viewManager.borderRadius(view, entry.mapBufferValue)
} }
VP_BORDER_STYLE -> { VP_BORDER_STYLE -> {
viewManager.borderStyle(view, entry.intValue) val styleBuffer = entry.mapBufferValue
if (styleBuffer.contains(CORNER_ALL)) {
viewManager.borderStyle(view, (styleBuffer.getDouble(CORNER_ALL)).toInt())
}
} }
VP_ELEVATION -> { VP_ELEVATION -> {
viewManager.setElevation(view, entry.doubleValue.toFloat()) viewManager.setElevation(view, entry.doubleValue.toFloat())

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

@ -9,7 +9,6 @@
#include "CppViewMutationsWrapper.h" #include "CppViewMutationsWrapper.h"
#include "EventEmitterWrapper.h" #include "EventEmitterWrapper.h"
#include "StateWrapperImpl.h" #include "StateWrapperImpl.h"
#include "viewPropConversions.h"
#include <react/jni/ReadableNativeMap.h> #include <react/jni/ReadableNativeMap.h>
#include <react/renderer/components/scrollview/ScrollViewProps.h> #include <react/renderer/components/scrollview/ScrollViewProps.h>
@ -264,12 +263,11 @@ local_ref<jobject> FabricMountingManager::getProps(
react_native_assert( react_native_assert(
newShadowView.props->rawProps.empty() && newShadowView.props->rawProps.empty() &&
"Raw props must be empty when views are using mapbuffer"); "Raw props must be empty when views are using mapbuffer");
auto oldProps = oldShadowView.props != nullptr
? static_cast<ViewProps const &>(*oldShadowView.props) // MapBufferBuilder must be constructed and live in this scope,
: ViewProps{}; MapBufferBuilder builder;
auto newProps = static_cast<ViewProps const &>(*newShadowView.props); newShadowView.props->propsDiffMapBuffer(&*oldShadowView.props, builder);
return JReadableMapBuffer::createWithContents( return JReadableMapBuffer::createWithContents(builder.build());
viewPropsDiff(oldProps, newProps));
} else { } else {
return ReadableNativeMap::newObjectCxxArgs(newShadowView.props->rawProps); return ReadableNativeMap::newObjectCxxArgs(newShadowView.props->rawProps);
} }

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

@ -8,6 +8,7 @@
#pragma once #pragma once
#include <react/renderer/components/view/ViewProps.h> #include <react/renderer/components/view/ViewProps.h>
#include <react/renderer/components/view/ViewPropsMapBuffer.h>
#include <react/renderer/components/view/conversions.h> #include <react/renderer/components/view/conversions.h>
#include <react/renderer/graphics/conversions.h> #include <react/renderer/graphics/conversions.h>
#include <react/renderer/mapbuffer/MapBuffer.h> #include <react/renderer/mapbuffer/MapBuffer.h>
@ -19,58 +20,6 @@ namespace facebook {
namespace react { namespace react {
namespace { namespace {
// ViewProps values
constexpr MapBuffer::Key VP_ACCESSIBILITY_ACTIONS = 0;
constexpr MapBuffer::Key VP_ACCESSIBILITY_HINT = 1;
constexpr MapBuffer::Key VP_ACCESSIBILITY_LABEL = 2;
constexpr MapBuffer::Key VP_ACCESSIBILITY_LABELLED_BY = 3;
constexpr MapBuffer::Key VP_ACCESSIBILITY_LIVE_REGION = 4;
constexpr MapBuffer::Key VP_ACCESSIBILITY_ROLE = 5;
constexpr MapBuffer::Key VP_ACCESSIBILITY_STATE = 6;
constexpr MapBuffer::Key VP_ACCESSIBILITY_VALUE = 7;
constexpr MapBuffer::Key VP_ACCESSIBLE = 8;
constexpr MapBuffer::Key VP_BACKFACE_VISIBILITY = 9;
constexpr MapBuffer::Key VP_BG_COLOR = 10;
constexpr MapBuffer::Key VP_BORDER_COLOR = 11;
constexpr MapBuffer::Key VP_BORDER_RADII = 12;
constexpr MapBuffer::Key VP_BORDER_STYLE = 13;
constexpr MapBuffer::Key VP_COLLAPSABLE = 14;
constexpr MapBuffer::Key VP_ELEVATION = 15;
constexpr MapBuffer::Key VP_FOCUSABLE = 16;
constexpr MapBuffer::Key VP_HAS_TV_FOCUS = 17;
constexpr MapBuffer::Key VP_HIT_SLOP = 18;
constexpr MapBuffer::Key VP_IMPORTANT_FOR_ACCESSIBILITY = 19;
constexpr MapBuffer::Key VP_NATIVE_BACKGROUND = 20;
constexpr MapBuffer::Key VP_NATIVE_FOREGROUND = 21;
constexpr MapBuffer::Key VP_NATIVE_ID = 22;
constexpr MapBuffer::Key VP_OFFSCREEN_ALPHA_COMPOSITING = 23;
constexpr MapBuffer::Key VP_OPACITY = 24;
constexpr MapBuffer::Key VP_POINTER_EVENTS = 25;
constexpr MapBuffer::Key VP_POINTER_ENTER = 26;
constexpr MapBuffer::Key VP_POINTER_LEAVE = 27;
constexpr MapBuffer::Key VP_POINTER_MOVE = 28;
constexpr MapBuffer::Key VP_REMOVE_CLIPPED_SUBVIEW = 29;
constexpr MapBuffer::Key VP_RENDER_TO_HARDWARE_TEXTURE = 30;
constexpr MapBuffer::Key VP_SHADOW_COLOR = 31;
constexpr MapBuffer::Key VP_TEST_ID = 32;
constexpr MapBuffer::Key VP_TRANSFORM = 33;
constexpr MapBuffer::Key VP_ZINDEX = 34;
constexpr MapBuffer::Key VP_POINTER_ENTER_CAPTURE = 38;
constexpr MapBuffer::Key VP_POINTER_LEAVE_CAPTURE = 39;
constexpr MapBuffer::Key VP_POINTER_MOVE_CAPTURE = 40;
constexpr MapBuffer::Key VP_POINTER_OVER = 41;
constexpr MapBuffer::Key VP_POINTER_OVER_CAPTURE = 42;
constexpr MapBuffer::Key VP_POINTER_OUT = 43;
constexpr MapBuffer::Key VP_POINTER_OUT_CAPTURE = 44;
// Yoga values
constexpr MapBuffer::Key YG_BORDER_WIDTH = 100;
constexpr MapBuffer::Key YG_OVERFLOW = 101;
// AccessibilityAction values
constexpr MapBuffer::Key ACCESSIBILITY_ACTION_NAME = 0;
constexpr MapBuffer::Key ACCESSIBILITY_ACTION_LABEL = 1;
static MapBuffer convertAccessibilityActions( static MapBuffer convertAccessibilityActions(
std::vector<AccessibilityAction> const &actions) { std::vector<AccessibilityAction> const &actions) {
MapBufferBuilder builder(actions.size()); MapBufferBuilder builder(actions.size());
@ -262,294 +211,5 @@ MapBuffer convertTransform(Transform const &transform) {
} }
} // namespace } // namespace
/**
* Diffs two sets of ViewProps into MapBuffer.
* TODO: Currently unsupported: nextFocusForward/Left/Up/Right/Down
*/
static inline MapBuffer viewPropsDiff(
ViewProps const &oldProps,
ViewProps const &newProps) {
MapBufferBuilder builder;
if (oldProps.accessibilityActions != newProps.accessibilityActions) {
builder.putMapBuffer(
VP_ACCESSIBILITY_ACTIONS,
convertAccessibilityActions(newProps.accessibilityActions));
}
if (oldProps.accessibilityHint != newProps.accessibilityHint) {
builder.putString(VP_ACCESSIBILITY_HINT, newProps.accessibilityHint);
}
if (oldProps.accessibilityLabel != newProps.accessibilityLabel) {
builder.putString(VP_ACCESSIBILITY_LABEL, newProps.accessibilityLabel);
}
if (oldProps.accessibilityLabelledBy != newProps.accessibilityLabelledBy) {
builder.putMapBuffer(
VP_ACCESSIBILITY_LABELLED_BY,
convertAccessibilityLabelledBy(newProps.accessibilityLabelledBy));
}
if (oldProps.accessibilityLiveRegion != newProps.accessibilityLiveRegion) {
int value;
switch (newProps.accessibilityLiveRegion) {
case AccessibilityLiveRegion::None:
value = 0;
break;
case AccessibilityLiveRegion::Polite:
value = 1;
break;
case AccessibilityLiveRegion::Assertive:
value = 2;
break;
}
builder.putInt(VP_ACCESSIBILITY_LIVE_REGION, value);
}
if (oldProps.accessibilityRole != newProps.accessibilityRole) {
builder.putString(VP_ACCESSIBILITY_ROLE, newProps.accessibilityRole);
}
if (oldProps.accessibilityState != newProps.accessibilityState) {
builder.putMapBuffer(
VP_ACCESSIBILITY_STATE,
convertAccessibilityState(newProps.accessibilityState));
}
if (oldProps.accessibilityValue != newProps.accessibilityValue) {
builder.putString(
VP_ACCESSIBILITY_VALUE, newProps.accessibilityValue.text.value_or(""));
}
if (oldProps.accessible != newProps.accessible) {
builder.putBool(VP_ACCESSIBLE, newProps.accessible);
}
if (oldProps.backfaceVisibility != newProps.backfaceVisibility) {
int value;
switch (newProps.backfaceVisibility) {
case BackfaceVisibility::Auto:
value = 0;
break;
case BackfaceVisibility::Visible:
value = 1;
break;
case BackfaceVisibility::Hidden:
value = 2;
break;
}
builder.putInt(VP_BACKFACE_VISIBILITY, value);
}
if (oldProps.backgroundColor != newProps.backgroundColor) {
builder.putInt(VP_BG_COLOR, toAndroidRepr(newProps.backgroundColor));
}
if (oldProps.borderColors != newProps.borderColors) {
builder.putMapBuffer(
VP_BORDER_COLOR, convertBorderColors(newProps.borderColors));
}
if (oldProps.borderRadii != newProps.borderRadii) {
builder.putMapBuffer(
VP_BORDER_RADII, convertBorderRadii(newProps.borderRadii));
}
if (oldProps.borderStyles != newProps.borderStyles) {
int value = -1;
if (newProps.borderStyles.all.has_value()) {
switch (newProps.borderStyles.all.value()) {
case BorderStyle::Solid:
value = 0;
break;
case BorderStyle::Dotted:
value = 1;
break;
case BorderStyle::Dashed:
value = 2;
break;
}
}
builder.putInt(VP_BORDER_STYLE, value);
}
if (oldProps.elevation != newProps.elevation) {
builder.putDouble(VP_ELEVATION, newProps.elevation);
}
#ifdef ANDROID
if (oldProps.focusable != newProps.focusable) {
builder.putBool(VP_FOCUSABLE, newProps.focusable);
}
if (oldProps.hasTVPreferredFocus != newProps.hasTVPreferredFocus) {
builder.putBool(VP_HAS_TV_FOCUS, newProps.hasTVPreferredFocus);
}
#endif
if (oldProps.hitSlop != newProps.hitSlop) {
builder.putMapBuffer(VP_HIT_SLOP, convertEdgeInsets(newProps.hitSlop));
}
if (oldProps.importantForAccessibility !=
newProps.importantForAccessibility) {
int value;
switch (newProps.importantForAccessibility) {
case ImportantForAccessibility::Auto:
value = 0;
break;
case ImportantForAccessibility::Yes:
value = 1;
break;
case ImportantForAccessibility::No:
value = 2;
break;
case ImportantForAccessibility::NoHideDescendants:
value = 3;
break;
}
builder.putInt(VP_IMPORTANT_FOR_ACCESSIBILITY, value);
}
#ifdef ANDROID
if (oldProps.nativeBackground != newProps.nativeBackground) {
builder.putMapBuffer(
VP_NATIVE_BACKGROUND,
convertNativeBackground(newProps.nativeBackground));
}
if (oldProps.nativeForeground != newProps.nativeForeground) {
builder.putMapBuffer(
VP_NATIVE_FOREGROUND,
convertNativeBackground(newProps.nativeForeground));
}
#endif
if (oldProps.nativeId != newProps.nativeId) {
builder.putString(VP_NATIVE_ID, newProps.nativeId);
}
#ifdef ANDROID
if (oldProps.needsOffscreenAlphaCompositing !=
newProps.needsOffscreenAlphaCompositing) {
builder.putBool(
VP_OFFSCREEN_ALPHA_COMPOSITING,
newProps.needsOffscreenAlphaCompositing);
}
#endif
if (oldProps.opacity != newProps.opacity) {
builder.putDouble(VP_OPACITY, newProps.opacity);
}
if (oldProps.pointerEvents != newProps.pointerEvents) {
int value;
switch (newProps.pointerEvents) {
case PointerEventsMode::Auto:
value = 0;
break;
case PointerEventsMode::None:
value = 1;
break;
case PointerEventsMode::BoxNone:
value = 2;
break;
case PointerEventsMode::BoxOnly:
value = 3;
break;
}
builder.putInt(VP_POINTER_EVENTS, value);
}
if (oldProps.events != newProps.events) {
builder.putBool(
VP_POINTER_ENTER, newProps.events[ViewEvents::Offset::PointerEnter]);
builder.putBool(
VP_POINTER_LEAVE, newProps.events[ViewEvents::Offset::PointerLeave]);
builder.putBool(
VP_POINTER_MOVE, newProps.events[ViewEvents::Offset::PointerMove]);
builder.putBool(
VP_POINTER_ENTER_CAPTURE,
newProps.events[ViewEvents::Offset::PointerEnterCapture]);
builder.putBool(
VP_POINTER_LEAVE_CAPTURE,
newProps.events[ViewEvents::Offset::PointerLeaveCapture]);
builder.putBool(
VP_POINTER_MOVE_CAPTURE,
newProps.events[ViewEvents::Offset::PointerMoveCapture]);
builder.putBool(
VP_POINTER_OVER, newProps.events[ViewEvents::Offset::PointerOver]);
builder.putBool(
VP_POINTER_OVER_CAPTURE,
newProps.events[ViewEvents::Offset::PointerOverCapture]);
builder.putBool(
VP_POINTER_OUT, newProps.events[ViewEvents::Offset::PointerOut]);
builder.putBool(
VP_POINTER_OUT_CAPTURE,
newProps.events[ViewEvents::Offset::PointerOutCapture]);
}
if (oldProps.removeClippedSubviews != newProps.removeClippedSubviews) {
builder.putBool(VP_REMOVE_CLIPPED_SUBVIEW, newProps.removeClippedSubviews);
}
#ifdef ANDROID
if (oldProps.renderToHardwareTextureAndroid !=
newProps.renderToHardwareTextureAndroid) {
builder.putBool(
VP_RENDER_TO_HARDWARE_TEXTURE, newProps.renderToHardwareTextureAndroid);
}
#endif
if (oldProps.shadowColor != newProps.shadowColor) {
builder.putInt(VP_SHADOW_COLOR, toAndroidRepr(newProps.shadowColor));
}
if (oldProps.testId != newProps.testId) {
builder.putString(VP_TEST_ID, newProps.testId);
}
// TODO: seems like transform covers rotation/translate/scale/skew?
if (oldProps.transform != newProps.transform) {
builder.putMapBuffer(VP_TRANSFORM, convertTransform(newProps.transform));
}
if (oldProps.zIndex != newProps.zIndex) {
builder.putInt(VP_ZINDEX, newProps.zIndex.value_or(0));
}
if (oldProps.yogaStyle != newProps.yogaStyle) {
auto const &oldStyle = oldProps.yogaStyle;
auto const &newStyle = newProps.yogaStyle;
if (!(oldStyle.border() == newStyle.border())) {
builder.putMapBuffer(
YG_BORDER_WIDTH, convertBorderWidths(newStyle.border()));
}
if (oldStyle.overflow() != newStyle.overflow()) {
int value;
switch (newStyle.overflow()) {
case YGOverflowVisible:
value = 0;
break;
case YGOverflowHidden:
value = 1;
break;
case YGOverflowScroll:
value = 2;
break;
}
builder.putInt(YG_OVERFLOW, value);
}
}
return builder.build();
}
} // namespace react } // namespace react
} // namespace facebook } // namespace facebook

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

@ -32,6 +32,11 @@ class AccessibilityProps {
static bool enablePropIteratorSetter; static bool enablePropIteratorSetter;
#ifdef ANDROID
void propsDiffMapBuffer(Props const *oldProps, MapBufferBuilder &builder)
const;
#endif
#pragma mark - Props #pragma mark - Props
bool accessible{false}; bool accessible{false};

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

@ -0,0 +1,168 @@
/*
* 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.
*/
#include "AccessibilityPropsMapBuffer.h"
#include "AccessibilityProps.h"
#include <react/renderer/mapbuffer/MapBufferBuilder.h>
namespace facebook {
namespace react {
#ifdef ANDROID
static MapBuffer convertAccessibilityActions(
std::vector<AccessibilityAction> const &actions) {
MapBufferBuilder builder(actions.size());
for (auto i = 0; i < actions.size(); i++) {
auto const &action = actions[i];
MapBufferBuilder actionsBuilder(2);
actionsBuilder.putString(ACCESSIBILITY_ACTION_NAME, action.name);
if (action.label.has_value()) {
actionsBuilder.putString(
ACCESSIBILITY_ACTION_LABEL, action.label.value());
}
builder.putMapBuffer(i, actionsBuilder.build());
}
return builder.build();
}
static MapBuffer convertAccessibilityLabelledBy(
AccessibilityLabelledBy const &labelledBy) {
MapBufferBuilder builder(labelledBy.value.size());
for (auto i = 0; i < labelledBy.value.size(); i++) {
builder.putString(i, labelledBy.value[i]);
}
return builder.build();
}
// AccessibilityState values
constexpr MapBuffer::Key ACCESSIBILITY_STATE_BUSY = 0;
constexpr MapBuffer::Key ACCESSIBILITY_STATE_DISABLED = 1;
constexpr MapBuffer::Key ACCESSIBILITY_STATE_EXPANDED = 2;
constexpr MapBuffer::Key ACCESSIBILITY_STATE_SELECTED = 3;
constexpr MapBuffer::Key ACCESSIBILITY_STATE_CHECKED = 4;
MapBuffer convertAccessibilityState(AccessibilityState const &state) {
MapBufferBuilder builder(5);
builder.putBool(ACCESSIBILITY_STATE_BUSY, state.busy);
builder.putBool(ACCESSIBILITY_STATE_DISABLED, state.disabled);
builder.putBool(ACCESSIBILITY_STATE_EXPANDED, state.expanded);
builder.putBool(ACCESSIBILITY_STATE_SELECTED, state.selected);
int checked;
switch (state.checked) {
case AccessibilityState::Unchecked:
checked = 0;
break;
case AccessibilityState::Checked:
checked = 1;
break;
case AccessibilityState::Mixed:
checked = 2;
break;
case AccessibilityState::None:
checked = 3;
break;
}
builder.putInt(ACCESSIBILITY_STATE_CHECKED, checked);
return builder.build();
}
// TODO: Currently unsupported: nextFocusForward/Left/Up/Right/Down
void AccessibilityProps::propsDiffMapBuffer(
Props const *oldPropsPtr,
MapBufferBuilder &builder) const {
// Call with default props if necessary
if (oldPropsPtr == nullptr) {
AccessibilityProps defaultProps{};
propsDiffMapBuffer(reinterpret_cast<Props *>(&defaultProps), builder);
return;
}
AccessibilityProps const &oldProps =
*(reinterpret_cast<const AccessibilityProps *>(oldPropsPtr));
AccessibilityProps const &newProps = *this;
if (oldProps.accessibilityActions != newProps.accessibilityActions) {
builder.putMapBuffer(
AP_ACCESSIBILITY_ACTIONS,
convertAccessibilityActions(newProps.accessibilityActions));
}
if (oldProps.accessibilityHint != newProps.accessibilityHint) {
builder.putString(AP_ACCESSIBILITY_HINT, newProps.accessibilityHint);
}
if (oldProps.accessibilityLabel != newProps.accessibilityLabel) {
builder.putString(AP_ACCESSIBILITY_LABEL, newProps.accessibilityLabel);
}
if (oldProps.accessibilityLabelledBy != newProps.accessibilityLabelledBy) {
builder.putMapBuffer(
AP_ACCESSIBILITY_LABELLED_BY,
convertAccessibilityLabelledBy(newProps.accessibilityLabelledBy));
}
if (oldProps.accessibilityLiveRegion != newProps.accessibilityLiveRegion) {
int value;
switch (newProps.accessibilityLiveRegion) {
case AccessibilityLiveRegion::None:
value = 0;
break;
case AccessibilityLiveRegion::Polite:
value = 1;
break;
case AccessibilityLiveRegion::Assertive:
value = 2;
break;
}
builder.putInt(AP_ACCESSIBILITY_LIVE_REGION, value);
}
if (oldProps.accessibilityRole != newProps.accessibilityRole) {
builder.putString(AP_ACCESSIBILITY_ROLE, newProps.accessibilityRole);
}
if (oldProps.accessibilityState != newProps.accessibilityState) {
builder.putMapBuffer(
AP_ACCESSIBILITY_STATE,
convertAccessibilityState(newProps.accessibilityState));
}
if (oldProps.accessibilityValue != newProps.accessibilityValue) {
builder.putString(
AP_ACCESSIBILITY_VALUE, newProps.accessibilityValue.text.value_or(""));
}
if (oldProps.accessible != newProps.accessible) {
builder.putBool(AP_ACCESSIBLE, newProps.accessible);
}
if (oldProps.importantForAccessibility !=
newProps.importantForAccessibility) {
int value;
switch (newProps.importantForAccessibility) {
case ImportantForAccessibility::Auto:
value = 0;
break;
case ImportantForAccessibility::Yes:
value = 1;
break;
case ImportantForAccessibility::No:
value = 2;
break;
case ImportantForAccessibility::NoHideDescendants:
value = 3;
break;
}
builder.putInt(AP_IMPORTANT_FOR_ACCESSIBILITY, value);
}
}
#endif
} // namespace react
} // namespace facebook

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

@ -0,0 +1,33 @@
/*
* 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 <react/renderer/mapbuffer/MapBuffer.h>
namespace facebook {
namespace react {
#ifdef ANDROID
constexpr MapBuffer::Key AP_ACCESSIBILITY_ACTIONS = 0;
constexpr MapBuffer::Key AP_ACCESSIBILITY_HINT = 1;
constexpr MapBuffer::Key AP_ACCESSIBILITY_LABEL = 2;
constexpr MapBuffer::Key AP_ACCESSIBILITY_LABELLED_BY = 3;
constexpr MapBuffer::Key AP_ACCESSIBILITY_LIVE_REGION = 4;
constexpr MapBuffer::Key AP_ACCESSIBILITY_ROLE = 5;
constexpr MapBuffer::Key AP_ACCESSIBILITY_STATE = 6;
constexpr MapBuffer::Key AP_ACCESSIBILITY_VALUE = 7;
constexpr MapBuffer::Key AP_ACCESSIBLE = 8;
constexpr MapBuffer::Key AP_IMPORTANT_FOR_ACCESSIBILITY = 19;
// AccessibilityAction values
constexpr MapBuffer::Key ACCESSIBILITY_ACTION_NAME = 0;
constexpr MapBuffer::Key ACCESSIBILITY_ACTION_LABEL = 1;
#endif
} // namespace react
} // namespace facebook

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

@ -41,6 +41,11 @@ class ViewProps : public YogaStylableProps, public AccessibilityProps {
const char *propName, const char *propName,
RawValue const &value); RawValue const &value);
#ifdef ANDROID
void propsDiffMapBuffer(Props const *oldProps, MapBufferBuilder &builder)
const override;
#endif
#pragma mark - Props #pragma mark - Props
// Color // Color
@ -51,7 +56,7 @@ class ViewProps : public YogaStylableProps, public AccessibilityProps {
// Borders // Borders
CascadedBorderRadii borderRadii{}; CascadedBorderRadii borderRadii{};
CascadedBorderColors borderColors{}; CascadedBorderColors borderColors{};
CascadedBorderCurves borderCurves{}; CascadedBorderCurves borderCurves{}; // iOS only?
CascadedBorderStyles borderStyles{}; CascadedBorderStyles borderStyles{};
// Shadow // Shadow

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

@ -0,0 +1,202 @@
/*
* 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.
*/
#ifdef ANDROID
#include "ViewPropsMapBuffer.h"
#include "ViewProps.h"
#include "viewPropConversions.h"
#include <react/renderer/graphics/conversions.h>
#include <react/renderer/mapbuffer/MapBufferBuilder.h>
namespace facebook {
namespace react {
// TODO: Currently unsupported: nextFocusForward/Left/Up/Right/Down
void ViewProps::propsDiffMapBuffer(
Props const *oldPropsPtr,
MapBufferBuilder &builder) const {
// Call with default props if necessary
if (oldPropsPtr == nullptr) {
ViewProps defaultProps{};
propsDiffMapBuffer(&defaultProps, builder);
return;
}
// Delegate to base classes
YogaStylableProps::propsDiffMapBuffer(oldPropsPtr, builder);
AccessibilityProps::propsDiffMapBuffer(oldPropsPtr, builder);
ViewProps const &oldProps = *(static_cast<const ViewProps *>(oldPropsPtr));
ViewProps const &newProps = *this;
if (oldProps.backfaceVisibility != newProps.backfaceVisibility) {
int value;
switch (newProps.backfaceVisibility) {
case BackfaceVisibility::Auto:
value = 0;
break;
case BackfaceVisibility::Visible:
value = 1;
break;
case BackfaceVisibility::Hidden:
value = 2;
break;
}
builder.putInt(VP_BACKFACE_VISIBILITY, value);
}
if (oldProps.backgroundColor != newProps.backgroundColor) {
builder.putInt(VP_BG_COLOR, toAndroidRepr(newProps.backgroundColor));
}
if (oldProps.foregroundColor != newProps.foregroundColor) {
builder.putInt(VP_FG_COLOR, toAndroidRepr(newProps.foregroundColor));
}
if (oldProps.borderCurves != newProps.borderCurves) {
builder.putMapBuffer(
VP_BORDER_CURVES, convertCascadedCorners(newProps.borderCurves));
}
if (oldProps.borderColors != newProps.borderColors) {
builder.putMapBuffer(
VP_BORDER_COLOR, convertBorderColors(newProps.borderColors));
}
if (oldProps.borderRadii != newProps.borderRadii) {
builder.putMapBuffer(
VP_BORDER_RADII, convertCascadedCorners(newProps.borderRadii));
}
if (oldProps.borderStyles != newProps.borderStyles) {
builder.putMapBuffer(
VP_BORDER_STYLE, convertCascadedEdges(newProps.borderStyles));
}
if (oldProps.elevation != newProps.elevation) {
builder.putDouble(VP_ELEVATION, newProps.elevation);
}
if (oldProps.focusable != newProps.focusable) {
builder.putBool(VP_FOCUSABLE, newProps.focusable);
}
if (oldProps.hasTVPreferredFocus != newProps.hasTVPreferredFocus) {
builder.putBool(VP_HAS_TV_FOCUS, newProps.hasTVPreferredFocus);
}
if (oldProps.hitSlop != newProps.hitSlop) {
builder.putMapBuffer(VP_HIT_SLOP, convertEdgeInsets(newProps.hitSlop));
}
if (oldProps.nativeBackground != newProps.nativeBackground) {
builder.putMapBuffer(
VP_NATIVE_BACKGROUND,
convertNativeBackground(newProps.nativeBackground));
}
if (oldProps.nativeForeground != newProps.nativeForeground) {
builder.putMapBuffer(
VP_NATIVE_FOREGROUND,
convertNativeBackground(newProps.nativeForeground));
}
if (oldProps.needsOffscreenAlphaCompositing !=
newProps.needsOffscreenAlphaCompositing) {
builder.putBool(
VP_OFFSCREEN_ALPHA_COMPOSITING,
newProps.needsOffscreenAlphaCompositing);
}
if (oldProps.opacity != newProps.opacity) {
builder.putDouble(VP_OPACITY, newProps.opacity);
}
if (oldProps.pointerEvents != newProps.pointerEvents) {
int value;
switch (newProps.pointerEvents) {
case PointerEventsMode::Auto:
value = 0;
break;
case PointerEventsMode::None:
value = 1;
break;
case PointerEventsMode::BoxNone:
value = 2;
break;
case PointerEventsMode::BoxOnly:
value = 3;
break;
}
builder.putInt(VP_POINTER_EVENTS, value);
}
if (oldProps.events != newProps.events) {
builder.putBool(
VP_POINTER_ENTER, newProps.events[ViewEvents::Offset::PointerEnter]);
builder.putBool(
VP_POINTER_LEAVE, newProps.events[ViewEvents::Offset::PointerLeave]);
builder.putBool(
VP_POINTER_MOVE, newProps.events[ViewEvents::Offset::PointerMove]);
builder.putBool(
VP_POINTER_ENTER_CAPTURE,
newProps.events[ViewEvents::Offset::PointerEnterCapture]);
builder.putBool(
VP_POINTER_LEAVE_CAPTURE,
newProps.events[ViewEvents::Offset::PointerLeaveCapture]);
builder.putBool(
VP_POINTER_MOVE_CAPTURE,
newProps.events[ViewEvents::Offset::PointerMoveCapture]);
builder.putBool(
VP_POINTER_OVER, newProps.events[ViewEvents::Offset::PointerOver]);
builder.putBool(
VP_POINTER_OVER_CAPTURE,
newProps.events[ViewEvents::Offset::PointerOverCapture]);
builder.putBool(
VP_POINTER_OUT, newProps.events[ViewEvents::Offset::PointerOut]);
builder.putBool(
VP_POINTER_OUT_CAPTURE,
newProps.events[ViewEvents::Offset::PointerOutCapture]);
}
if (oldProps.removeClippedSubviews != newProps.removeClippedSubviews) {
builder.putBool(VP_REMOVE_CLIPPED_SUBVIEW, newProps.removeClippedSubviews);
}
if (oldProps.renderToHardwareTextureAndroid !=
newProps.renderToHardwareTextureAndroid) {
builder.putBool(
VP_RENDER_TO_HARDWARE_TEXTURE, newProps.renderToHardwareTextureAndroid);
}
if (oldProps.shadowColor != newProps.shadowColor) {
builder.putInt(VP_SHADOW_COLOR, toAndroidRepr(newProps.shadowColor));
}
if (oldProps.testId != newProps.testId) {
builder.putString(VP_TEST_ID, newProps.testId);
}
if (oldProps.transform != newProps.transform) {
builder.putMapBuffer(VP_TRANSFORM, convertTransform(newProps.transform));
}
if (oldProps.zIndex != newProps.zIndex) {
builder.putInt(VP_ZINDEX, newProps.zIndex.value_or(0));
}
}
} // namespace react
} // namespace facebook
#endif

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

@ -0,0 +1,56 @@
/*
* 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 <react/renderer/mapbuffer/MapBuffer.h>
namespace facebook {
namespace react {
#ifdef ANDROID
constexpr MapBuffer::Key VP_BACKFACE_VISIBILITY = 9;
constexpr MapBuffer::Key VP_BG_COLOR = 10;
constexpr MapBuffer::Key VP_BORDER_COLOR = 11;
constexpr MapBuffer::Key VP_BORDER_RADII = 12;
constexpr MapBuffer::Key VP_BORDER_STYLE = 13;
constexpr MapBuffer::Key VP_COLLAPSABLE = 14;
constexpr MapBuffer::Key VP_ELEVATION = 15;
constexpr MapBuffer::Key VP_FOCUSABLE = 16;
constexpr MapBuffer::Key VP_HAS_TV_FOCUS = 17;
constexpr MapBuffer::Key VP_HIT_SLOP = 18;
constexpr MapBuffer::Key VP_NATIVE_BACKGROUND = 20;
constexpr MapBuffer::Key VP_NATIVE_FOREGROUND = 21;
constexpr MapBuffer::Key VP_OFFSCREEN_ALPHA_COMPOSITING = 23;
constexpr MapBuffer::Key VP_OPACITY = 24;
constexpr MapBuffer::Key VP_POINTER_EVENTS = 25;
constexpr MapBuffer::Key VP_POINTER_ENTER = 26;
constexpr MapBuffer::Key VP_POINTER_LEAVE = 27;
constexpr MapBuffer::Key VP_POINTER_MOVE = 28;
constexpr MapBuffer::Key VP_REMOVE_CLIPPED_SUBVIEW = 29;
constexpr MapBuffer::Key VP_RENDER_TO_HARDWARE_TEXTURE = 30;
constexpr MapBuffer::Key VP_SHADOW_COLOR = 31;
constexpr MapBuffer::Key VP_TEST_ID = 32;
constexpr MapBuffer::Key VP_TRANSFORM = 33;
constexpr MapBuffer::Key VP_ZINDEX = 34;
constexpr MapBuffer::Key VP_POINTER_ENTER_CAPTURE = 38;
constexpr MapBuffer::Key VP_POINTER_LEAVE_CAPTURE = 39;
constexpr MapBuffer::Key VP_POINTER_MOVE_CAPTURE = 40;
constexpr MapBuffer::Key VP_POINTER_OVER = 41;
constexpr MapBuffer::Key VP_POINTER_OVER_CAPTURE = 42;
constexpr MapBuffer::Key VP_POINTER_OUT = 43;
constexpr MapBuffer::Key VP_POINTER_OUT_CAPTURE = 44;
constexpr MapBuffer::Key VP_BORDER_CURVES = 45;
constexpr MapBuffer::Key VP_FG_COLOR = 46;
// Yoga values
constexpr MapBuffer::Key YG_BORDER_WIDTH = 100;
constexpr MapBuffer::Key YG_OVERFLOW = 101;
#endif
} // namespace react
} // namespace facebook

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

@ -31,6 +31,11 @@ class YogaStylableProps : public Props {
const char *propName, const char *propName,
RawValue const &value); RawValue const &value);
#ifdef ANDROID
void propsDiffMapBuffer(Props const *oldProps, MapBufferBuilder &builder)
const override;
#endif
#pragma mark - Props #pragma mark - Props
YGStyle yogaStyle{}; YGStyle yogaStyle{};
@ -39,7 +44,7 @@ class YogaStylableProps : public Props {
#pragma mark - DebugStringConvertible (Partial) #pragma mark - DebugStringConvertible (Partial)
SharedDebugStringConvertibleList getDebugProps() const; SharedDebugStringConvertibleList getDebugProps() const override;
#endif #endif
}; };

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

@ -0,0 +1,87 @@
/*
* 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.
*/
#ifdef ANDROID
#include "ViewProps.h"
#include "ViewPropsMapBuffer.h"
#include "viewPropConversions.h"
#include <react/renderer/mapbuffer/MapBufferBuilder.h>
namespace facebook {
namespace react {
MapBuffer convertBorderWidths(YGStyle::Edges const &border) {
MapBufferBuilder builder(7);
putOptionalFloat(
builder, EDGE_TOP, optionalFloatFromYogaValue(border[YGEdgeTop]));
putOptionalFloat(
builder, EDGE_RIGHT, optionalFloatFromYogaValue(border[YGEdgeRight]));
putOptionalFloat(
builder, EDGE_BOTTOM, optionalFloatFromYogaValue(border[YGEdgeBottom]));
putOptionalFloat(
builder, EDGE_LEFT, optionalFloatFromYogaValue(border[YGEdgeLeft]));
putOptionalFloat(
builder, EDGE_START, optionalFloatFromYogaValue(border[YGEdgeStart]));
putOptionalFloat(
builder, EDGE_END, optionalFloatFromYogaValue(border[YGEdgeEnd]));
putOptionalFloat(
builder, EDGE_ALL, optionalFloatFromYogaValue(border[YGEdgeAll]));
return builder.build();
}
// TODO: Currently unsupported: nextFocusForward/Left/Up/Right/Down
void YogaStylableProps::propsDiffMapBuffer(
Props const *oldPropsPtr,
MapBufferBuilder &builder) const {
// Call with default props if necessary
if (oldPropsPtr == nullptr) {
YogaStylableProps defaultProps{};
propsDiffMapBuffer(&defaultProps, builder);
return;
}
// Delegate to base classes
Props::propsDiffMapBuffer(oldPropsPtr, builder);
YogaStylableProps const &oldProps =
*(static_cast<const YogaStylableProps *>(oldPropsPtr));
YogaStylableProps const &newProps = *this;
if (oldProps.yogaStyle != newProps.yogaStyle) {
auto const &oldStyle = oldProps.yogaStyle;
auto const &newStyle = newProps.yogaStyle;
if (!(oldStyle.border() == newStyle.border())) {
builder.putMapBuffer(
YG_BORDER_WIDTH, convertBorderWidths(newStyle.border()));
}
if (oldStyle.overflow() != newStyle.overflow()) {
int value;
switch (newStyle.overflow()) {
case YGOverflowVisible:
value = 0;
break;
case YGOverflowHidden:
value = 1;
break;
case YGOverflowScroll:
value = 2;
break;
}
builder.putInt(YG_OVERFLOW, value);
}
}
}
} // namespace react
} // namespace facebook
#endif

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

@ -0,0 +1,24 @@
/*
* 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
#ifdef ANDROID
#include <react/renderer/mapbuffer/MapBuffer.h>
namespace facebook {
namespace react {
// Yoga values
constexpr MapBuffer::Key YG_BORDER_WIDTH = 100;
constexpr MapBuffer::Key YG_OVERFLOW = 101;
} // namespace react
} // namespace facebook
#endif

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

@ -0,0 +1,198 @@
/*
* 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 <react/renderer/components/view/ViewProps.h>
#include <react/renderer/components/view/ViewPropsMapBuffer.h>
#include <react/renderer/components/view/conversions.h>
#include <react/renderer/graphics/conversions.h>
#include <react/renderer/mapbuffer/MapBuffer.h>
#include <react/renderer/mapbuffer/MapBufferBuilder.h>
#include <optional>
namespace facebook {
namespace react {
namespace {
constexpr MapBuffer::Key EDGE_TOP = 0;
constexpr MapBuffer::Key EDGE_LEFT = 1;
constexpr MapBuffer::Key EDGE_RIGHT = 2;
constexpr MapBuffer::Key EDGE_BOTTOM = 3;
constexpr MapBuffer::Key EDGE_START = 4;
constexpr MapBuffer::Key EDGE_END = 5;
constexpr MapBuffer::Key EDGE_ALL = 6;
constexpr MapBuffer::Key CORNER_TOP_LEFT = 0;
constexpr MapBuffer::Key CORNER_TOP_RIGHT = 1;
constexpr MapBuffer::Key CORNER_BOTTOM_RIGHT = 2;
constexpr MapBuffer::Key CORNER_BOTTOM_LEFT = 3;
constexpr MapBuffer::Key CORNER_TOP_START = 4;
constexpr MapBuffer::Key CORNER_TOP_END = 5;
constexpr MapBuffer::Key CORNER_BOTTOM_END = 6;
constexpr MapBuffer::Key CORNER_BOTTOM_START = 7;
constexpr MapBuffer::Key CORNER_ALL = 8;
inline void putOptionalFloat(
MapBufferBuilder &builder,
MapBuffer::Key key,
std::optional<Float> const &value) {
builder.putDouble(key, value.value_or(NAN));
}
inline std::optional<Float> optionalFromValue(
std::optional<BorderCurve> const &value) {
if (!value) {
return {};
}
return {value.value() == BorderCurve::Circular ? 1 : 2};
}
inline std::optional<Float> optionalFromValue(
std::optional<Float> const &value) {
return value;
}
inline std::optional<Float> optionalFromValue(
std::optional<BorderStyle> const &value) {
if (!value) {
return {};
}
int intValue = -1;
switch (value.value()) {
case BorderStyle::Solid:
intValue = 0;
break;
case BorderStyle::Dotted:
intValue = 1;
break;
case BorderStyle::Dashed:
intValue = 2;
break;
}
return {intValue};
}
inline void putOptionalColor(
MapBufferBuilder &builder,
MapBuffer::Key key,
std::optional<SharedColor> const &color) {
builder.putInt(key, color.has_value() ? toAndroidRepr(color.value()) : -1);
}
inline MapBuffer convertBorderColors(CascadedBorderColors const &colors) {
MapBufferBuilder builder(7);
putOptionalColor(builder, EDGE_TOP, colors.top);
putOptionalColor(builder, EDGE_RIGHT, colors.right);
putOptionalColor(builder, EDGE_BOTTOM, colors.bottom);
putOptionalColor(builder, EDGE_LEFT, colors.left);
putOptionalColor(builder, EDGE_START, colors.start);
putOptionalColor(builder, EDGE_END, colors.end);
putOptionalColor(builder, EDGE_ALL, colors.all);
return builder.build();
}
template <typename T>
MapBuffer convertCascadedEdges(CascadedRectangleEdges<T> const &edges) {
MapBufferBuilder builder(7);
putOptionalFloat(builder, EDGE_TOP, optionalFromValue(edges.top));
putOptionalFloat(builder, EDGE_RIGHT, optionalFromValue(edges.right));
putOptionalFloat(builder, EDGE_BOTTOM, optionalFromValue(edges.bottom));
putOptionalFloat(builder, EDGE_LEFT, optionalFromValue(edges.left));
putOptionalFloat(builder, EDGE_START, optionalFromValue(edges.start));
putOptionalFloat(builder, EDGE_END, optionalFromValue(edges.end));
putOptionalFloat(builder, EDGE_ALL, optionalFromValue(edges.all));
return builder.build();
}
template <typename T>
MapBuffer convertCascadedCorners(CascadedRectangleCorners<T> const &corners) {
MapBufferBuilder builder(9);
putOptionalFloat(
builder, CORNER_TOP_LEFT, optionalFromValue(corners.topLeft));
putOptionalFloat(
builder, CORNER_TOP_RIGHT, optionalFromValue(corners.topRight));
putOptionalFloat(
builder, CORNER_BOTTOM_RIGHT, optionalFromValue(corners.bottomRight));
putOptionalFloat(
builder, CORNER_BOTTOM_LEFT, optionalFromValue(corners.bottomLeft));
putOptionalFloat(
builder, CORNER_TOP_START, optionalFromValue(corners.topStart));
putOptionalFloat(builder, CORNER_TOP_END, optionalFromValue(corners.topEnd));
putOptionalFloat(
builder, CORNER_BOTTOM_END, optionalFromValue(corners.bottomEnd));
putOptionalFloat(
builder, CORNER_BOTTOM_START, optionalFromValue(corners.bottomStart));
putOptionalFloat(builder, CORNER_ALL, optionalFromValue(corners.all));
return builder.build();
}
inline MapBuffer convertEdgeInsets(EdgeInsets const &insets) {
MapBufferBuilder builder(4);
builder.putDouble(EDGE_TOP, insets.top);
builder.putDouble(EDGE_RIGHT, insets.right);
builder.putDouble(EDGE_BOTTOM, insets.bottom);
builder.putDouble(EDGE_LEFT, insets.left);
return builder.build();
}
#ifdef ANDROID
constexpr MapBuffer::Key NATIVE_DRAWABLE_KIND = 0;
constexpr MapBuffer::Key NATIVE_DRAWABLE_ATTRIBUTE = 1;
constexpr MapBuffer::Key NATIVE_DRAWABLE_COLOR = 2;
constexpr MapBuffer::Key NATIVE_DRAWABLE_BORDERLESS = 3;
constexpr MapBuffer::Key NATIVE_DRAWABLE_RIPPLE_RADIUS = 4;
inline MapBuffer convertNativeBackground(
std::optional<NativeDrawable> const &value) {
if (!value.has_value()) {
return MapBufferBuilder::EMPTY();
}
auto const &drawable = value.value();
MapBufferBuilder builder(4);
switch (drawable.kind) {
case NativeDrawable::Kind::ThemeAttr:
builder.putInt(NATIVE_DRAWABLE_KIND, 0);
builder.putString(NATIVE_DRAWABLE_ATTRIBUTE, drawable.themeAttr);
break;
case NativeDrawable::Kind::Ripple:
builder.putInt(NATIVE_DRAWABLE_KIND, 1);
if (drawable.ripple.color.has_value()) {
builder.putInt(NATIVE_DRAWABLE_COLOR, drawable.ripple.color.value());
}
builder.putBool(NATIVE_DRAWABLE_BORDERLESS, drawable.ripple.borderless);
if (drawable.ripple.rippleRadius.has_value()) {
builder.putDouble(
NATIVE_DRAWABLE_RIPPLE_RADIUS,
drawable.ripple.rippleRadius.value());
}
break;
}
return builder.build();
}
#endif
inline MapBuffer convertTransform(Transform const &transform) {
MapBufferBuilder builder(16);
for (int32_t i = 0; i < transform.matrix.size(); i++) {
builder.putDouble(i, transform.matrix[i]);
}
return builder.build();
}
} // namespace
} // namespace react
} // namespace facebook

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

@ -26,4 +26,5 @@ target_link_libraries(react_render_core
react_debug react_debug
react_render_debug react_render_debug
react_render_graphics react_render_graphics
react_render_mapbuffer
react_utils) react_utils)

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

@ -6,6 +6,7 @@
*/ */
#include "Props.h" #include "Props.h"
#include "PropsMapBuffer.h"
#include <folly/dynamic.h> #include <folly/dynamic.h>
#include <react/renderer/core/propsConversions.h> #include <react/renderer/core/propsConversions.h>

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

@ -16,6 +16,10 @@
#include <react/renderer/core/Sealable.h> #include <react/renderer/core/Sealable.h>
#include <react/renderer/debug/DebugStringConvertible.h> #include <react/renderer/debug/DebugStringConvertible.h>
#ifdef ANDROID
#include <react/renderer/mapbuffer/MapBufferBuilder.h>
#endif
namespace facebook { namespace facebook {
namespace react { namespace react {
@ -71,6 +75,10 @@ class Props : public virtual Sealable, public virtual DebugStringConvertible {
#ifdef ANDROID #ifdef ANDROID
folly::dynamic rawProps = folly::dynamic::object(); folly::dynamic rawProps = folly::dynamic::object();
virtual void propsDiffMapBuffer(
Props const *oldProps,
MapBufferBuilder &builder) const;
#endif #endif
}; };

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

@ -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.
*/
#include "PropsMapBuffer.h"
#include "Props.h"
#include <react/renderer/mapbuffer/MapBufferBuilder.h>
namespace facebook {
namespace react {
#ifdef ANDROID
void Props::propsDiffMapBuffer(
Props const *oldPropsPtr,
MapBufferBuilder &builder) const {
// Call with default props if necessary
if (oldPropsPtr == nullptr) {
Props defaultProps{};
propsDiffMapBuffer(&defaultProps, builder);
return;
}
Props const &oldProps = *oldPropsPtr;
Props const &newProps = *this;
if (oldProps.nativeId != newProps.nativeId) {
builder.putString(PROPS_NATIVE_ID, nativeId);
}
}
#endif
} // namespace react
} // namespace facebook

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

@ -0,0 +1,23 @@
/*
* 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
#ifdef ANDROID
#include <react/renderer/mapbuffer/MapBuffer.h>
namespace facebook {
namespace react {
constexpr MapBuffer::Key PROPS_MAX = 1;
constexpr MapBuffer::Key PROPS_NATIVE_ID = 1;
} // namespace react
} // namespace facebook
#endif