Fabric: folly::dynamic was replaced with RawValue in prop-parsing infra
Summary: Our long-term plan is to completely illuminate `jsi::Value`-to-`folly::dynamic` serialization step in prop parsing process improving performance and memory pressure. At the same time, we don't want to introduce a hard dependency in application code to JSI because it exposes direct access to VM and prevents parsing some data that come *NOT* from JSVM. RawValue is an extremely light-weight (hopefully fully optimized-out) abstraction that provides limited JSON-like and C++-idiomatic interface. The current particular implementation is still using `folly::dynamic` inside, but I have fully JSI-powered one which will replace the current one right after we figure out how to deal with folly::dynamic-specific callsites. Or we can implement RawValue in a hybrid manner if a code-size implication of that will be minimal. Reviewed By: JoshuaGross, mdvacca Differential Revision: D13962466 fbshipit-source-id: e848522fd242f21e9e771773f2103f1c1d9d7f21
This commit is contained in:
parent
b0c8275369
commit
9842e39019
|
@ -171,11 +171,7 @@ local_ref<JMountItem::javaobject> createUpdatePropsMountItem(const jni::global_r
|
|||
auto newViewProps = *std::dynamic_pointer_cast<const ViewProps>(shadowView.props);
|
||||
|
||||
// TODO: move props from map to a typed object.
|
||||
auto rawProps = shadowView.props->rawProps;
|
||||
folly::dynamic newProps = folly::dynamic::object();
|
||||
for (auto element : rawProps) {
|
||||
newProps[element.first] = element.second;
|
||||
}
|
||||
auto newProps = shadowView.props->rawProps;
|
||||
|
||||
local_ref<ReadableNativeMap::jhybridobject> readableMap = ReadableNativeMap::newObjectCxxArgs(newProps);
|
||||
|
||||
|
|
|
@ -36,8 +36,8 @@ inline std::string toString(const EllipsizeMode &ellipsisMode) {
|
|||
}
|
||||
}
|
||||
|
||||
inline void fromDynamic(const folly::dynamic &value, EllipsizeMode &result) {
|
||||
auto string = value.getString();
|
||||
inline void fromRawValue(const RawValue &value, EllipsizeMode &result) {
|
||||
auto string = (std::string)value;
|
||||
if (string == "clip") {
|
||||
result = EllipsizeMode::Clip;
|
||||
return;
|
||||
|
@ -57,8 +57,8 @@ inline void fromDynamic(const folly::dynamic &value, EllipsizeMode &result) {
|
|||
abort();
|
||||
}
|
||||
|
||||
inline void fromDynamic(const folly::dynamic &value, FontWeight &result) {
|
||||
auto string = value.asString();
|
||||
inline void fromRawValue(const RawValue &value, FontWeight &result) {
|
||||
auto string = (std::string)value;
|
||||
if (string == "normal") {
|
||||
result = FontWeight::Regular;
|
||||
return;
|
||||
|
@ -114,8 +114,8 @@ inline std::string toString(const FontWeight &fontWeight) {
|
|||
return folly::to<std::string>((int)fontWeight);
|
||||
}
|
||||
|
||||
inline void fromDynamic(const folly::dynamic &value, FontStyle &result) {
|
||||
auto string = value.asString();
|
||||
inline void fromRawValue(const RawValue &value, FontStyle &result) {
|
||||
auto string = (std::string)value;
|
||||
if (string == "normal") {
|
||||
result = FontStyle::Normal;
|
||||
return;
|
||||
|
@ -142,28 +142,28 @@ inline std::string toString(const FontStyle &fontStyle) {
|
|||
}
|
||||
}
|
||||
|
||||
inline void fromDynamic(const folly::dynamic &value, FontVariant &result) {
|
||||
assert(value.isArray());
|
||||
inline void fromRawValue(const RawValue &value, FontVariant &result) {
|
||||
assert(value.hasType<std::vector<std::string>>());
|
||||
result = FontVariant::Default;
|
||||
for (auto &&item : value) {
|
||||
auto string = item.asString();
|
||||
if (string == "small-caps") {
|
||||
auto items = std::vector<std::string>{value};
|
||||
for (const auto &item : items) {
|
||||
if (item == "small-caps") {
|
||||
result = (FontVariant)((int)result | (int)FontVariant::SmallCaps);
|
||||
continue;
|
||||
}
|
||||
if (string == "oldstyle-nums") {
|
||||
if (item == "oldstyle-nums") {
|
||||
result = (FontVariant)((int)result | (int)FontVariant::OldstyleNums);
|
||||
continue;
|
||||
}
|
||||
if (string == "lining-nums") {
|
||||
if (item == "lining-nums") {
|
||||
result = (FontVariant)((int)result | (int)FontVariant::LiningNums);
|
||||
continue;
|
||||
}
|
||||
if (string == "tabular-nums") {
|
||||
if (item == "tabular-nums") {
|
||||
result = (FontVariant)((int)result | (int)FontVariant::TabularNums);
|
||||
continue;
|
||||
}
|
||||
if (string == "proportional-nums") {
|
||||
if (item == "proportional-nums") {
|
||||
result = (FontVariant)((int)result | (int)FontVariant::ProportionalNums);
|
||||
continue;
|
||||
}
|
||||
|
@ -196,8 +196,8 @@ inline std::string toString(const FontVariant &fontVariant) {
|
|||
return result;
|
||||
}
|
||||
|
||||
inline void fromDynamic(const folly::dynamic &value, TextAlignment &result) {
|
||||
auto string = value.asString();
|
||||
inline void fromRawValue(const RawValue &value, TextAlignment &result) {
|
||||
auto string = (std::string)value;
|
||||
if (string == "natural") {
|
||||
result = TextAlignment::Natural;
|
||||
return;
|
||||
|
@ -236,8 +236,8 @@ inline std::string toString(const TextAlignment &textAlignment) {
|
|||
}
|
||||
}
|
||||
|
||||
inline void fromDynamic(const folly::dynamic &value, WritingDirection &result) {
|
||||
auto string = value.asString();
|
||||
inline void fromRawValue(const RawValue &value, WritingDirection &result) {
|
||||
auto string = (std::string)value;
|
||||
if (string == "natural") {
|
||||
result = WritingDirection::Natural;
|
||||
return;
|
||||
|
@ -264,10 +264,10 @@ inline std::string toString(const WritingDirection &writingDirection) {
|
|||
}
|
||||
}
|
||||
|
||||
inline void fromDynamic(
|
||||
const folly::dynamic &value,
|
||||
inline void fromRawValue(
|
||||
const RawValue &value,
|
||||
TextDecorationLineType &result) {
|
||||
auto string = value.asString();
|
||||
auto string = (std::string)value;
|
||||
if (string == "none") {
|
||||
result = TextDecorationLineType::None;
|
||||
return;
|
||||
|
@ -301,10 +301,10 @@ inline std::string toString(
|
|||
}
|
||||
}
|
||||
|
||||
inline void fromDynamic(
|
||||
const folly::dynamic &value,
|
||||
inline void fromRawValue(
|
||||
const RawValue &value,
|
||||
TextDecorationLineStyle &result) {
|
||||
auto string = value.asString();
|
||||
auto string = (std::string)value;
|
||||
if (string == "single") {
|
||||
result = TextDecorationLineStyle::Single;
|
||||
return;
|
||||
|
@ -332,10 +332,10 @@ inline std::string toString(
|
|||
}
|
||||
}
|
||||
|
||||
inline void fromDynamic(
|
||||
const folly::dynamic &value,
|
||||
inline void fromRawValue(
|
||||
const RawValue &value,
|
||||
TextDecorationLinePattern &result) {
|
||||
auto string = value.asString();
|
||||
auto string = (std::string)value;
|
||||
if (string == "solid") {
|
||||
result = TextDecorationLinePattern::Solid;
|
||||
return;
|
||||
|
|
|
@ -13,10 +13,10 @@
|
|||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
inline void fromDynamic(
|
||||
const folly::dynamic &value,
|
||||
inline void fromRawValue(
|
||||
const RawValue &value,
|
||||
ActivityIndicatorViewSize &result) {
|
||||
auto string = value.asString();
|
||||
auto string = (std::string)value;
|
||||
if (string == "large") {
|
||||
result = ActivityIndicatorViewSize::Large;
|
||||
return;
|
||||
|
|
|
@ -14,41 +14,43 @@
|
|||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
inline void fromDynamic(const folly::dynamic &value, ImageSource &result) {
|
||||
if (value.isString()) {
|
||||
result = {.type = ImageSource::Type::Remote, .uri = value.asString()};
|
||||
inline void fromRawValue(const RawValue &value, ImageSource &result) {
|
||||
if (value.hasType<std::string>()) {
|
||||
result = {.type = ImageSource::Type::Remote, .uri = (std::string)value};
|
||||
return;
|
||||
}
|
||||
|
||||
if (value.isObject()) {
|
||||
if (value.hasType<std::unordered_map<std::string, RawValue>>()) {
|
||||
auto items = (std::unordered_map<std::string, RawValue>)value;
|
||||
result = {};
|
||||
|
||||
result.type = ImageSource::Type::Remote;
|
||||
|
||||
if (value.count("__packager_asset")) {
|
||||
if (items.find("__packager_asset") != items.end()) {
|
||||
result.type = ImageSource::Type::Local;
|
||||
}
|
||||
|
||||
if (value.count("width") && value.count("height")) {
|
||||
fromDynamic(value, result.size);
|
||||
if (items.find("width") != items.end() &&
|
||||
items.find("height") != items.end()) {
|
||||
result.size = {(Float)items.at("width"), (Float)items.at("height")};
|
||||
}
|
||||
|
||||
if (value.count("scale")) {
|
||||
result.scale = (Float)value["scale"].asDouble();
|
||||
if (items.find("scale") != items.end()) {
|
||||
result.scale = (Float)items.at("scale");
|
||||
} else {
|
||||
result.scale = value.count("deprecated") ? 0.0 : 1.0;
|
||||
result.scale = items.find("deprecated") != items.end() ? 0.0 : 1.0;
|
||||
}
|
||||
|
||||
if (value.count("url")) {
|
||||
result.uri = value["url"].asString();
|
||||
if (items.find("url") != items.end()) {
|
||||
result.uri = (std::string)items.at("url");
|
||||
}
|
||||
|
||||
if (value.count("uri")) {
|
||||
result.uri = value["uri"].asString();
|
||||
if (items.find("uri") != items.end()) {
|
||||
result.uri = (std::string)items.at("uri");
|
||||
}
|
||||
|
||||
if (value.count("bundle")) {
|
||||
result.bundle = value["bundle"].asString();
|
||||
if (items.find("bundle") != items.end()) {
|
||||
result.bundle = (std::string)items.at("bundle");
|
||||
result.type = ImageSource::Type::Local;
|
||||
}
|
||||
|
||||
|
@ -62,9 +64,9 @@ inline std::string toString(const ImageSource &value) {
|
|||
return "{uri: " + value.uri + "}";
|
||||
}
|
||||
|
||||
inline void fromDynamic(const folly::dynamic &value, ImageResizeMode &result) {
|
||||
assert(value.isString());
|
||||
auto stringValue = value.asString();
|
||||
inline void fromRawValue(const RawValue &value, ImageResizeMode &result) {
|
||||
assert(value.hasType<std::string>());
|
||||
auto stringValue = (std::string)value;
|
||||
if (stringValue == "cover") {
|
||||
result = ImageResizeMode::Cover;
|
||||
return;
|
||||
|
|
|
@ -13,10 +13,10 @@
|
|||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
inline void fromDynamic(
|
||||
const folly::dynamic &value,
|
||||
inline void fromRawValue(
|
||||
const RawValue &value,
|
||||
ScrollViewSnapToAlignment &result) {
|
||||
auto string = value.asString();
|
||||
auto string = (std::string)value;
|
||||
if (string == "start") {
|
||||
result = ScrollViewSnapToAlignment::Start;
|
||||
return;
|
||||
|
@ -32,10 +32,10 @@ inline void fromDynamic(
|
|||
abort();
|
||||
}
|
||||
|
||||
inline void fromDynamic(
|
||||
const folly::dynamic &value,
|
||||
inline void fromRawValue(
|
||||
const RawValue &value,
|
||||
ScrollViewIndicatorStyle &result) {
|
||||
auto string = value.asString();
|
||||
auto string = (std::string)value;
|
||||
if (string == "default") {
|
||||
result = ScrollViewIndicatorStyle::Default;
|
||||
return;
|
||||
|
@ -51,10 +51,10 @@ inline void fromDynamic(
|
|||
abort();
|
||||
}
|
||||
|
||||
inline void fromDynamic(
|
||||
const folly::dynamic &value,
|
||||
inline void fromRawValue(
|
||||
const RawValue &value,
|
||||
ScrollViewKeyboardDismissMode &result) {
|
||||
auto string = value.asString();
|
||||
auto string = (std::string)value;
|
||||
if (string == "none") {
|
||||
result = ScrollViewKeyboardDismissMode::None;
|
||||
return;
|
||||
|
|
|
@ -81,20 +81,18 @@ inline void fromString(const std::string &string, AccessibilityTraits &result) {
|
|||
abort();
|
||||
}
|
||||
|
||||
inline void fromDynamic(
|
||||
const folly::dynamic &value,
|
||||
AccessibilityTraits &result) {
|
||||
if (value.isString()) {
|
||||
fromString(value.asString(), result);
|
||||
inline void fromRawValue(const RawValue &value, AccessibilityTraits &result) {
|
||||
if (value.hasType<std::string>()) {
|
||||
fromString((std::string)value, result);
|
||||
return;
|
||||
}
|
||||
|
||||
if (value.isArray()) {
|
||||
if (value.hasType<std::vector<std::string>>()) {
|
||||
result = {};
|
||||
for (auto &item : value) {
|
||||
auto string = item.asString();
|
||||
auto items = (std::vector<std::string>)value;
|
||||
for (auto &item : items) {
|
||||
AccessibilityTraits itemAccessibilityTraits;
|
||||
fromString(value.asString(), itemAccessibilityTraits);
|
||||
fromString(item, itemAccessibilityTraits);
|
||||
result = result | itemAccessibilityTraits;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -126,9 +126,9 @@ inline YGDirection yogaDirectionFromLayoutDirection(LayoutDirection direction) {
|
|||
}
|
||||
}
|
||||
|
||||
inline void fromDynamic(const folly::dynamic &value, YGDirection &result) {
|
||||
assert(value.isString());
|
||||
auto stringValue = value.asString();
|
||||
inline void fromRawValue(const RawValue &value, YGDirection &result) {
|
||||
assert(value.hasType<std::string>());
|
||||
auto stringValue = (std::string)value;
|
||||
if (stringValue == "inherit") {
|
||||
result = YGDirectionInherit;
|
||||
return;
|
||||
|
@ -144,9 +144,9 @@ inline void fromDynamic(const folly::dynamic &value, YGDirection &result) {
|
|||
abort();
|
||||
}
|
||||
|
||||
inline void fromDynamic(const folly::dynamic &value, YGFlexDirection &result) {
|
||||
assert(value.isString());
|
||||
auto stringValue = value.asString();
|
||||
inline void fromRawValue(const RawValue &value, YGFlexDirection &result) {
|
||||
assert(value.hasType<std::string>());
|
||||
auto stringValue = (std::string)value;
|
||||
if (stringValue == "column") {
|
||||
result = YGFlexDirectionColumn;
|
||||
return;
|
||||
|
@ -166,9 +166,9 @@ inline void fromDynamic(const folly::dynamic &value, YGFlexDirection &result) {
|
|||
abort();
|
||||
}
|
||||
|
||||
inline void fromDynamic(const folly::dynamic &value, YGJustify &result) {
|
||||
assert(value.isString());
|
||||
auto stringValue = value.asString();
|
||||
inline void fromRawValue(const RawValue &value, YGJustify &result) {
|
||||
assert(value.hasType<std::string>());
|
||||
auto stringValue = (std::string)value;
|
||||
if (stringValue == "flex-start") {
|
||||
result = YGJustifyFlexStart;
|
||||
return;
|
||||
|
@ -196,9 +196,9 @@ inline void fromDynamic(const folly::dynamic &value, YGJustify &result) {
|
|||
abort();
|
||||
}
|
||||
|
||||
inline void fromDynamic(const folly::dynamic &value, YGAlign &result) {
|
||||
assert(value.isString());
|
||||
auto stringValue = value.asString();
|
||||
inline void fromRawValue(const RawValue &value, YGAlign &result) {
|
||||
assert(value.hasType<std::string>());
|
||||
auto stringValue = (std::string)value;
|
||||
if (stringValue == "auto") {
|
||||
result = YGAlignAuto;
|
||||
return;
|
||||
|
@ -234,9 +234,9 @@ inline void fromDynamic(const folly::dynamic &value, YGAlign &result) {
|
|||
abort();
|
||||
}
|
||||
|
||||
inline void fromDynamic(const folly::dynamic &value, YGPositionType &result) {
|
||||
assert(value.isString());
|
||||
auto stringValue = value.asString();
|
||||
inline void fromRawValue(const RawValue &value, YGPositionType &result) {
|
||||
assert(value.hasType<std::string>());
|
||||
auto stringValue = (std::string)value;
|
||||
if (stringValue == "relative") {
|
||||
result = YGPositionTypeRelative;
|
||||
return;
|
||||
|
@ -248,9 +248,9 @@ inline void fromDynamic(const folly::dynamic &value, YGPositionType &result) {
|
|||
abort();
|
||||
}
|
||||
|
||||
inline void fromDynamic(const folly::dynamic &value, YGWrap &result) {
|
||||
assert(value.isString());
|
||||
auto stringValue = value.asString();
|
||||
inline void fromRawValue(const RawValue &value, YGWrap &result) {
|
||||
assert(value.hasType<std::string>());
|
||||
auto stringValue = (std::string)value;
|
||||
if (stringValue == "no-wrap") {
|
||||
result = YGWrapNoWrap;
|
||||
return;
|
||||
|
@ -266,9 +266,9 @@ inline void fromDynamic(const folly::dynamic &value, YGWrap &result) {
|
|||
abort();
|
||||
}
|
||||
|
||||
inline void fromDynamic(const folly::dynamic &value, YGOverflow &result) {
|
||||
assert(value.isString());
|
||||
auto stringValue = value.asString();
|
||||
inline void fromRawValue(const RawValue &value, YGOverflow &result) {
|
||||
assert(value.hasType<std::string>());
|
||||
auto stringValue = (std::string)value;
|
||||
if (stringValue == "visible") {
|
||||
result = YGOverflowVisible;
|
||||
return;
|
||||
|
@ -284,9 +284,9 @@ inline void fromDynamic(const folly::dynamic &value, YGOverflow &result) {
|
|||
abort();
|
||||
}
|
||||
|
||||
inline void fromDynamic(const folly::dynamic &value, YGDisplay &result) {
|
||||
assert(value.isString());
|
||||
auto stringValue = value.asString();
|
||||
inline void fromRawValue(const RawValue &value, YGDisplay &result) {
|
||||
assert(value.hasType<std::string>());
|
||||
auto stringValue = (std::string)value;
|
||||
if (stringValue == "flex") {
|
||||
result = YGDisplayFlex;
|
||||
return;
|
||||
|
@ -298,14 +298,14 @@ inline void fromDynamic(const folly::dynamic &value, YGDisplay &result) {
|
|||
abort();
|
||||
}
|
||||
|
||||
inline void fromDynamic(
|
||||
const folly::dynamic &value,
|
||||
inline void fromRawValue(
|
||||
const RawValue &value,
|
||||
decltype(YGStyle{}.margin[0]) /* type is subject to change */ &result) {
|
||||
if (value.isNumber()) {
|
||||
result = yogaStyleValueFromFloat(value.asDouble());
|
||||
if (value.hasType<Float>()) {
|
||||
result = yogaStyleValueFromFloat((Float)value);
|
||||
return;
|
||||
} else if (value.isString()) {
|
||||
const auto stringValue = value.asString();
|
||||
} else if (value.hasType<std::string>()) {
|
||||
const auto stringValue = (std::string)value;
|
||||
if (stringValue == "auto") {
|
||||
result = YGValueUndefined;
|
||||
return;
|
||||
|
@ -324,12 +324,12 @@ inline void fromDynamic(
|
|||
result = YGValueUndefined;
|
||||
}
|
||||
|
||||
inline void fromDynamic(const folly::dynamic &value, YGFloatOptional &result) {
|
||||
if (value.isNumber()) {
|
||||
result = YGFloatOptional(value.asDouble());
|
||||
inline void fromRawValue(const RawValue &value, YGFloatOptional &result) {
|
||||
if (value.hasType<float>()) {
|
||||
result = YGFloatOptional((float)value);
|
||||
return;
|
||||
} else if (value.isString()) {
|
||||
const auto stringValue = value.asString();
|
||||
} else if (value.hasType<std::string>()) {
|
||||
const auto stringValue = (std::string)value;
|
||||
if (stringValue == "auto") {
|
||||
result = YGFloatOptional();
|
||||
return;
|
||||
|
@ -338,76 +338,74 @@ inline void fromDynamic(const folly::dynamic &value, YGFloatOptional &result) {
|
|||
abort();
|
||||
}
|
||||
|
||||
inline void fromDynamic(const folly::dynamic &value, Transform &result) {
|
||||
assert(value.isArray());
|
||||
inline void fromRawValue(const RawValue &value, Transform &result) {
|
||||
assert(value.hasType<std::vector<RawValue>>());
|
||||
auto transformMatrix = Transform{};
|
||||
for (const auto &tranformConfiguration : value) {
|
||||
assert(tranformConfiguration.isObject());
|
||||
auto pair = *tranformConfiguration.items().begin();
|
||||
const auto &operation = pair.first.asString();
|
||||
const auto ¶meters = pair.second;
|
||||
auto configurations = (std::vector<RawValue>)value;
|
||||
|
||||
for (const auto &configuration : configurations) {
|
||||
auto configurationPair =
|
||||
(std::unordered_map<std::string, RawValue>)configuration;
|
||||
auto pair = configurationPair.begin();
|
||||
auto operation = pair->first;
|
||||
auto ¶meters = pair->second;
|
||||
|
||||
if (operation == "matrix") {
|
||||
assert(parameters.isArray());
|
||||
assert(parameters.size() == transformMatrix.matrix.size());
|
||||
assert(parameters.hasType<std::vector<Float>>());
|
||||
auto numbers = (std::vector<Float>)parameters;
|
||||
assert(numbers.size() == transformMatrix.matrix.size());
|
||||
auto i = 0;
|
||||
for (auto item : parameters) {
|
||||
transformMatrix.matrix[i++] = (Float)item.asDouble();
|
||||
for (auto number : numbers) {
|
||||
transformMatrix.matrix[i++] = number;
|
||||
}
|
||||
} else if (operation == "perspective") {
|
||||
transformMatrix = transformMatrix *
|
||||
Transform::Perspective((Float)parameters.asDouble());
|
||||
} else if (operation == "rotateX") {
|
||||
transformMatrix = transformMatrix *
|
||||
Transform::Rotate((Float)parameters.asDouble(), 0, 0);
|
||||
} else if (operation == "rotateY") {
|
||||
transformMatrix = transformMatrix *
|
||||
Transform::Rotate(0, (Float)parameters.asDouble(), 0);
|
||||
} else if (operation == "rotateZ") {
|
||||
transformMatrix = transformMatrix *
|
||||
Transform::Rotate(0, 0, (Float)parameters.asDouble());
|
||||
} else if (operation == "scale") {
|
||||
transformMatrix = transformMatrix *
|
||||
Transform::Scale((Float)parameters.asDouble(),
|
||||
(Float)parameters.asDouble(),
|
||||
(Float)parameters.asDouble());
|
||||
} else if (operation == "scaleX") {
|
||||
transformMatrix = transformMatrix *
|
||||
Transform::Scale((Float)parameters.asDouble(), 0, 0);
|
||||
} else if (operation == "scaleY") {
|
||||
transformMatrix = transformMatrix *
|
||||
Transform::Scale(0, (Float)parameters.asDouble(), 0);
|
||||
} else if (operation == "scaleZ") {
|
||||
transformMatrix = transformMatrix *
|
||||
Transform::Scale(0, 0, (Float)parameters.asDouble());
|
||||
} else if (operation == "translate") {
|
||||
transformMatrix =
|
||||
transformMatrix *
|
||||
Transform::Translate(
|
||||
parameters[0].asDouble(), parameters[1].asDouble(), 0);
|
||||
transformMatrix * Transform::Perspective((Float)parameters);
|
||||
} else if (operation == "rotateX") {
|
||||
transformMatrix =
|
||||
transformMatrix * Transform::Rotate((Float)parameters, 0, 0);
|
||||
} else if (operation == "rotateY") {
|
||||
transformMatrix =
|
||||
transformMatrix * Transform::Rotate(0, (Float)parameters, 0);
|
||||
} else if (operation == "rotateZ") {
|
||||
transformMatrix =
|
||||
transformMatrix * Transform::Rotate(0, 0, (Float)parameters);
|
||||
} else if (operation == "scale") {
|
||||
auto number = (Float)parameters;
|
||||
transformMatrix =
|
||||
transformMatrix * Transform::Scale(number, number, number);
|
||||
} else if (operation == "scaleX") {
|
||||
transformMatrix =
|
||||
transformMatrix * Transform::Scale((Float)parameters, 0, 0);
|
||||
} else if (operation == "scaleY") {
|
||||
transformMatrix =
|
||||
transformMatrix * Transform::Scale(0, (Float)parameters, 0);
|
||||
} else if (operation == "scaleZ") {
|
||||
transformMatrix =
|
||||
transformMatrix * Transform::Scale(0, 0, (Float)parameters);
|
||||
} else if (operation == "translate") {
|
||||
auto numbers = (std::vector<Float>)parameters;
|
||||
transformMatrix = transformMatrix *
|
||||
Transform::Translate(numbers.at(0), numbers.at(1), 0);
|
||||
} else if (operation == "translateX") {
|
||||
transformMatrix =
|
||||
transformMatrix * Transform::Translate(parameters.asDouble(), 0, 0);
|
||||
transformMatrix * Transform::Translate((Float)parameters, 0, 0);
|
||||
} else if (operation == "translateY") {
|
||||
transformMatrix =
|
||||
transformMatrix * Transform::Translate(0, parameters.asDouble(), 0);
|
||||
transformMatrix * Transform::Translate(0, (Float)parameters, 0);
|
||||
} else if (operation == "skewX") {
|
||||
transformMatrix =
|
||||
transformMatrix * Transform::Skew(parameters.asDouble(), 0);
|
||||
transformMatrix = transformMatrix * Transform::Skew((Float)parameters, 0);
|
||||
} else if (operation == "skewY") {
|
||||
transformMatrix =
|
||||
transformMatrix * Transform::Skew(0, parameters.asDouble());
|
||||
transformMatrix = transformMatrix * Transform::Skew(0, (Float)parameters);
|
||||
}
|
||||
}
|
||||
|
||||
result = transformMatrix;
|
||||
}
|
||||
|
||||
inline void fromDynamic(
|
||||
const folly::dynamic &value,
|
||||
PointerEventsMode &result) {
|
||||
assert(value.isString());
|
||||
auto stringValue = value.asString();
|
||||
inline void fromRawValue(const RawValue &value, PointerEventsMode &result) {
|
||||
assert(value.hasType<std::string>());
|
||||
auto stringValue = (std::string)value;
|
||||
if (stringValue == "auto") {
|
||||
result = PointerEventsMode::Auto;
|
||||
return;
|
||||
|
@ -427,9 +425,9 @@ inline void fromDynamic(
|
|||
abort();
|
||||
}
|
||||
|
||||
inline void fromDynamic(const folly::dynamic &value, BorderStyle &result) {
|
||||
assert(value.isString());
|
||||
auto stringValue = value.asString();
|
||||
inline void fromRawValue(const RawValue &value, BorderStyle &result) {
|
||||
assert(value.hasType<std::string>());
|
||||
auto stringValue = (std::string)value;
|
||||
if (stringValue == "solid") {
|
||||
result = BorderStyle::Solid;
|
||||
return;
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#include "RawProps.h"
|
|
@ -0,0 +1,97 @@
|
|||
/**
|
||||
* Copyright (c) Facebook, Inc. and its 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 <folly/dynamic.h>
|
||||
#include <jsi/JSIDynamic.h>
|
||||
#include <jsi/jsi.h>
|
||||
#include <react/core/RawValue.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
/*
|
||||
* `RawProps` represents an untyped map of props comes from JavaScript side.
|
||||
* `RawProps` stores JSI (or `folly::dynamic`) primitives inside and abstract
|
||||
* them as `RawValue` objects.
|
||||
* `RawProps` is NOT a thread-safe type nor long-living type.
|
||||
* The caller must not store values of this type.
|
||||
* The class is practically a wrapper around a `jsi::Value and `jsi::Runtime`
|
||||
* pair (or folly::dynamic) preventing direct access to it and inefficient
|
||||
* misuse. Not copyable, not moveable.
|
||||
*/
|
||||
class RawProps {
|
||||
public:
|
||||
/*
|
||||
* Creates an object with given `runtime` and `value`.
|
||||
*/
|
||||
RawProps(jsi::Runtime &runtime, const jsi::Value &value) noexcept
|
||||
: RawProps(
|
||||
value.isNull() ? folly::dynamic::object()
|
||||
: jsi::dynamicFromValue(runtime, value)) {}
|
||||
|
||||
/*
|
||||
* Creates an object with given `folly::dynamic` object.
|
||||
* Deprecated.
|
||||
* We need this temporary, only because we have a callsite that does not have
|
||||
* a `jsi::Runtime` behind the data.
|
||||
*/
|
||||
RawProps(const folly::dynamic &dynamic) noexcept
|
||||
:
|
||||
#ifdef ANDROID
|
||||
dynamic_(dynamic),
|
||||
#endif
|
||||
map_((std::unordered_map<std::string, RawValue>)RawValue(dynamic)) {
|
||||
}
|
||||
|
||||
/*
|
||||
* Not moveable.
|
||||
*/
|
||||
RawProps(RawProps &&other) noexcept = delete;
|
||||
RawProps &operator=(RawProps &&other) noexcept = delete;
|
||||
|
||||
/*
|
||||
* Not copyable.
|
||||
*/
|
||||
RawProps(const RawProps &other) noexcept = delete;
|
||||
RawProps &operator=(const RawProps &other) noexcept = delete;
|
||||
|
||||
#ifdef ANDROID
|
||||
/*
|
||||
* Deprecated. Do not use.
|
||||
* The support for explicit conversion to `folly::dynamic` is deprecated and
|
||||
* will be removed as soon Android implementation does not need it.
|
||||
*/
|
||||
explicit operator folly::dynamic() const noexcept {
|
||||
return dynamic_;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Returns a const unowning pointer to `RawValue` of a prop with a given name.
|
||||
* Returns `nullptr`, it a prop with the given name does not exist.
|
||||
*/
|
||||
const RawValue *at(const std::string &name) const noexcept {
|
||||
auto iterator = map_.find(name);
|
||||
if (iterator == map_.end()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return &iterator->second;
|
||||
}
|
||||
|
||||
private:
|
||||
#ifdef ANDROID
|
||||
const folly::dynamic dynamic_;
|
||||
#endif
|
||||
|
||||
const std::unordered_map<std::string, RawValue> map_;
|
||||
};
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
|
@ -0,0 +1,8 @@
|
|||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#include "RawValue.h"
|
|
@ -0,0 +1,266 @@
|
|||
/**
|
||||
* Copyright (c) Facebook, Inc. and its 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 <folly/dynamic.h>
|
||||
#include <jsi/JSIDynamic.h>
|
||||
#include <jsi/jsi.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
class RawProps;
|
||||
|
||||
/*
|
||||
* `RawValue` abstracts some arbitrary complex data structure similar to JSON.
|
||||
* `RawValue` supports explicit conversion to: `bool`, `int`, `int64_t`,
|
||||
* `float`, `double`, `string`, and `vector` & `map` of those types and itself.
|
||||
*
|
||||
* The main intention of the class is to abstract React props parsing infra from
|
||||
* JSI, to enable support for any non-JSI-based data sources. The particular
|
||||
* implementation of the interface is a very slim abstraction around
|
||||
* `folly::dynamic` though.
|
||||
* In the near future, this class will hold a `jsi::Runtime` and `jsi::Value`
|
||||
* pair instead of `folly::dynamic`.
|
||||
*
|
||||
* How `RawValue` is different from `JSI::Value`:
|
||||
* * `RawValue` provides much more scoped API without any references to
|
||||
* JavaScript specifics.
|
||||
* * The API is much more C++-idiomatic and easy to use from C++ code.
|
||||
* * The API prevents access to JSI/JavaScript internals from prop-parsing
|
||||
* code.
|
||||
* * The `RawValue` is not copyable nor thread-safe, which prevent
|
||||
* misuse and accidental performance problems.
|
||||
*
|
||||
* How `RawValue` is different from `folly::dynamic`:
|
||||
* * `RawValue` is a lazy data structure, it does not copy all content inside,
|
||||
* it provides efficient SAX-like access to the data.
|
||||
* * `RawValue` has more static and C++-idiomatic API.
|
||||
* * The `RawValue` is not copyable nor thread-safe, which prevent
|
||||
* misuse and accidental performance problems.
|
||||
*/
|
||||
class RawValue {
|
||||
public:
|
||||
/*
|
||||
* Constructors.
|
||||
*/
|
||||
RawValue() noexcept : dynamic_(nullptr){};
|
||||
|
||||
RawValue(RawValue &&other) noexcept : dynamic_(std::move(other.dynamic_)) {}
|
||||
|
||||
RawValue &operator=(RawValue &&other) noexcept {
|
||||
if (this != &other) {
|
||||
dynamic_ = std::move(other.dynamic_);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
friend RawProps;
|
||||
|
||||
/*
|
||||
* Arbitrary constructors are private only for RawProps and internal usage.
|
||||
*/
|
||||
RawValue(const folly::dynamic &dynamic) noexcept : dynamic_(dynamic){};
|
||||
|
||||
RawValue(folly::dynamic &&dynamic) noexcept : dynamic_(std::move(dynamic)){};
|
||||
|
||||
/*
|
||||
* Copy constructor and copy assignment operator are private and only for
|
||||
* internal use. Basically, it's implementation details. Other particular
|
||||
* implementations of the `RawValue` interface may not have them.
|
||||
*/
|
||||
RawValue(RawValue const &other) noexcept : dynamic_(other.dynamic_) {}
|
||||
|
||||
RawValue &operator=(const RawValue &other) noexcept {
|
||||
if (this != &other) {
|
||||
dynamic_ = other.dynamic_;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
public:
|
||||
/*
|
||||
* Casts the value to a specified type.
|
||||
*/
|
||||
template <typename T>
|
||||
explicit operator T() const noexcept {
|
||||
return castValue(dynamic_, (T *)nullptr);
|
||||
}
|
||||
|
||||
inline explicit operator folly::dynamic() const {
|
||||
return dynamic_;
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks if the stored value has specified type.
|
||||
*/
|
||||
template <typename T>
|
||||
bool hasType() const noexcept {
|
||||
return checkValueType(dynamic_, (T *)nullptr);
|
||||
};
|
||||
|
||||
/*
|
||||
* Checks if the stored value is *not* `null`.
|
||||
*/
|
||||
bool hasValue() const noexcept {
|
||||
return !dynamic_.isNull();
|
||||
}
|
||||
|
||||
private:
|
||||
folly::dynamic dynamic_;
|
||||
|
||||
static bool checkValueType(
|
||||
const folly::dynamic &dynamic,
|
||||
RawValue *type) noexcept {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool checkValueType(
|
||||
const folly::dynamic &dynamic,
|
||||
bool *type) noexcept {
|
||||
return dynamic.isBool();
|
||||
}
|
||||
|
||||
static bool checkValueType(
|
||||
const folly::dynamic &dynamic,
|
||||
int *type) noexcept {
|
||||
return dynamic.isNumber();
|
||||
}
|
||||
|
||||
static bool checkValueType(
|
||||
const folly::dynamic &dynamic,
|
||||
int64_t *type) noexcept {
|
||||
return dynamic.isNumber();
|
||||
}
|
||||
|
||||
static bool checkValueType(
|
||||
const folly::dynamic &dynamic,
|
||||
float *type) noexcept {
|
||||
return dynamic.isNumber();
|
||||
}
|
||||
|
||||
static bool checkValueType(
|
||||
const folly::dynamic &dynamic,
|
||||
double *type) noexcept {
|
||||
return dynamic.isNumber();
|
||||
}
|
||||
|
||||
static bool checkValueType(
|
||||
const folly::dynamic &dynamic,
|
||||
std::string *type) noexcept {
|
||||
return dynamic.isString();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static bool checkValueType(
|
||||
const folly::dynamic &dynamic,
|
||||
std::vector<T> *type) noexcept {
|
||||
if (!dynamic.isArray()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const auto &item : dynamic) {
|
||||
if (!checkValueType(item, (T *)nullptr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Note: We test only one element.
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static bool checkValueType(
|
||||
const folly::dynamic &dynamic,
|
||||
std::unordered_map<std::string, T> *type) noexcept {
|
||||
if (!dynamic.isObject()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const auto &item : dynamic.items()) {
|
||||
assert(item.first.isString());
|
||||
if (!checkValueType(item.second, (T *)nullptr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Note: We test only one element.
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Casts
|
||||
static RawValue castValue(
|
||||
const folly::dynamic &dynamic,
|
||||
RawValue *type) noexcept {
|
||||
return RawValue(dynamic);
|
||||
}
|
||||
|
||||
static bool castValue(const folly::dynamic &dynamic, bool *type) noexcept {
|
||||
return dynamic.getBool();
|
||||
}
|
||||
|
||||
static int castValue(const folly::dynamic &dynamic, int *type) noexcept {
|
||||
return dynamic.asInt();
|
||||
}
|
||||
|
||||
static int64_t castValue(
|
||||
const folly::dynamic &dynamic,
|
||||
int64_t *type) noexcept {
|
||||
return dynamic.asInt();
|
||||
}
|
||||
|
||||
static float castValue(const folly::dynamic &dynamic, float *type) noexcept {
|
||||
return dynamic.asDouble();
|
||||
}
|
||||
|
||||
static double castValue(
|
||||
const folly::dynamic &dynamic,
|
||||
double *type) noexcept {
|
||||
return dynamic.asDouble();
|
||||
}
|
||||
|
||||
static std::string castValue(
|
||||
const folly::dynamic &dynamic,
|
||||
std::string *type) noexcept {
|
||||
return dynamic.getString();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static std::vector<T> castValue(
|
||||
const folly::dynamic &dynamic,
|
||||
std::vector<T> *type) noexcept {
|
||||
assert(dynamic.isArray());
|
||||
auto result = std::vector<T>{};
|
||||
result.reserve(dynamic.size());
|
||||
for (const auto &item : dynamic) {
|
||||
result.push_back(castValue(item, (T *)nullptr));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static std::unordered_map<std::string, T> castValue(
|
||||
const folly::dynamic &dynamic,
|
||||
std::unordered_map<std::string, T> *type) noexcept {
|
||||
assert(dynamic.isObject());
|
||||
auto result = std::unordered_map<std::string, T>{};
|
||||
for (const auto &item : dynamic.items()) {
|
||||
assert(item.first.isString());
|
||||
result[item.first.getString()] = castValue(item.second, (T *)nullptr);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
|
@ -7,12 +7,13 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <folly/dynamic.h>
|
||||
#include <react/core/RawProps.h>
|
||||
#include <react/core/RawValue.h>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <folly/dynamic.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
|
@ -28,13 +29,6 @@ using InstanceHandle = struct InstanceHandleDummyStruct {
|
|||
*/
|
||||
using SurfaceId = int32_t;
|
||||
|
||||
/*
|
||||
* `RawProps` represents untyped map with props comes from JavaScript side.
|
||||
*/
|
||||
// TODO(T26954420): Use iterator as underlying type for RawProps.
|
||||
using RawProps = std::unordered_map<std::string, folly::dynamic>;
|
||||
using SharedRawProps = std::shared_ptr<const RawProps>;
|
||||
|
||||
/*
|
||||
* Universal component handle which allows to refer to `ComponentDescriptor`s
|
||||
* in maps efficiently.
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include <folly/Optional.h>
|
||||
#include <folly/dynamic.h>
|
||||
#include <react/core/RawProps.h>
|
||||
#include <react/graphics/Color.h>
|
||||
#include <react/graphics/Geometry.h>
|
||||
#include <react/graphics/conversions.h>
|
||||
|
@ -16,90 +17,78 @@
|
|||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
inline void fromDynamic(const folly::dynamic &value, bool &result) {
|
||||
result = value.getBool();
|
||||
}
|
||||
inline void fromDynamic(const folly::dynamic &value, int &result) {
|
||||
// All numbers from JS are treated as double, and JS cannot represent int64 in
|
||||
// practice. So this always converts the value to int64 instead.
|
||||
result = value.asInt();
|
||||
}
|
||||
inline void fromDynamic(const folly::dynamic &value, float &result) {
|
||||
result = (float)value.asDouble();
|
||||
}
|
||||
inline void fromDynamic(const folly::dynamic &value, double &result) {
|
||||
result = value.asDouble();
|
||||
}
|
||||
inline void fromDynamic(const folly::dynamic &value, std::string &result) {
|
||||
result = value.getString();
|
||||
}
|
||||
inline void fromDynamic(const folly::dynamic &value, folly::dynamic &result) {
|
||||
result = value;
|
||||
template <typename T>
|
||||
void fromRawValue(const RawValue &rawValue, T &result) {
|
||||
result = (T)rawValue;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void fromDynamic(const folly::dynamic &value, std::vector<T> &result) {
|
||||
if (!value.isArray()) {
|
||||
T itemResult;
|
||||
fromDynamic(value, itemResult);
|
||||
result = {itemResult};
|
||||
void fromRawValue(const RawValue &rawValue, std::vector<T> &result) {
|
||||
if (rawValue.hasType<std::vector<RawValue>>()) {
|
||||
auto items = (std::vector<RawValue>)rawValue;
|
||||
auto length = items.size();
|
||||
result.clear();
|
||||
result.reserve(length);
|
||||
for (int i = 0; i < length; i++) {
|
||||
T itemResult;
|
||||
fromRawValue(items.at(i), itemResult);
|
||||
result.push_back(itemResult);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// The case where `value` is not an array.
|
||||
result.clear();
|
||||
result.reserve(1);
|
||||
T itemResult;
|
||||
for (auto &itemValue : value) {
|
||||
fromDynamic(itemValue, itemResult);
|
||||
result.push_back(itemResult);
|
||||
}
|
||||
fromRawValue(rawValue, itemResult);
|
||||
result.push_back(itemResult);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T convertRawProp(
|
||||
T convertRawProp(
|
||||
const RawProps &rawProps,
|
||||
const std::string &name,
|
||||
const T &sourceValue,
|
||||
const T &defaultValue = T()) {
|
||||
const auto &iterator = rawProps.find(name);
|
||||
if (iterator == rawProps.end()) {
|
||||
const auto rawValue = rawProps.at(name);
|
||||
|
||||
if (!rawValue) {
|
||||
return sourceValue;
|
||||
}
|
||||
|
||||
const auto &value = iterator->second;
|
||||
|
||||
// Special case: `null` always means `the prop was removed, use default
|
||||
// value`.
|
||||
if (value.isNull()) {
|
||||
if (!rawValue->hasValue()) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
T result;
|
||||
fromDynamic(value, result);
|
||||
fromRawValue(*rawValue, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline static folly::Optional<T> convertRawProp(
|
||||
static folly::Optional<T> convertRawProp(
|
||||
const RawProps &rawProps,
|
||||
const std::string &name,
|
||||
const folly::Optional<T> &sourceValue,
|
||||
const folly::Optional<T> &defaultValue = {}) {
|
||||
const auto &iterator = rawProps.find(name);
|
||||
if (iterator == rawProps.end()) {
|
||||
const auto rawValue = rawProps.at(name);
|
||||
|
||||
if (!rawValue) {
|
||||
return sourceValue;
|
||||
}
|
||||
|
||||
const auto &value = iterator->second;
|
||||
|
||||
// Special case: `null` always means `the prop was removed, use default
|
||||
// value`.
|
||||
if (value.isNull()) {
|
||||
if (!rawValue->hasValue()) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
T result;
|
||||
fromDynamic(value, result);
|
||||
return result;
|
||||
fromRawValue(*rawValue, result);
|
||||
return folly::Optional<T>{result};
|
||||
}
|
||||
|
||||
} // namespace react
|
||||
|
|
|
@ -17,7 +17,7 @@ Props::Props(const Props &sourceProps, const RawProps &rawProps)
|
|||
: nativeId(convertRawProp(rawProps, "nativeID", sourceProps.nativeId))
|
||||
#ifdef ANDROID
|
||||
,
|
||||
rawProps(rawProps)
|
||||
rawProps((folly::dynamic)rawProps)
|
||||
#endif
|
||||
{};
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ class Props : public virtual Sealable, public virtual DebugStringConvertible {
|
|||
const std::string nativeId;
|
||||
|
||||
#ifdef ANDROID
|
||||
const RawProps rawProps;
|
||||
const folly::dynamic rawProps = folly::dynamic::object();
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
|
@ -20,8 +20,7 @@ TEST(ComponentDescriptorTest, createShadowNode) {
|
|||
descriptor->getComponentName().c_str(), TestShadowNode::Name().c_str());
|
||||
ASSERT_STREQ(descriptor->getComponentName().c_str(), "Test");
|
||||
|
||||
RawProps raw;
|
||||
raw["nativeID"] = "abc";
|
||||
const auto &raw = RawProps(folly::dynamic::object("nativeID", "abc"));
|
||||
SharedProps props = descriptor->cloneProps(nullptr, raw);
|
||||
SharedShadowNode node = descriptor->createShadowNode(
|
||||
ShadowNodeFragment{.tag = 9,
|
||||
|
@ -42,8 +41,7 @@ TEST(ComponentDescriptorTest, cloneShadowNode) {
|
|||
SharedComponentDescriptor descriptor =
|
||||
std::make_shared<TestComponentDescriptor>(nullptr);
|
||||
|
||||
RawProps raw;
|
||||
raw["nativeID"] = "abc";
|
||||
const auto &raw = RawProps(folly::dynamic::object("nativeID", "abc"));
|
||||
SharedProps props = descriptor->cloneProps(nullptr, raw);
|
||||
SharedShadowNode node = descriptor->createShadowNode(
|
||||
ShadowNodeFragment{.tag = 9,
|
||||
|
@ -62,8 +60,7 @@ TEST(ComponentDescriptorTest, appendChild) {
|
|||
SharedComponentDescriptor descriptor =
|
||||
std::make_shared<TestComponentDescriptor>(nullptr);
|
||||
|
||||
RawProps raw;
|
||||
raw["nativeID"] = "abc";
|
||||
const auto &raw = RawProps(folly::dynamic::object("nativeID", "abc"));
|
||||
SharedProps props = descriptor->cloneProps(nullptr, raw);
|
||||
SharedShadowNode node1 = descriptor->createShadowNode(
|
||||
ShadowNodeFragment{.tag = 1,
|
||||
|
|
|
@ -16,8 +16,7 @@
|
|||
using namespace facebook::react;
|
||||
|
||||
TEST(ShadowNodeTest, handleProps) {
|
||||
RawProps raw;
|
||||
raw["nativeID"] = "abc";
|
||||
const auto &raw = RawProps(folly::dynamic::object("nativeID", "abc"));
|
||||
|
||||
auto props = std::make_shared<Props>(Props(), raw);
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <react/core/ConcreteComponentDescriptor.h>
|
||||
#include <react/core/ConcreteShadowNode.h>
|
||||
#include <react/core/LocalData.h>
|
||||
#include <react/core/RawProps.h>
|
||||
#include <react/core/ShadowNode.h>
|
||||
|
||||
using namespace facebook::react;
|
||||
|
@ -41,7 +42,8 @@ static const char TestComponentName[] = "Test";
|
|||
class TestProps : public Props {
|
||||
public:
|
||||
using Props::Props;
|
||||
TestProps() : Props(Props(), {{"nativeID", "testNativeID"}}) {}
|
||||
TestProps()
|
||||
: Props(Props(), RawProps(folly::dynamic::object("nativeID", "testNativeID"))) {}
|
||||
};
|
||||
using SharedTestProps = std::shared_ptr<const TestProps>;
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <folly/dynamic.h>
|
||||
#include <react/core/RawProps.h>
|
||||
#include <react/graphics/Color.h>
|
||||
#include <react/graphics/Geometry.h>
|
||||
|
||||
|
@ -16,30 +17,30 @@ namespace react {
|
|||
|
||||
#pragma mark - Color
|
||||
|
||||
inline void fromDynamic(const folly::dynamic &value, SharedColor &result) {
|
||||
inline void fromRawValue(const RawValue &value, SharedColor &result) {
|
||||
float red;
|
||||
float green;
|
||||
float blue;
|
||||
float alpha;
|
||||
|
||||
if (value.isNumber()) {
|
||||
auto argb = value.asInt();
|
||||
if (value.hasType<int>()) {
|
||||
auto argb = (int64_t)value;
|
||||
auto ratio = 256.f;
|
||||
alpha = ((argb >> 24) & 0xFF) / ratio;
|
||||
red = ((argb >> 16) & 0xFF) / ratio;
|
||||
green = ((argb >> 8) & 0xFF) / ratio;
|
||||
blue = (argb & 0xFF) / ratio;
|
||||
} else if (value.isArray()) {
|
||||
auto size = value.size();
|
||||
assert(size == 3 || size == 4);
|
||||
red = value[0].asDouble();
|
||||
green = value[1].asDouble();
|
||||
blue = value[2].asDouble();
|
||||
alpha = size == 4 ? value[3].asDouble() : 1.0;
|
||||
} else if (value.hasType<std::vector<float>>()) {
|
||||
auto items = (std::vector<float>)value;
|
||||
auto length = items.size();
|
||||
assert(length == 3 || length == 4);
|
||||
red = items.at(0);
|
||||
green = items.at(1);
|
||||
blue = items.at(2);
|
||||
alpha = length == 4 ? items.at(3) : 1.0;
|
||||
} else {
|
||||
abort();
|
||||
}
|
||||
|
||||
result = colorFromComponents({red, green, blue, alpha});
|
||||
}
|
||||
|
||||
|
@ -68,74 +69,84 @@ inline std::string toString(const SharedColor &value) {
|
|||
|
||||
#pragma mark - Geometry
|
||||
|
||||
inline void fromDynamic(const folly::dynamic &value, Point &result) {
|
||||
if (value.isObject()) {
|
||||
result = Point{(Float)value["x"].asDouble(), (Float)value["y"].asDouble()};
|
||||
inline void fromRawValue(const RawValue &value, Point &result) {
|
||||
if (value.hasType<std::unordered_map<std::string, Float>>()) {
|
||||
auto map = (std::unordered_map<std::string, Float>)value;
|
||||
result = {map.at("x"), map.at("y")};
|
||||
return;
|
||||
}
|
||||
if (value.isArray()) {
|
||||
result = Point{(Float)value[0].asDouble(), (Float)value[1].asDouble()};
|
||||
|
||||
if (value.hasType<std::vector<Float>>()) {
|
||||
auto array = (std::vector<Float>)value;
|
||||
assert(array.size() == 2);
|
||||
result = {array.at(0), array.at(1)};
|
||||
return;
|
||||
}
|
||||
|
||||
abort();
|
||||
}
|
||||
|
||||
inline void fromDynamic(const folly::dynamic &value, Size &result) {
|
||||
if (value.isObject()) {
|
||||
result = Size{(Float)value["width"].asDouble(),
|
||||
(Float)value["height"].asDouble()};
|
||||
inline void fromRawValue(const RawValue &value, Size &result) {
|
||||
if (value.hasType<std::unordered_map<std::string, Float>>()) {
|
||||
auto map = (std::unordered_map<std::string, Float>)value;
|
||||
result = {map.at("width"), map.at("height")};
|
||||
return;
|
||||
}
|
||||
if (value.isArray()) {
|
||||
result = Size{(Float)value[0].asDouble(), (Float)value[1].asDouble()};
|
||||
|
||||
if (value.hasType<std::vector<Float>>()) {
|
||||
auto array = (std::vector<Float>)value;
|
||||
assert(array.size() == 2);
|
||||
result = {array.at(0), array.at(1)};
|
||||
return;
|
||||
}
|
||||
|
||||
abort();
|
||||
}
|
||||
|
||||
inline void fromDynamic(const folly::dynamic &value, EdgeInsets &result) {
|
||||
if (value.isNumber()) {
|
||||
const Float number = value.asDouble();
|
||||
result = EdgeInsets{number, number, number, number};
|
||||
inline void fromRawValue(const RawValue &value, EdgeInsets &result) {
|
||||
if (value.hasType<Float>()) {
|
||||
auto number = (Float)value;
|
||||
result = {number, number, number, number};
|
||||
}
|
||||
|
||||
if (value.hasType<std::unordered_map<std::string, Float>>()) {
|
||||
auto map = (std::unordered_map<std::string, Float>)value;
|
||||
result = {map.at("top"), map.at("left"), map.at("bottom"), map.at("right")};
|
||||
return;
|
||||
}
|
||||
if (value.isObject()) {
|
||||
result = EdgeInsets{(Float)value["top"].asDouble(),
|
||||
(Float)value["left"].asDouble(),
|
||||
(Float)value["bottom"].asDouble(),
|
||||
(Float)value["right"].asDouble()};
|
||||
return;
|
||||
}
|
||||
if (value.isArray()) {
|
||||
result = EdgeInsets{(Float)value[0].asDouble(),
|
||||
(Float)value[1].asDouble(),
|
||||
(Float)value[2].asDouble(),
|
||||
(Float)value[3].asDouble()};
|
||||
|
||||
if (value.hasType<std::vector<Float>>()) {
|
||||
auto array = (std::vector<Float>)value;
|
||||
assert(array.size() == 4);
|
||||
result = {array.at(0), array.at(1), array.at(2), array.at(3)};
|
||||
return;
|
||||
}
|
||||
|
||||
abort();
|
||||
}
|
||||
|
||||
inline void fromDynamic(const folly::dynamic &value, CornerInsets &result) {
|
||||
if (value.isNumber()) {
|
||||
const Float number = value.asDouble();
|
||||
result = CornerInsets{number, number, number, number};
|
||||
inline void fromRawValue(const RawValue &value, CornerInsets &result) {
|
||||
if (value.hasType<Float>()) {
|
||||
auto number = (Float)value;
|
||||
result = {number, number, number, number};
|
||||
}
|
||||
|
||||
if (value.hasType<std::unordered_map<std::string, Float>>()) {
|
||||
auto map = (std::unordered_map<std::string, Float>)value;
|
||||
result = {map.at("topLeft"),
|
||||
map.at("topRight"),
|
||||
map.at("bottomLeft"),
|
||||
map.at("bottomRight")};
|
||||
return;
|
||||
}
|
||||
if (value.isObject()) {
|
||||
result = CornerInsets{(Float)value["topLeft"].asDouble(),
|
||||
(Float)value["topRight"].asDouble(),
|
||||
(Float)value["bottomLeft"].asDouble(),
|
||||
(Float)value["bottomRight"].asDouble()};
|
||||
return;
|
||||
}
|
||||
if (value.isArray()) {
|
||||
result = CornerInsets{(Float)value[0].asDouble(),
|
||||
(Float)value[1].asDouble(),
|
||||
(Float)value[2].asDouble(),
|
||||
(Float)value[3].asDouble()};
|
||||
|
||||
if (value.hasType<std::vector<Float>>()) {
|
||||
auto array = (std::vector<Float>)value;
|
||||
assert(array.size() == 4);
|
||||
result = {array.at(0), array.at(1), array.at(2), array.at(3)};
|
||||
return;
|
||||
}
|
||||
|
||||
abort();
|
||||
}
|
||||
|
||||
|
|
|
@ -112,14 +112,13 @@ SharedShadowNode ComponentDescriptorRegistry::createNode(
|
|||
const SharedEventTarget &eventTarget) const {
|
||||
ComponentName componentName = componentNameByReactViewName(viewName);
|
||||
const SharedComponentDescriptor &componentDescriptor = (*this)[componentName];
|
||||
RawProps rawProps = rawPropsFromDynamic(props);
|
||||
|
||||
SharedShadowNode shadowNode = componentDescriptor->createShadowNode(
|
||||
{.tag = tag,
|
||||
.rootTag = rootTag,
|
||||
.eventEmitter =
|
||||
componentDescriptor->createEventEmitter(std::move(eventTarget), tag),
|
||||
.props = componentDescriptor->cloneProps(nullptr, rawProps)});
|
||||
.props = componentDescriptor->cloneProps(nullptr, RawProps(props))});
|
||||
return shadowNode;
|
||||
}
|
||||
|
||||
|
|
|
@ -33,17 +33,16 @@ SharedShadowNode UIManager::createNode(
|
|||
SharedShadowNode UIManager::cloneNode(
|
||||
const SharedShadowNode &shadowNode,
|
||||
const SharedShadowNodeSharedList &children,
|
||||
const folly::Optional<RawProps> &rawProps) const {
|
||||
const RawProps *rawProps) const {
|
||||
auto &componentDescriptor =
|
||||
componentDescriptorRegistry_->at(shadowNode->getComponentHandle());
|
||||
|
||||
auto clonedShadowNode = componentDescriptor.cloneShadowNode(
|
||||
*shadowNode,
|
||||
{
|
||||
.props = rawProps.has_value()
|
||||
? componentDescriptor.cloneProps(
|
||||
shadowNode->getProps(), rawProps.value())
|
||||
: ShadowNodeFragment::nullSharedProps(),
|
||||
.props = rawProps ? componentDescriptor.cloneProps(
|
||||
shadowNode->getProps(), *rawProps)
|
||||
: ShadowNodeFragment::nullSharedProps(),
|
||||
.children = children,
|
||||
});
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ class UIManager {
|
|||
SharedShadowNode cloneNode(
|
||||
const SharedShadowNode &shadowNode,
|
||||
const SharedShadowNodeSharedList &children = nullptr,
|
||||
const folly::Optional<RawProps> &rawProps = {}) const;
|
||||
const RawProps *rawProps = nullptr) const;
|
||||
|
||||
void appendChild(
|
||||
const SharedShadowNode &parentShadowNode,
|
||||
|
|
|
@ -120,7 +120,7 @@ jsi::Value UIManagerBinding::get(
|
|||
tagFromValue(runtime, arguments[0]),
|
||||
componentNameFromValue(runtime, arguments[1]),
|
||||
surfaceIdFromValue(runtime, arguments[2]),
|
||||
rawPropsFromValue(runtime, arguments[3]),
|
||||
RawProps(runtime, arguments[3]),
|
||||
eventTargetFromValue(runtime, arguments[4], arguments[0])));
|
||||
});
|
||||
}
|
||||
|
@ -172,12 +172,13 @@ jsi::Value UIManagerBinding::get(
|
|||
const jsi::Value &thisValue,
|
||||
const jsi::Value *arguments,
|
||||
size_t count) -> jsi::Value {
|
||||
const auto &rawProps = RawProps(runtime, arguments[1]);
|
||||
return valueFromShadowNode(
|
||||
runtime,
|
||||
uiManager.cloneNode(
|
||||
shadowNodeFromValue(runtime, arguments[0]),
|
||||
nullptr,
|
||||
rawPropsFromValue(runtime, arguments[1])));
|
||||
&rawProps));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -192,12 +193,13 @@ jsi::Value UIManagerBinding::get(
|
|||
const jsi::Value &thisValue,
|
||||
const jsi::Value *arguments,
|
||||
size_t count) -> jsi::Value {
|
||||
const auto &rawProps = RawProps(runtime, arguments[1]);
|
||||
return valueFromShadowNode(
|
||||
runtime,
|
||||
uiManager.cloneNode(
|
||||
shadowNodeFromValue(runtime, arguments[0]),
|
||||
ShadowNode::emptySharedShadowNodeSharedList(),
|
||||
rawPropsFromValue(runtime, arguments[1])));
|
||||
&rawProps));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -319,7 +321,7 @@ jsi::Value UIManagerBinding::get(
|
|||
size_t count) -> jsi::Value {
|
||||
uiManager.setNativeProps(
|
||||
shadowNodeFromValue(runtime, arguments[0]),
|
||||
rawPropsFromValue(runtime, arguments[1]));
|
||||
RawProps(runtime, arguments[1]));
|
||||
|
||||
return jsi::Value::undefined();
|
||||
});
|
||||
|
|
|
@ -13,23 +13,6 @@ namespace react {
|
|||
using RuntimeExecutor = std::function<void(
|
||||
std::function<void(facebook::jsi::Runtime &runtime)> &&callback)>;
|
||||
|
||||
inline RawProps rawPropsFromDynamic(const folly::dynamic object) noexcept {
|
||||
RawProps result;
|
||||
|
||||
if (object.isNull()) {
|
||||
return result;
|
||||
}
|
||||
|
||||
assert(object.isObject());
|
||||
|
||||
for (const auto &pair : object.items()) {
|
||||
assert(pair.first.isString());
|
||||
result[pair.first.asString()] = pair.second;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
struct EventHandlerWrapper : public EventHandler {
|
||||
EventHandlerWrapper(jsi::Function eventHandler)
|
||||
: callback(std::move(eventHandler)) {}
|
||||
|
@ -81,13 +64,6 @@ inline static jsi::Value valueFromShadowNodeList(
|
|||
runtime, std::make_unique<ShadowNodeListWrapper>(shadowNodeList));
|
||||
}
|
||||
|
||||
inline static RawProps rawPropsFromValue(
|
||||
jsi::Runtime &runtime,
|
||||
const jsi::Value &value) {
|
||||
return rawPropsFromDynamic(folly::dynamic{
|
||||
value.isNull() ? nullptr : jsi::dynamicFromValue(runtime, value)});
|
||||
}
|
||||
|
||||
inline static SharedEventTarget eventTargetFromValue(
|
||||
jsi::Runtime &runtime,
|
||||
const jsi::Value &eventTargetValue,
|
||||
|
|
|
@ -56,8 +56,8 @@ class ::_CLASSNAME_:: final::_EXTEND_CLASSES_:: {
|
|||
const enumTemplate = `
|
||||
enum class ::_ENUM_NAME_:: { ::_VALUES_:: };
|
||||
|
||||
static inline void fromDynamic(const folly::dynamic &value, ::_ENUM_NAME_:: &result) {
|
||||
auto string = value.asString();
|
||||
static inline void fromRawValue(const RawValue &value, ::_ENUM_NAME_:: &result) {
|
||||
auto string = (std::string)value;
|
||||
::_FROM_CASES_::
|
||||
abort();
|
||||
}
|
||||
|
|
|
@ -80,8 +80,8 @@ namespace react {
|
|||
|
||||
enum class EnumPropsNativeComponentAlignment { Top, Center, Bottom };
|
||||
|
||||
static inline void fromDynamic(const folly::dynamic &value, EnumPropsNativeComponentAlignment &result) {
|
||||
auto string = value.asString();
|
||||
static inline void fromRawValue(const RawValue &value, EnumPropsNativeComponentAlignment &result) {
|
||||
auto string = (std::string)value;
|
||||
if (string == \\"top\\") { result = EnumPropsNativeComponentAlignment::Top; return; }
|
||||
if (string == \\"center\\") { result = EnumPropsNativeComponentAlignment::Center; return; }
|
||||
if (string == \\"bottom\\") { result = EnumPropsNativeComponentAlignment::Bottom; return; }
|
||||
|
|
Loading…
Reference in New Issue