Fabric: Devirtualizing of props parsing infra

Summary:
This diff contains several tight to each other changes (which can/should not be split into several diffs):
 * The props parsing/conversion process was de-virtualized: we don't use virtual `apply` method to parse props anymore. Instead, we use old-fashioned constructors.
 * All fields of Props classes which represent props values were marked as `const` which make impossible to modify them after the objects were created (even if we have non-const value-of/pointer-to the whole Props object). Those fields are also `public` now.
 * All custom handwritten getters were removed (because we don't need them anymore).

So, now we don't need all those custom getters which makes code much more compact, performant and codegen-friendly.

Reviewed By: fkgozali

Differential Revision: D7901245

fbshipit-source-id: 9f4b1fd2da64bf963b63215ed3bd74b9d3c58dd5
This commit is contained in:
Valentin Shergin 2018-05-14 15:43:28 -07:00 committed by Facebook Github Bot
parent 582e1bded3
commit dd3a6eda70
31 changed files with 225 additions and 305 deletions

View File

@ -39,7 +39,7 @@ using namespace facebook::react;
[super updateProps:props oldProps:oldProps];
auto paragraphProps = std::static_pointer_cast<const ParagraphProps>(props);
assert(paragraphProps);
_paragraphAttributes = paragraphProps->getParagraphAttributes();
_paragraphAttributes = paragraphProps->paragraphAttributes;
}
- (void)updateLocalData:(SharedLocalData)localData

View File

