Stage 1: printing props to screen

Summary:
# LegacyViewManagerInterop is born

LegacyViewManagerInterop is a component that should make it possible for legacy components to work in Fabric, new renderer.
This is just a first stage that prints keys of props to screen together with component name.

Reviewed By: shergin

Differential Revision: D17552827

fbshipit-source-id: c3e062f413727729e6a9b683c60f59f0292cc63b
This commit is contained in:
Samuel Susla
2019-10-03 08:37:28 -07:00
committed by Facebook Github Bot
parent a261e6dfb2
commit 74608ee4ab
15 changed files with 397 additions and 5 deletions
@@ -0,0 +1,23 @@
/**
* 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.
*/
#import <UIKit/UIKit.h>
#import <React/RCTViewComponentView.h>
NS_ASSUME_NONNULL_BEGIN
@interface RCTLegacyViewManagerInteropComponentView : RCTViewComponentView
/**
Returns true for components that are supported by LegacyViewManagerInterop layer, false otherwise.
*/
+ (BOOL)isSupported:(NSString *)componentName;
@end
NS_ASSUME_NONNULL_END
@@ -0,0 +1,82 @@
/**
* 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.
*/
#import "RCTLegacyViewManagerInteropComponentView.h"
#import <react/components/legacyviewmanagerinterop/LegacyViewManagerInteropComponentDescriptor.h>
#import <react/components/legacyviewmanagerinterop/LegacyViewManagerInteropViewProps.h>
using namespace facebook::react;
static std::string propNames(LegacyViewManagerInteropViewProps const &props)
{
std::string propNames;
for (auto const &prop : props.otherProps) {
propNames += prop.first + ", ";
}
if (propNames.size() > 1) {
propNames.resize(propNames.size() - 2);
}
return propNames;
}
@implementation RCTLegacyViewManagerInteropComponentView {
UILabel *_label;
LegacyViewManagerInteropShadowNode::ConcreteState::Shared _state;
}
- (instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
static const auto defaultProps = std::make_shared<const LegacyViewManagerInteropViewProps>();
_props = defaultProps;
CGRect bounds = self.bounds;
_label = [[UILabel alloc] initWithFrame:bounds];
_label.backgroundColor = [UIColor colorWithRed:1.0 green:0.0 blue:0.0 alpha:0.3];
_label.layoutMargins = UIEdgeInsetsMake(12, 12, 12, 12);
_label.lineBreakMode = NSLineBreakByWordWrapping;
_label.numberOfLines = 0;
_label.textAlignment = NSTextAlignmentCenter;
_label.textColor = [UIColor whiteColor];
self.contentView = _label;
}
return self;
}
+ (BOOL)isSupported:(NSString *)componentName
{
static NSSet<NSString *> *supportedComponents = [NSSet new];
return [supportedComponents containsObject:componentName];
}
#pragma mark - RCTComponentViewProtocol
+ (ComponentDescriptorProvider)componentDescriptorProvider
{
return concreteComponentDescriptorProvider<LegacyViewManagerInteropComponentDescriptor>();
}
- (void)updateState:(State::Shared const &)state oldState:(State::Shared const &)oldState
{
_state = std::static_pointer_cast<LegacyViewManagerInteropShadowNode::ConcreteState const>(state);
}
- (void)finalizeUpdates:(RNComponentViewUpdateMask)updateMask
{
[super finalizeUpdates:updateMask];
if (_props && _state) {
const auto &props = *std::static_pointer_cast<const LegacyViewManagerInteropViewProps>(_props);
_label.text = [NSString
stringWithFormat:@"name: %s, props: %s", _state->getData().componentName.c_str(), propNames(props).c_str()];
}
}
@end
@@ -8,6 +8,7 @@
#import "RCTComponentViewFactory.h"
#import <React/RCTAssert.h>
#import <React/RCTConversions.h>
#import <better/map.h>
#import <better/mutex.h>
@@ -17,6 +18,7 @@
#import "RCTARTSurfaceViewComponentView.h"
#import "RCTActivityIndicatorViewComponentView.h"
#import "RCTImageComponentView.h"
#import "RCTLegacyViewManagerInteropComponentView.h"
#import "RCTModalHostViewComponentView.h"
#import "RCTParagraphComponentView.h"
#import "RCTPullToRefreshViewComponentView.h"
@@ -52,6 +54,22 @@ using namespace facebook::react;
[componentViewFactory registerComponentViewClass:[RCTModalHostViewComponentView class]];
[componentViewFactory registerComponentViewClass:[RCTARTSurfaceViewComponentView class]];
auto providerRegistry = &componentViewFactory->_providerRegistry;
providerRegistry->setComponentDescriptorProviderRequest([providerRegistry,
componentViewFactory](ComponentName requestedComponentName) {
if ([RCTLegacyViewManagerInteropComponentView isSupported:RCTNSStringFromString(requestedComponentName)]) {
auto flavor = std::make_shared<std::string const>(requestedComponentName);
auto componentName = ComponentName{flavor->c_str()};
auto componentHandle = reinterpret_cast<ComponentHandle>(componentName);
auto constructor = [RCTLegacyViewManagerInteropComponentView componentDescriptorProvider].constructor;
providerRegistry->add(ComponentDescriptorProvider{componentHandle, componentName, flavor, constructor});
componentViewFactory->_componentViewClasses[componentHandle] = [RCTLegacyViewManagerInteropComponentView class];
}
});
return componentViewFactory;
}
@@ -0,0 +1,59 @@
load("@fbsource//tools/build_defs/apple:flag_defs.bzl", "get_debug_preprocessor_flags")
load(
"//tools/build_defs/oss:rn_defs.bzl",
"APPLE",
"YOGA_CXX_TARGET",
"get_apple_compiler_flags",
"get_apple_inspector_flags",
"react_native_xplat_target",
"rn_xplat_cxx_library",
"subdir_glob",
)
APPLE_COMPILER_FLAGS = get_apple_compiler_flags()
rn_xplat_cxx_library(
name = "legacyviewmanagerinterop",
srcs = glob(
["**/*.cpp"],
),
headers = [],
header_namespace = "",
exported_headers = subdir_glob(
[
("", "*.h"),
],
prefix = "react/components/legacyviewmanagerinterop",
),
compiler_flags = [
"-fexceptions",
"-frtti",
"-std=c++14",
"-Wall",
],
fbobjc_compiler_flags = APPLE_COMPILER_FLAGS,
fbobjc_preprocessor_flags = get_debug_preprocessor_flags() + get_apple_inspector_flags(),
force_static = True,
platforms = (APPLE),
preprocessor_flags = [
"-DLOG_TAG=\"ReactNative\"",
"-DWITH_FBSYSTRACE=1",
],
visibility = ["PUBLIC"],
deps = [
"fbsource//xplat/fbsystrace:fbsystrace",
"fbsource//xplat/folly:headers_only",
"fbsource//xplat/folly:memory",
"fbsource//xplat/folly:molly",
"fbsource//xplat/third-party/glog:glog",
YOGA_CXX_TARGET,
react_native_xplat_target("fabric/debug:debug"),
react_native_xplat_target("fabric/core:core"),
react_native_xplat_target("fabric/components/image:image"),
react_native_xplat_target("fabric/components/view:view"),
react_native_xplat_target("fabric/graphics:graphics"),
react_native_xplat_target("fabric/imagemanager:imagemanager"),
react_native_xplat_target("fabric/uimanager:uimanager"),
"fbsource//xplat/js/react-native-github:generated_components-rncore",
],
)
@@ -0,0 +1,41 @@
/**
* 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 "LegacyViewManagerInteropComponentDescriptor.h"
#include "LegacyViewManagerInteropState.h"
namespace facebook {
namespace react {
ComponentHandle
LegacyViewManagerInteropComponentDescriptor::getComponentHandle() const {
return reinterpret_cast<ComponentHandle>(getComponentName());
}
ComponentName LegacyViewManagerInteropComponentDescriptor::getComponentName()
const {
return std::static_pointer_cast<std::string const>(this->flavor_)->c_str();
}
void LegacyViewManagerInteropComponentDescriptor::adopt(
ShadowNode::Unshared shadowNode) const {
ConcreteComponentDescriptor::adopt(shadowNode);
assert(std::dynamic_pointer_cast<LegacyViewManagerInteropShadowNode>(
shadowNode));
auto legacyViewManagerInteropShadowNode =
std::static_pointer_cast<LegacyViewManagerInteropShadowNode>(shadowNode);
// Storing a component name inside the ShadowNode.
auto state = LegacyViewManagerInteropState{};
state.componentName =
*std::static_pointer_cast<std::string const>(this->flavor_);
legacyViewManagerInteropShadowNode->setStateData(std::move(state));
}
} // namespace react
} // namespace facebook
@@ -0,0 +1,33 @@
/**
* 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 <react/components/legacyviewmanagerinterop/LegacyViewManagerInteropShadowNode.h>
#include <react/core/ConcreteComponentDescriptor.h>
namespace facebook {
namespace react {
class LegacyViewManagerInteropComponentDescriptor final
: public ConcreteComponentDescriptor<LegacyViewManagerInteropShadowNode> {
public:
using ConcreteComponentDescriptor::ConcreteComponentDescriptor;
/*
* Returns `name` and `handle` based on a `flavor`, not on static data from
* `LegacyViewManagerInteropShadowNode`.
*/
ComponentHandle getComponentHandle() const override;
ComponentName getComponentName() const override;
protected:
void adopt(ShadowNode::Unshared shadowNode) const override;
};
} // namespace react
} // namespace facebook
@@ -0,0 +1,15 @@
/**
* 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.
*/
namespace facebook {
namespace react {
extern const char LegacyViewManagerInteropComponentName[] =
"LegacyViewManagerInterop";
} // namespace react
} // namespace facebook
@@ -0,0 +1,26 @@
/**
* 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 <react/components/legacyviewmanagerinterop/LegacyViewManagerInteropState.h>
#include <react/components/legacyviewmanagerinterop/LegacyViewManagerInteropViewProps.h>
#include <react/components/view/ConcreteViewShadowNode.h>
namespace facebook {
namespace react {
extern const char LegacyViewManagerInteropComponentName[];
using LegacyViewManagerInteropShadowNode = ConcreteViewShadowNode<
LegacyViewManagerInteropComponentName,
LegacyViewManagerInteropViewProps,
ViewEventEmitter,
LegacyViewManagerInteropState>;
} // namespace react
} // namespace facebook
@@ -0,0 +1,12 @@
/**
* 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 "LegacyViewManagerInteropState.h"
namespace facebook {
namespace react {} // namespace react
} // namespace facebook
@@ -0,0 +1,24 @@
/**
* 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
#import <string>
namespace facebook {
namespace react {
/*
* State for <LegacyViewManagerInterop> component.
*/
class LegacyViewManagerInteropState final {
public:
std::string componentName;
};
} // namespace react
} // namespace facebook
@@ -0,0 +1,36 @@
/**
* 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 "LegacyViewManagerInteropViewProps.h"
#include <folly/json.h>
#include <react/core/propsConversions.h>
#include <iostream>
namespace facebook {
namespace react {
static std::unordered_map<std::string, folly::dynamic> convertToMap(
RawProps const &rawProps) {
std::unordered_map<std::string, folly::dynamic> map{};
auto const dynamic = (folly::dynamic)rawProps;
if (dynamic.isObject()) {
for (auto const &t : dynamic.items()) {
if (t.first.isString()) {
map[t.first.asString()] = t.second;
}
}
}
return map;
}
LegacyViewManagerInteropViewProps::LegacyViewManagerInteropViewProps(
const LegacyViewManagerInteropViewProps &sourceProps,
const RawProps &rawProps)
: ViewProps(sourceProps, rawProps), otherProps(convertToMap(rawProps)) {}
} // namespace react
} // namespace facebook
@@ -0,0 +1,28 @@
/**
* 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 <folly/dynamic.h>
#include <react/components/view/ViewProps.h>
#include <unordered_map>
namespace facebook {
namespace react {
class LegacyViewManagerInteropViewProps final : public ViewProps {
public:
LegacyViewManagerInteropViewProps() = default;
LegacyViewManagerInteropViewProps(
const LegacyViewManagerInteropViewProps &sourceProps,
const RawProps &rawProps);
#pragma mark - Props
const std::unordered_map<std::string, folly::dynamic> otherProps;
};
} // namespace react
} // namespace facebook
@@ -52,7 +52,6 @@ void RawProps::parse(RawPropsParser const &parser) const noexcept {
parser.preparse(*this);
}
#ifdef ANDROID
/*
* Deprecated. Do not use.
* The support for explicit conversion to `folly::dynamic` is deprecated and
@@ -68,7 +67,6 @@ RawProps::operator folly::dynamic() const noexcept {
return dynamic_;
}
}
#endif
/*
* Returns `true` if the object is empty.
@@ -76,14 +76,12 @@ class RawProps final {
void parse(RawPropsParser const &parser) const noexcept;
#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;
#endif
/*
* Returns `true` if the object is empty.
@@ -8,7 +8,6 @@
#include "ShadowNode.h"
#include <better/small_vector.h>
#include <string>
#include <react/core/ComponentDescriptor.h>
#include <react/core/ShadowNodeFragment.h>