@ -24,8 +24,8 @@ using namespace facebook::react;
auto oldViewProps = *std::dynamic_pointer_cast<const ViewProps>(oldProps);
auto newViewProps = *std::dynamic_pointer_cast<const ViewProps>(props);
if (oldViewProps.getBackgroundColor() != newViewProps.getBackgroundColor()) {
self.backgroundColor = [UIColor colorWithCGColor:newViewProps.getBackgroundColor().get()];
if (oldViewProps.backgroundColor != newViewProps.backgroundColor) {
self.backgroundColor = [UIColor colorWithCGColor:newViewProps.backgroundColor.get()];
}
// TODO: Implement all sutable non-layout <View> props.

View File

@ -28,22 +28,12 @@ public:
using SharedConcreteProps = std::shared_ptr<const PropsT>;
using SharedConcreteShadowNode = std::shared_ptr<const ConcreteShadowNode>;
static const SharedConcreteProps Props(const RawProps &rawProps, const SharedProps &baseProps = nullptr) {
if (!baseProps) {
auto props = std::make_shared<PropsT>();
props->apply(rawProps);
return props;
static SharedConcreteProps Props(const RawProps &rawProps, const SharedProps &baseProps = nullptr) {
return std::make_shared<const PropsT>(baseProps ? *std::static_pointer_cast<const PropsT>(baseProps) : PropsT(), rawProps);
}
auto concreteBaseProps = std::dynamic_pointer_cast<const PropsT>(baseProps);
assert(concreteBaseProps);
auto props = std::make_shared<PropsT>(*concreteBaseProps);
props->apply(rawProps);
return props;
}
static const SharedConcreteProps defaultSharedProps() {
static const SharedConcreteProps defaultSharedProps = std::make_shared<PropsT>();
static SharedConcreteProps defaultSharedProps() {
static const SharedConcreteProps defaultSharedProps = std::make_shared<const PropsT>();
return defaultSharedProps;
}

View File

@ -13,15 +13,8 @@
namespace facebook {
namespace react {
void Props::apply(const RawProps &rawProps) {
ensureUnsealed();
applyRawProp(rawProps, "nativeID", nativeId_);
}
const std::string &Props::getNativeId() const {
return nativeId_;
}
Props::Props(const Props &sourceProps, const RawProps &rawProps):
nativeId(convertRawProp(rawProps, "nativeID", sourceProps.nativeId)) {};
} // namespace react
} // namespace facebook

View File

@ -28,12 +28,10 @@ class Props:
public virtual DebugStringConvertible {
public:
virtual void apply(const RawProps &rawProps);
Props() = default;
Props(const Props &sourceProps, const RawProps &rawProps);
const std::string &getNativeId() const;
private:
std::string nativeId_ {""};
const std::string nativeId;
};
} // namespace react

View File

@ -20,33 +20,37 @@ inline int intFromDynamic(const folly::dynamic &value) { return value.getInt();
inline Float floatFromDynamic(const folly::dynamic &value) { return value.getDouble(); }
inline std::string stringFromDynamic(const folly::dynamic &value) { return value.getString(); }
#define APPLY_RAW_PROP_TEMPLATE(type, converter) \
inline static void applyRawProp(const RawProps &rawProps, const std::string &name, type &property) { \
#define CONVERT_RAW_PROP_TEMPLATE(type, converter) \
inline static type convertRawProp(const RawProps &rawProps, const std::string &name, const type &defaultValue) { \
auto &&iterator = rawProps.find(name); \
if (iterator != rawProps.end()) { \
property = converter(iterator->second); \
return converter(iterator->second); \
} else { \
return defaultValue; \
} \
} \
\
inline static void applyRawProp(const RawProps &rawProps, const std::string &name, folly::Optional<type> &property) { \
inline static folly::Optional<type> convertRawProp(const RawProps &rawProps, const std::string &name, const folly::Optional<type> &defaultValue) { \
auto &&iterator = rawProps.find(name); \
if (iterator != rawProps.end()) { \
auto &&value = iterator->second; \
if (value.isNull()) { \
property = {}; \
return {}; \
} else { \
property = converter(value); \
return converter(value); \
} \
} else { \
return defaultValue; \
} \
}
APPLY_RAW_PROP_TEMPLATE(bool, boolFromDynamic)
APPLY_RAW_PROP_TEMPLATE(int, intFromDynamic)
APPLY_RAW_PROP_TEMPLATE(Float, floatFromDynamic)
APPLY_RAW_PROP_TEMPLATE(std::string, stringFromDynamic)
APPLY_RAW_PROP_TEMPLATE(SharedColor, colorFromDynamic)
APPLY_RAW_PROP_TEMPLATE(Point, pointFromDynamic)
APPLY_RAW_PROP_TEMPLATE(Size, sizeFromDynamic)
CONVERT_RAW_PROP_TEMPLATE(bool, boolFromDynamic)
CONVERT_RAW_PROP_TEMPLATE(int, intFromDynamic)
CONVERT_RAW_PROP_TEMPLATE(Float, floatFromDynamic)
CONVERT_RAW_PROP_TEMPLATE(std::string, stringFromDynamic)
CONVERT_RAW_PROP_TEMPLATE(SharedColor, colorFromDynamic)
CONVERT_RAW_PROP_TEMPLATE(Point, pointFromDynamic)
CONVERT_RAW_PROP_TEMPLATE(Size, sizeFromDynamic)
} // namespace react
} // namespace facebook

View File

@ -26,7 +26,7 @@ TEST(ComponentDescriptorTest, createShadowNode) {
ASSERT_STREQ(node->getComponentName().c_str(), "Test");
ASSERT_EQ(node->getTag(), 9);
ASSERT_EQ(node->getRootTag(), 1);
ASSERT_STREQ(node->getProps()->getNativeId().c_str(), "abc");
ASSERT_STREQ(node->getProps()->nativeId.c_str(), "abc");
}
TEST(ComponentDescriptorTest, cloneShadowNode) {
@ -42,7 +42,7 @@ TEST(ComponentDescriptorTest, cloneShadowNode) {
ASSERT_STREQ(cloned->getComponentName().c_str(), "Test");
ASSERT_EQ(cloned->getTag(), 9);
ASSERT_EQ(cloned->getRootTag(), 1);
ASSERT_STREQ(cloned->getProps()->getNativeId().c_str(), "abc");
ASSERT_STREQ(cloned->getProps()->nativeId.c_str(), "abc");
}
TEST(ComponentDescriptorTest, appendChild) {

View File

@ -19,13 +19,12 @@ TEST(ShadowNodeTest, handleProps) {
RawProps raw;
raw["nativeID"] = "abc";
auto props = std::make_shared<Props>();
props->apply(raw);
auto props = std::make_shared<Props>(Props(), raw);
// Props are not sealed after applying raw props.
ASSERT_FALSE(props->getSealed());
ASSERT_STREQ(props->getNativeId().c_str(), "abc");
ASSERT_STREQ(props->nativeId.c_str(), "abc");
}
TEST(ShadowNodeTest, handleShadowNodeCreation) {
@ -41,7 +40,7 @@ TEST(ShadowNodeTest, handleShadowNodeCreation) {
ASSERT_EQ(node->getSourceNode(), nullptr);
ASSERT_EQ(node->getChildren()->size(), 0);
ASSERT_STREQ(node->getProps()->getNativeId().c_str(), "testNativeID");
ASSERT_STREQ(node->getProps()->nativeId.c_str(), "testNativeID");
node->sealRecursive();
ASSERT_TRUE(node->getSealed());

View File

@ -13,6 +13,7 @@
#include <fabric/core/ConcreteShadowNode.h>
#include <fabric/core/LocalData.h>
#include <fabric/core/ShadowNode.h>
#include <folly/dynamic.h>
using namespace facebook::react;
@ -37,11 +38,9 @@ private:
class TestProps : public Props {
public:
TestProps() {
RawProps raw;
raw["nativeID"] = "testNativeID";
apply(raw);
}
using Props::Props;
TestProps():
Props(Props(), {{"nativeID", "testNativeID"}}) {}
};
using SharedTestProps = std::shared_ptr<const TestProps>;

View File

@ -16,52 +16,53 @@
namespace facebook {
namespace react {
void BaseTextProps::apply(const RawProps &rawProps) {
static TextAttributes convertRawProp(const RawProps &rawProps, const TextAttributes defaultTextAttributes) {
TextAttributes textAttributes;
// Color
applyRawProp(rawProps, "color", textAttributes_.foregroundColor);
applyRawProp(rawProps, "backgroundColor", textAttributes_.backgroundColor);
applyRawProp(rawProps, "opacity", textAttributes_.opacity);
textAttributes.foregroundColor = convertRawProp(rawProps, "color", defaultTextAttributes.foregroundColor);
textAttributes.backgroundColor = convertRawProp(rawProps, "backgroundColor", defaultTextAttributes.backgroundColor);
textAttributes.opacity = convertRawProp(rawProps, "opacity", defaultTextAttributes.opacity);
// Font
applyRawProp(rawProps, "fontFamily", textAttributes_.fontFamily);
applyRawProp(rawProps, "fontSize", textAttributes_.fontSize);
applyRawProp(rawProps, "fontSizeMultiplier", textAttributes_.fontSizeMultiplier);
applyRawProp(rawProps, "fontWeight", textAttributes_.fontWeight);
applyRawProp(rawProps, "fontStyle", textAttributes_.fontStyle);
applyRawProp(rawProps, "fontVariant", textAttributes_.fontVariant);
applyRawProp(rawProps, "allowFontScaling", textAttributes_.allowFontScaling);
applyRawProp(rawProps, "letterSpacing", textAttributes_.letterSpacing);
textAttributes.fontFamily = convertRawProp(rawProps, "fontFamily", defaultTextAttributes.fontFamily);
textAttributes.fontSize = convertRawProp(rawProps, "fontSize", defaultTextAttributes.fontSize);
textAttributes.fontSizeMultiplier = convertRawProp(rawProps, "fontSizeMultiplier", defaultTextAttributes.fontSizeMultiplier);
textAttributes.fontWeight = convertRawProp(rawProps, "fontWeight", defaultTextAttributes.fontWeight);
textAttributes.fontStyle = convertRawProp(rawProps, "fontStyle", defaultTextAttributes.fontStyle);
textAttributes.fontVariant = convertRawProp(rawProps, "fontVariant", defaultTextAttributes.fontVariant);
textAttributes.allowFontScaling = convertRawProp(rawProps, "allowFontScaling", defaultTextAttributes.allowFontScaling);
textAttributes.letterSpacing = convertRawProp(rawProps, "letterSpacing", defaultTextAttributes.letterSpacing);
// Paragraph
applyRawProp(rawProps, "lineHeight", textAttributes_.lineHeight);
applyRawProp(rawProps, "alignment", textAttributes_.alignment);
applyRawProp(rawProps, "baseWritingDirection", textAttributes_.baseWritingDirection);
textAttributes.lineHeight = convertRawProp(rawProps, "lineHeight", defaultTextAttributes.lineHeight);
textAttributes.alignment = convertRawProp(rawProps, "alignment", defaultTextAttributes.alignment);
textAttributes.baseWritingDirection = convertRawProp(rawProps, "baseWritingDirection", defaultTextAttributes.baseWritingDirection);
// Decoration
applyRawProp(rawProps, "textDecorationColor", textAttributes_.textDecorationColor);
applyRawProp(rawProps, "textDecorationLineType", textAttributes_.textDecorationLineType);
applyRawProp(rawProps, "textDecorationLineStyle", textAttributes_.textDecorationLineStyle);
applyRawProp(rawProps, "textDecorationLinePattern", textAttributes_.textDecorationLinePattern);
textAttributes.textDecorationColor = convertRawProp(rawProps, "textDecorationColor", defaultTextAttributes.textDecorationColor);
textAttributes.textDecorationLineType = convertRawProp(rawProps, "textDecorationLineType", defaultTextAttributes.textDecorationLineType);
textAttributes.textDecorationLineStyle = convertRawProp(rawProps, "textDecorationLineStyle", defaultTextAttributes.textDecorationLineStyle);
textAttributes.textDecorationLinePattern = convertRawProp(rawProps, "textDecorationLinePattern", defaultTextAttributes.textDecorationLinePattern);
// Shadow
applyRawProp(rawProps, "textShadowOffset", textAttributes_.textShadowOffset);
applyRawProp(rawProps, "textShadowRadius", textAttributes_.textShadowRadius);
applyRawProp(rawProps, "textShadowColor", textAttributes_.textShadowColor);
textAttributes.textShadowOffset = convertRawProp(rawProps, "textShadowOffset", defaultTextAttributes.textShadowOffset);
textAttributes.textShadowRadius = convertRawProp(rawProps, "textShadowRadius", defaultTextAttributes.textShadowRadius);
textAttributes.textShadowColor = convertRawProp(rawProps, "textShadowColor", defaultTextAttributes.textShadowColor);
// Special
applyRawProp(rawProps, "isHighlighted", textAttributes_.isHighlighted);
textAttributes.isHighlighted = convertRawProp(rawProps, "isHighlighted", defaultTextAttributes.isHighlighted);
return textAttributes;
}
#pragma mark - Getters
TextAttributes BaseTextProps::getTextAttributes() const {
return textAttributes_;
}
BaseTextProps::BaseTextProps(const BaseTextProps &sourceProps, const RawProps &rawProps):
textAttributes(convertRawProp(rawProps, sourceProps.textAttributes)) {};
#pragma mark - DebugStringConvertible
SharedDebugStringConvertibleList BaseTextProps::getDebugProps() const {
return textAttributes_.getDebugProps();
return textAttributes.getDebugProps();
}
} // namespace react

View File

@ -22,27 +22,17 @@ namespace react {
class BaseTextProps {
public:
/*
* Same semantic as `Props::apply(...)`.
*/
void apply(const RawProps &rawProps);
BaseTextProps() = default;
BaseTextProps(const BaseTextProps &sourceProps, const RawProps &rawProps);
#pragma mark - Getters
#pragma mark - Props
/*
* Returns all props values as `TextAttributes` object.
*/
TextAttributes getTextAttributes() const;
const TextAttributes textAttributes {};
#pragma mark - DebugStringConvertible (partially)
SharedDebugStringConvertibleList getDebugProps() const;
private:
TextAttributes textAttributes_;
};
} // namespace react
} // namespace facebook

View File

@ -30,7 +30,7 @@ AttributedString BaseTextShadowNode::getAttributedString(
SharedRawTextShadowNode rawTextShadowNode = std::dynamic_pointer_cast<const RawTextShadowNode>(childNode);
if (rawTextShadowNode) {
AttributedString::Fragment fragment;
fragment.string = rawTextShadowNode->getProps()->getText();
fragment.string = rawTextShadowNode->getProps()->text;
fragment.textAttributes = textAttributes;
attributedString.appendFragment(fragment);
continue;
@ -40,7 +40,7 @@ AttributedString BaseTextShadowNode::getAttributedString(
SharedTextShadowNode textShadowNode = std::dynamic_pointer_cast<const TextShadowNode>(childNode);
if (textShadowNode) {
TextAttributes localTextAttributes = textAttributes;
localTextAttributes.apply(textShadowNode->getProps()->getTextAttributes());
localTextAttributes.apply(textShadowNode->getProps()->textAttributes);
attributedString.appendAttributedString(textShadowNode->getAttributedString(localTextAttributes, textShadowNode->getChildren()));
continue;
}

View File

@ -15,38 +15,34 @@
namespace facebook {
namespace react {
void ParagraphProps::apply(const RawProps &rawProps) {
ViewProps::apply(rawProps);
BaseTextProps::apply(rawProps);
static ParagraphAttributes convertRawProp(const RawProps &rawProps, const ParagraphAttributes &defaultParagraphAttributes) {
ParagraphAttributes paragraphAttributes;
// Paragraph Attributes
applyRawProp(rawProps, "numberOfLines", paragraphAttributes_.maximumNumberOfLines);
applyRawProp(rawProps, "ellipsizeMode", paragraphAttributes_.ellipsizeMode);
applyRawProp(rawProps, "adjustsFontSizeToFit", paragraphAttributes_.adjustsFontSizeToFit);
applyRawProp(rawProps, "minimumFontSize", paragraphAttributes_.minimumFontSize);
applyRawProp(rawProps, "maximumFontSize", paragraphAttributes_.maximumFontSize);
paragraphAttributes.maximumNumberOfLines = convertRawProp(rawProps, "numberOfLines", defaultParagraphAttributes.maximumNumberOfLines);
paragraphAttributes.ellipsizeMode = convertRawProp(rawProps, "ellipsizeMode", defaultParagraphAttributes.ellipsizeMode);
paragraphAttributes.adjustsFontSizeToFit = convertRawProp(rawProps, "adjustsFontSizeToFit", defaultParagraphAttributes.adjustsFontSizeToFit);
paragraphAttributes.minimumFontSize = convertRawProp(rawProps, "minimumFontSize", defaultParagraphAttributes.minimumFontSize);
paragraphAttributes.maximumFontSize = convertRawProp(rawProps, "maximumFontSize", defaultParagraphAttributes.maximumFontSize);
// Other Props
applyRawProp(rawProps, "selectable", isSelectable_);
return paragraphAttributes;
}
#pragma mark - Getters
ParagraphAttributes ParagraphProps::getParagraphAttributes() const {
return paragraphAttributes_;
}
bool ParagraphProps::getIsSelectable() const {
return isSelectable_;
}
ParagraphProps::ParagraphProps(const ParagraphProps &sourceProps, const RawProps &rawProps):
ViewProps(sourceProps, rawProps),
BaseTextProps(sourceProps, rawProps),
paragraphAttributes(convertRawProp(rawProps, sourceProps.paragraphAttributes)),
isSelectable(convertRawProp(rawProps, "selectable", sourceProps.isSelectable)) {};
#pragma mark - DebugStringConvertible
SharedDebugStringConvertibleList ParagraphProps::getDebugProps() const {
return
ViewProps::getDebugProps() +
paragraphAttributes_.getDebugProps() +
BaseTextProps::getDebugProps();
BaseTextProps::getDebugProps() +
paragraphAttributes.getDebugProps() +
SharedDebugStringConvertibleList {
debugStringConvertibleItem("isSelectable", isSelectable)
};
}
} // namespace react

View File

@ -32,30 +32,25 @@ class ParagraphProps:
public BaseTextProps {
public:
ParagraphProps() = default;
ParagraphProps(const ParagraphProps &sourceProps, const RawProps &rawProps);
void apply(const RawProps &rawProps) override;
#pragma mark - Getters
#pragma mark - Props
/*
* Returns `ParagraphAttributes` object which has all prop values that affect
* visual representation of the paragraph.
* Contains all prop values that affect visual representation of the paragraph.
*/
ParagraphAttributes getParagraphAttributes() const;
const ParagraphAttributes paragraphAttributes {};
/*
* Defines can the text be selected (and copied) or not.
*/
bool getIsSelectable() const;
const bool isSelectable {false};
#pragma mark - DebugStringConvertible
SharedDebugStringConvertibleList getDebugProps() const override;
private:
ParagraphAttributes paragraphAttributes_ {};
bool isSelectable_ {false};
};
} // namespace react

View File

@ -19,7 +19,7 @@ ComponentName ParagraphShadowNode::getComponentName() const {
}
AttributedString ParagraphShadowNode::getAttributedString() const {
return BaseTextShadowNode::getAttributedString(getProps()->getTextAttributes(), getChildren());
return BaseTextShadowNode::getAttributedString(getProps()->textAttributes, getChildren());
}
void ParagraphShadowNode::setTextLayoutManager(SharedTextLayoutManager textLayoutManager) {
@ -41,7 +41,7 @@ void ParagraphShadowNode::updateLocalData() {
Size ParagraphShadowNode::measure(LayoutConstraints layoutConstraints) const {
return textLayoutManager_->measure(
getAttributedString(),
getProps()->getParagraphAttributes(),
getProps()->paragraphAttributes,
layoutConstraints
);
}

View File

@ -15,15 +15,15 @@
namespace facebook {
namespace react {
APPLY_RAW_PROP_TEMPLATE(EllipsizeMode, ellipsizeModeFromDynamic)
APPLY_RAW_PROP_TEMPLATE(FontWeight, fontWeightFromDynamic)
APPLY_RAW_PROP_TEMPLATE(FontStyle, fontStyleFromDynamic)
APPLY_RAW_PROP_TEMPLATE(FontVariant, fontVariantFromDynamic)
APPLY_RAW_PROP_TEMPLATE(WritingDirection, writingDirectionFromDynamic)
APPLY_RAW_PROP_TEMPLATE(TextAlignment, textAlignmentFromDynamic)
APPLY_RAW_PROP_TEMPLATE(TextDecorationLineType, textDecorationLineTypeFromDynamic)
APPLY_RAW_PROP_TEMPLATE(TextDecorationLineStyle, textDecorationLineStyleFromDynamic)
APPLY_RAW_PROP_TEMPLATE(TextDecorationLinePattern, textDecorationLinePatternFromDynamic)
CONVERT_RAW_PROP_TEMPLATE(EllipsizeMode, ellipsizeModeFromDynamic)
CONVERT_RAW_PROP_TEMPLATE(FontWeight, fontWeightFromDynamic)
CONVERT_RAW_PROP_TEMPLATE(FontStyle, fontStyleFromDynamic)
CONVERT_RAW_PROP_TEMPLATE(FontVariant, fontVariantFromDynamic)
CONVERT_RAW_PROP_TEMPLATE(WritingDirection, writingDirectionFromDynamic)
CONVERT_RAW_PROP_TEMPLATE(TextAlignment, textAlignmentFromDynamic)
CONVERT_RAW_PROP_TEMPLATE(TextDecorationLineType, textDecorationLineTypeFromDynamic)
CONVERT_RAW_PROP_TEMPLATE(TextDecorationLineStyle, textDecorationLineStyleFromDynamic)
CONVERT_RAW_PROP_TEMPLATE(TextDecorationLinePattern, textDecorationLinePatternFromDynamic)
} // namespace react
} // namespace facebook

View File

@ -9,28 +9,21 @@
#include <fabric/core/propsConversions.h>
#include <fabric/debug/DebugStringConvertibleItem.h>
#include <fabric/debug/debugStringConvertibleUtils.h>
namespace facebook {
namespace react {
void RawTextProps::apply(const RawProps &rawProps) {
Props::apply(rawProps);
applyRawProp(rawProps, "text", text_);
}
#pragma mark - Getters
std::string RawTextProps::getText() const {
return text_;
}
RawTextProps::RawTextProps(const RawTextProps &sourceProps, const RawProps &rawProps):
Props(sourceProps, rawProps),
text(convertRawProp(rawProps, "text", sourceProps.text)) {};
#pragma mark - DebugStringConvertible
SharedDebugStringConvertibleList RawTextProps::getDebugProps() const {
SharedDebugStringConvertibleList list = {};
list.push_back(std::make_shared<DebugStringConvertibleItem>("text", text_));
return list;
return {
debugStringConvertibleItem("text", text)
};
}
} // namespace react

View File

@ -24,19 +24,16 @@ class RawTextProps:
public:
void apply(const RawProps &rawProps) override;
RawTextProps() = default;
RawTextProps(const RawTextProps &sourceProps, const RawProps &rawProps);
#pragma mark - Getters
#pragma mark - Props
std::string getText() const;
const std::string text {""};
#pragma mark - DebugStringConvertible
SharedDebugStringConvertibleList getDebugProps() const override;
private:
std::string text_ {""};
};
} // namespace react

View File

@ -16,10 +16,8 @@
namespace facebook {
namespace react {
void TextProps::apply(const RawProps &rawProps) {
Props::apply(rawProps);
BaseTextProps::apply(rawProps);
}
TextProps::TextProps(const TextProps &sourceProps, const RawProps &rawProps):
BaseTextProps::BaseTextProps(sourceProps, rawProps) {};
#pragma mark - DebugStringConvertible

View File

@ -25,7 +25,9 @@ class TextProps:
public BaseTextProps {
public:
void apply(const RawProps &rawProps) override;
TextProps() = default;
TextProps(const TextProps &sourceProps, const RawProps &rawProps);
#pragma mark - DebugStringConvertible

View File

@ -44,9 +44,7 @@ void ShadowTree::constraintLayout(const LayoutConstraints &layoutConstraints, co
UnsharedRootShadowNode ShadowTree::cloneRootShadowNode(const LayoutConstraints &layoutConstraints, const LayoutContext &layoutContext) const {
auto oldRootShadowNode = rootShadowNode_;
auto &&props = std::make_shared<RootProps>(*oldRootShadowNode->getProps());
props->applyLayoutConstraints(layoutConstraints);
props->applyLayoutContext(layoutContext);
auto &&props = std::make_shared<const RootProps>(*oldRootShadowNode->getProps(), layoutConstraints, layoutContext);
auto newRootShadowNode = std::make_shared<RootShadowNode>(oldRootShadowNode, props, nullptr);
return newRootShadowNode;
}

View File

@ -7,59 +7,37 @@
#include "ViewProps.h"
#include <fabric/debug/DebugStringConvertibleItem.h>
#include <fabric/graphics/graphicValuesConversions.h>
#include <fabric/core/propsConversions.h>
#include <fabric/debug/debugStringConvertibleUtils.h>
#include <fabric/graphics/debugStringConvertibleUtils.h>
#include <fabric/graphics/graphicValuesConversions.h>
namespace facebook {
namespace react {
void ViewProps::apply(const RawProps &rawProps) {
Props::apply(rawProps);
YogaStylableProps::apply(rawProps);
ViewProps::ViewProps(const YGStyle &yogaStyle):
YogaStylableProps(yogaStyle) {}
applyRawProp(rawProps, "zIndex", zIndex_);
applyRawProp(rawProps, "opacity", opacity_);
applyRawProp(rawProps, "color", foregroundColor_);
applyRawProp(rawProps, "backgroundColor", backgroundColor_);
}
#pragma mark - Getters
SharedColor ViewProps::getForegroundColor() const {
return foregroundColor_;
}
SharedColor ViewProps::getBackgroundColor() const {
return backgroundColor_;
}
ViewProps::ViewProps(const ViewProps &sourceProps, const RawProps &rawProps):
Props(sourceProps, rawProps),
YogaStylableProps(sourceProps, rawProps),
zIndex(convertRawProp(rawProps, "zIndex", sourceProps.zIndex)),
opacity(convertRawProp(rawProps, "opacity", sourceProps.opacity)),
foregroundColor(convertRawProp(rawProps, "color", sourceProps.foregroundColor)),
backgroundColor(convertRawProp(rawProps, "backgroundColor", sourceProps.backgroundColor)) {};
#pragma mark - DebugStringConvertible
SharedDebugStringConvertibleList ViewProps::getDebugProps() const {
ViewProps defaultProps = {};
SharedDebugStringConvertibleList list = {};
#define VIEW_PROPS_ADD_TO_SET(stringName, propertyName, accessor, convertor) \
if (propertyName != defaultProps.propertyName) { \
list.push_back(std::make_shared<DebugStringConvertibleItem>(#stringName, convertor(propertyName accessor))); \
}
VIEW_PROPS_ADD_TO_SET(zIndex, zIndex_, , std::to_string)
VIEW_PROPS_ADD_TO_SET(opacity, opacity_, , std::to_string)
VIEW_PROPS_ADD_TO_SET(backgroundColor, backgroundColor_, , colorNameFromColor)
VIEW_PROPS_ADD_TO_SET(foregroundColor, foregroundColor_, , colorNameFromColor)
// Accessibility Props
auto accessibilityPropsList = AccessibilityProps::getDebugProps();
std::move(accessibilityPropsList.begin(), accessibilityPropsList.end(), std::back_inserter(list));
// Yoga styles
list.push_back(std::make_shared<DebugStringConvertibleItem>("style", "", YogaStylableProps::getDebugProps()));
return list;
return
AccessibilityProps::getDebugProps() +
YogaStylableProps::getDebugProps() +
SharedDebugStringConvertibleList {
debugStringConvertibleItem("zIndex", zIndex),
debugStringConvertibleItem("opacity", opacity),
debugStringConvertibleItem("foregroundColor", foregroundColor),
debugStringConvertibleItem("backgroundColor", backgroundColor),
};
}
} // namespace react

View File

@ -26,28 +26,26 @@ class ViewProps:
public AccessibilityProps {
public:
void apply(const RawProps &rawProps) override;
#pragma mark - Getters
ViewProps() = default;
ViewProps(const YGStyle &yogaStyle);
ViewProps(const ViewProps &sourceProps, const RawProps &rawProps);
SharedColor getForegroundColor() const;
SharedColor getBackgroundColor() const;
#pragma mark - Props
const int zIndex {0};
const Float opacity {1};
const SharedColor foregroundColor {nullptr};
const SharedColor backgroundColor {nullptr};
const SharedColor shadowColor {nullptr};
const Point shadowOffset {};
#pragma mark - DebugStringConvertible
SharedDebugStringConvertibleList getDebugProps() const override;
private:
int zIndex_ {0};
Float opacity_ {1.0};
SharedColor foregroundColor_ {nullptr};
SharedColor backgroundColor_ {nullptr};
SharedColor shadowColor_ {nullptr};
Point shadowOffset_ {0, 0};
};
} // namespace react
} // namespace facebook

View File

@ -12,20 +12,7 @@
namespace facebook {
namespace react {
void AccessibilityProps::apply(const RawProps &rawProps) {
for (auto const &pair : rawProps) {
auto const &name = pair.first;
auto const &value = pair.second;
#define ACCESSIBILITY_PROPERTY(stringName, variableName, accessor, convertor) \
if (name == #stringName) { \
variableName = convertor(value accessor); \
continue; \
}
ACCESSIBILITY_PROPERTY(accessibilityLabel, accessibilityLabel_, .asString(),)
}
}
AccessibilityProps::AccessibilityProps(const AccessibilityProps &sourceProps, const RawProps &rawProps) {}
} // namespace react
} // namespace facebook

View File

@ -20,22 +20,24 @@ class AccessibilityProps;
typedef std::shared_ptr<const AccessibilityProps> SharedAccessibilityProps;
class AccessibilityProps:
public virtual DebugStringConvertible
{
public virtual DebugStringConvertible {
public:
void apply(const RawProps &rawProps);
protected:
bool accessible_ {true};
std::string accessibilityActions_ {""};
std::string accessibilityLabel_ {""};
AccessibilityTraits accessibilityTraits_ {AccessibilityTraits::None};
bool accessibilityViewIsModal_ {false};
bool accessibilityElementsHidden_ {false};
SharedDirectEventHandler onAccessibilityAction_ {nullptr};
SharedDirectEventHandler onAccessibilityTap_ {nullptr};
SharedDirectEventHandler onMagicTap_ {nullptr};
AccessibilityProps() = default;
AccessibilityProps(const AccessibilityProps &sourceProps, const RawProps &rawProps);
#pragma mark - Props
const bool accessible {true};
const std::string accessibilityActions {""};
const std::string accessibilityLabel {""};
const AccessibilityTraits accessibilityTraits {AccessibilityTraits::None};
const bool accessibilityViewIsModal {false};
const bool accessibilityElementsHidden {false};
const SharedDirectEventHandler onAccessibilityAction {nullptr};
const SharedDirectEventHandler onAccessibilityTap {nullptr};
const SharedDirectEventHandler onMagicTap {nullptr};
};
} // namespace react

View File

@ -7,39 +7,35 @@
#include "RootProps.h"
#include "YogaLayoutableShadowNode.h"
#include "yogaValuesConversions.h"
namespace facebook {
namespace react {
void RootProps::applyLayoutConstraints(const LayoutConstraints &layoutConstraints) {
ensureUnsealed();
layoutConstraints_ = layoutConstraints;
yogaStyle_.minDimensions[YGDimensionWidth] =
static YGStyle yogaStyleFromLayoutConstraints(const LayoutConstraints &layoutConstraints) {
YGStyle yogaStyle;
yogaStyle.minDimensions[YGDimensionWidth] =
yogaStyleValueFromFloat(layoutConstraints.minimumSize.width);
yogaStyle_.minDimensions[YGDimensionHeight] =
yogaStyle.minDimensions[YGDimensionHeight] =
yogaStyleValueFromFloat(layoutConstraints.minimumSize.height);
yogaStyle_.maxDimensions[YGDimensionWidth] =
yogaStyle.maxDimensions[YGDimensionWidth] =
yogaStyleValueFromFloat(layoutConstraints.maximumSize.width);
yogaStyle_.maxDimensions[YGDimensionHeight] =
yogaStyle.maxDimensions[YGDimensionHeight] =
yogaStyleValueFromFloat(layoutConstraints.maximumSize.height);
return yogaStyle;
}
void RootProps::applyLayoutContext(const LayoutContext &layoutContext) {
ensureUnsealed();
layoutContext_ = layoutContext;
}
LayoutConstraints RootProps::getLayoutConstraints() const {
return layoutConstraints_;
}
LayoutContext RootProps::getLayoutContext() const {
return layoutContext_;
}
RootProps::RootProps(
const RootProps &sourceProps,
const LayoutConstraints &layoutConstraints,
const LayoutContext &layoutContext
):
ViewProps(yogaStyleFromLayoutConstraints(layoutConstraints)),
layoutConstraints(layoutConstraints),
layoutContext(layoutContext) {};
} // namespace react
} // namespace facebook

View File

@ -25,19 +25,17 @@ class RootProps final:
public:
/*
* Same semantic as `apply()` but LayoutConstraints & LayoutContext specific.
*/
void applyLayoutConstraints(const LayoutConstraints &layoutConstraints);
void applyLayoutContext(const LayoutContext &layoutContext);
RootProps() = default;
RootProps(
const RootProps &sourceProps,
const LayoutConstraints &layoutConstraints,
const LayoutContext &layoutContext
);
LayoutConstraints getLayoutConstraints() const;
LayoutContext getLayoutContext() const;
#pragma mark - Props
private:
LayoutConstraints layoutConstraints_;
LayoutContext layoutContext_;
const LayoutConstraints layoutConstraints {};
const LayoutContext layoutContext {};
};
} // namespace react

View File

@ -16,7 +16,7 @@ ComponentName RootShadowNode::getComponentName() const {
void RootShadowNode::layout() {
ensureUnsealed();
layout(getProps()->getLayoutContext());
layout(getProps()->layoutContext);
}
} // namespace react

View File

@ -10,10 +10,10 @@
#include <algorithm>
#include <memory>
#include <yoga/Yoga.h>
#include <fabric/core/LayoutContext.h>
#include <fabric/core/LayoutConstraints.h>
#include <fabric/debug/DebugStringConvertibleItem.h>
#include <yoga/Yoga.h>
#include "yogaValuesConversions.h"
@ -40,7 +40,7 @@ YogaLayoutableShadowNode::YogaLayoutableShadowNode(
auto yogaNode = std::make_shared<YGNode>();
yogaNode->setConfig(suitableYogaConfig().get());
yogaNode->setStyle(props->getYogaStyle());
yogaNode->setStyle(props->yogaStyle);
yogaNode->setContext(this);
yogaNode->setDirty(true);
YogaLayoutableShadowNode::setYogaNodeChildrenBasedOnShadowNodeChildren(*yogaNode, children);
@ -59,7 +59,7 @@ YogaLayoutableShadowNode::YogaLayoutableShadowNode(
yogaNode->setDirty(true);
if (props) {
yogaNode->setStyle(props->getYogaStyle());
yogaNode->setStyle(props->yogaStyle);
}
if (children) {

View File

@ -17,18 +17,16 @@
namespace facebook {
namespace react {
const YGStyle &YogaStylableProps::getYogaStyle() const {
return yogaStyle_;
}
static YGStyle convertRawProp(const RawProps &rawProps, const YGStyle &defaultValue) {
YGStyle yogaStyle = defaultValue;
void YogaStylableProps::apply(const RawProps &rawProps) {
for (auto const &pair : rawProps) {
auto const &name = pair.first;
auto const &value = pair.second;
#define YOGA_STYLE_PROPERTY(stringName, yogaName, accessor, convertor) \
if (name == #stringName) { \
yogaStyle_.yogaName = convertor(value accessor); \
yogaStyle.yogaName = convertor(value accessor); \
continue; \
}
@ -97,15 +95,23 @@ void YogaStylableProps::apply(const RawProps &rawProps) {
YOGA_STYLE_OPTIONAL_FLOAT_PROPERTY(aspectRatio)
}
return yogaStyle;
}
YogaStylableProps::YogaStylableProps(const YGStyle &yogaStyle):
yogaStyle(yogaStyle) {}
YogaStylableProps::YogaStylableProps(const YogaStylableProps &sourceProps, const RawProps &rawProps):
yogaStyle(convertRawProp(rawProps, sourceProps.yogaStyle)) {};
#pragma mark - DebugStringConvertible
SharedDebugStringConvertibleList YogaStylableProps::getDebugProps() const {
SharedDebugStringConvertibleList list = {};
YGStyle defaultYogaStyle = YGStyle();
YGStyle currentYogaStyle = yogaStyle_;
YGStyle currentYogaStyle = yogaStyle;
#define YOGA_STYLE_PROPS_ADD_TO_SET(stringName, propertyName, accessor, convertor) \
{ \

View File

@ -23,16 +23,18 @@ class YogaStylableProps:
public virtual DebugStringConvertible {
public:
const YGStyle &getYogaStyle() const;
void apply(const RawProps &rawProps);
YogaStylableProps() = default;
YogaStylableProps(const YGStyle &yogaStyle);
YogaStylableProps(const YogaStylableProps &sourceProps, const RawProps &rawProps);
#pragma mark - Props
const YGStyle yogaStyle {};
#pragma mark - DebugStringConvertible
SharedDebugStringConvertibleList getDebugProps() const override;
protected:
YGStyle yogaStyle_ {};
};
} // namespace react