Skip to content

Commit

Permalink
Hook up fabric view component codegen (#7759)
Browse files Browse the repository at this point in the history
* Hook up view component codegen

* Change files

* Dont use relative imports

* format

* Change files

* Run codegen for all the view components

* fix path

* change to ignore codegen formatting

* x86 build fix

* Add clang-format override file for codegen

* codegen uses LF

* yse yargs required

* tmp

* readd codegen'd files using LF

* Disable sort includes on the codegen files

* updated clang-format file
  • Loading branch information
acoates-ms authored May 12, 2021
1 parent 97aee65 commit 36e48e2
Show file tree
Hide file tree
Showing 27 changed files with 1,452 additions and 30 deletions.
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

# Spec Codegen uses LF
*Spec.g.h eol=lf
/vnext/codegen/** eol=lf

# Force Visual Studio project files (mostly XML) to CRLF
# This helps avoid conflict which occurs when Xmarian/Mac contributors with AutoCRLF=input (or off)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "prerelease",
"comment": "Hook up view component codegen",
"packageName": "@react-native-windows/codegen",
"email": "30809111+acoates-ms@users.noreply.github.com",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "patch",
"comment": "Dont format files in codegen",
"packageName": "@rnw-scripts/format-files",
"email": "30809111+acoates-ms@users.noreply.github.com",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "prerelease",
"comment": "Hook up view component codegen",
"packageName": "react-native-windows",
"email": "30809111+acoates-ms@users.noreply.github.com",
"dependentChangeType": "patch"
}
58 changes: 52 additions & 6 deletions packages/@react-native-windows/codegen/src/Cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ const argv = yargs.options({
describe: 'C++/C# Namespace to put generated native modules in',
default: 'MyNamespace',
},
libraryName: {
type: 'string',
required: true,
describe: 'Used for part of the path generated within the codegen dir',
},
}).argv;

import {SchemaType} from 'react-native-tscodegen';
Expand Down Expand Up @@ -141,7 +146,14 @@ function generate(
): boolean {
schemaValidator.validate(schema);

const generatedFiles = [];
const componentOutputdir = path.join(
outputDirectory,
'react/components',
libraryName,
);

const generatedModuleFiles = [];
const generatedComponentFiles = [];
/*
for (const name of generators) {
for (const generator of GENERATORS[name]) {
Expand All @@ -151,16 +163,50 @@ function generate(
*/

const generateNM2 = createNM2Generator({namespace: argv.namespace});
const generatorPropsH = require('react-native-tscodegen/lib/rncodegen/src/generators/components/GeneratePropsH')
.generate;
const generatorPropsCPP = require('react-native-tscodegen/lib/rncodegen/src/generators/components/GeneratePropsCPP')
.generate;
const generatorShadowNodeH = require('react-native-tscodegen/lib/rncodegen/src/generators/components/GenerateShadowNodeH')
.generate;
const generatorShadowNodeCPP = require('react-native-tscodegen/lib/rncodegen/src/generators/components/GenerateShadowNodeCPP')
.generate;
const generatorComponentDescriptorH = require('react-native-tscodegen/lib/rncodegen/src/generators/components/GenerateComponentDescriptorH')
.generate;
const generatorEventEmitterH = require('react-native-tscodegen/lib/rncodegen/src/generators/components/GenerateEventEmitterH')
.generate;

generatedModuleFiles.push(
...generateNM2(libraryName, schema, moduleSpecName),
);

generatedFiles.push(...generateNM2(libraryName, schema, moduleSpecName));
generatedComponentFiles.push(
...generatorPropsH(libraryName, schema, moduleSpecName),
...generatorPropsCPP(libraryName, schema, moduleSpecName),
...generatorShadowNodeH(libraryName, schema, moduleSpecName),
...generatorShadowNodeCPP(libraryName, schema, moduleSpecName),
...generatorComponentDescriptorH(libraryName, schema, moduleSpecName),
...generatorEventEmitterH(libraryName, schema, moduleSpecName),
);

const filesToUpdate = new Map<string, string>([...generatedFiles]);
const moduleFilesToUpdate = new Map<string, string>([
...generatedModuleFiles,
]);
const componentFilesToUpdate = new Map<string, string>([
...generatedComponentFiles,
]);

if (test === true) {
return checkFilesForChanges(filesToUpdate, outputDirectory);
return (
checkFilesForChanges(moduleFilesToUpdate, outputDirectory) &&
checkFilesForChanges(componentFilesToUpdate, componentOutputdir)
);
}

return writeMapToFiles(filesToUpdate, outputDirectory);
return (
writeMapToFiles(moduleFilesToUpdate, outputDirectory) &&
writeMapToFiles(componentFilesToUpdate, componentOutputdir)
);
}

if ((argv.file && argv.files) || (!argv.file && !argv.files)) {
Expand All @@ -175,7 +221,7 @@ if (argv.file) {
schema = combineSchemas(globby.sync(argv.files as string[]));
}

const libraryName = 'libraryName';
const libraryName = argv.libraryName;
const moduleSpecName = 'moduleSpecName';
const outputDirectory = 'codegen';
generate(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -314,32 +314,30 @@ export function createNM2Generator({namespace}: {namespace: string}) {
const files = new Map<string, string>();

const nativeModules = Object.keys(schema.modules)
.map(moduleName => {
const modules = schema.modules[moduleName].nativeModules;
if (!modules) {
throw new Error('modules does not exist');
}

return modules;
})
.map(moduleName => schema.modules[moduleName].nativeModules)
.filter(Boolean)
.reduce((acc, components) => Object.assign(acc, components), {});

Object.keys(nativeModules).forEach(name => {
console.log(`Generating Native${name}Spec.g.h`);
const {properties} = nativeModules[name];
const traversedProperties = renderProperties(properties, false);
const traversedPropertyTuples = renderProperties(properties, true);

files.set(
`Native${name}Spec.g.h`,
moduleTemplate
.replace(/::_MODULE_PROPERTIES_TUPLE_::/g, traversedPropertyTuples)
.replace(/::_MODULE_PROPERTIES_SPEC_ERRORS_::/g, traversedProperties)
.replace(/::_MODULE_NAME_::/g, name)
.replace(/::_NAMESPACE_::/g, namespace),
);
});
if (nativeModules) {
Object.keys(nativeModules).forEach(name => {
console.log(`Generating Native${name}Spec.g.h`);
const {properties} = nativeModules[name];
const traversedProperties = renderProperties(properties, false);
const traversedPropertyTuples = renderProperties(properties, true);

files.set(
`Native${name}Spec.g.h`,
moduleTemplate
.replace(/::_MODULE_PROPERTIES_TUPLE_::/g, traversedPropertyTuples)
.replace(
/::_MODULE_PROPERTIES_SPEC_ERRORS_::/g,
traversedProperties,
)
.replace(/::_MODULE_NAME_::/g, name)
.replace(/::_NAMESPACE_::/g, namespace),
);
});
}

return files;
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@

// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

#pragma once

#include "ActivityIndicatorComponentView.h"

#include <UI.Xaml.Controls.h>
#include <Utils/ValueUtils.h>

#include <react/components/rnwcore/Props.h>

namespace Microsoft::ReactNative {

ActivityIndicatorComponentView::ActivityIndicatorComponentView() : m_element(xaml::Controls::ProgressRing()) {
static auto const defaultProps = std::make_shared<facebook::react::ActivityIndicatorViewProps const>();
m_props = defaultProps;
}

std::vector<facebook::react::ComponentDescriptorProvider>
ActivityIndicatorComponentView::supplementalComponentDescriptorProviders() noexcept {
return {};
}

void ActivityIndicatorComponentView::mountChildComponentView(
const IComponentView &childComponentView,
uint32_t index) noexcept {
assert(false);
}

void ActivityIndicatorComponentView::unmountChildComponentView(
const IComponentView &childComponentView,
uint32_t index) noexcept {
assert(false);
}

void ActivityIndicatorComponentView::updateProps(
facebook::react::Props::Shared const &props,
facebook::react::Props::Shared const &oldProps) noexcept {
const auto &oldActivityProps = *std::static_pointer_cast<const facebook::react::ActivityIndicatorViewProps>(m_props);
const auto &newActivityProps = *std::static_pointer_cast<const facebook::react::ActivityIndicatorViewProps>(props);

if (oldActivityProps.animating != newActivityProps.animating) {
m_element.IsActive(newActivityProps.animating);
}

if (oldActivityProps.color != newActivityProps.color) {
m_element.Foreground(SolidColorBrushFrom(newActivityProps.color));
}

m_props = std::static_pointer_cast<facebook::react::ActivityIndicatorViewProps const>(props);
}

void ActivityIndicatorComponentView::updateState(
facebook::react::State::Shared const &state,
facebook::react::State::Shared const &oldState) noexcept {}
void ActivityIndicatorComponentView::updateLayoutMetrics(
facebook::react::LayoutMetrics const &layoutMetrics,
facebook::react::LayoutMetrics const &oldLayoutMetrics) noexcept {
// Set Position & Size Properties

m_layoutMetrics = layoutMetrics;

winrt::Microsoft::ReactNative::ViewPanel::SetLeft(m_element, layoutMetrics.frame.origin.x);
winrt::Microsoft::ReactNative::ViewPanel::SetTop(m_element, layoutMetrics.frame.origin.y);

m_element.Width(layoutMetrics.frame.size.width);
m_element.Height(layoutMetrics.frame.size.height);
}
void ActivityIndicatorComponentView::finalizeUpdates(RNComponentViewUpdateMask updateMask) noexcept {}
void ActivityIndicatorComponentView::prepareForRecycle() noexcept {}
facebook::react::SharedProps ActivityIndicatorComponentView::props() noexcept {
assert(false);
return {};
}

const xaml::FrameworkElement ActivityIndicatorComponentView::Element() const noexcept {
return m_element;
}

} // namespace Microsoft::ReactNative
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@

// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

#pragma once

#include "ComponentView.h"

#include <Microsoft.ReactNative.Cxx/ReactContext.h>
#include <UI.Xaml.Controls.h>
#include "ViewComponentView.h"

#pragma warning(push)
#pragma warning(disable : 4244 4305)
#include <react/renderer/components/view/ViewProps.h>
#pragma warning(pop)

namespace Microsoft::ReactNative {

struct ActivityIndicatorComponentView : BaseComponentView {
ActivityIndicatorComponentView();

std::vector<facebook::react::ComponentDescriptorProvider> supplementalComponentDescriptorProviders() noexcept
override;
void mountChildComponentView(const IComponentView &childComponentView, uint32_t index) noexcept override;
void unmountChildComponentView(const IComponentView &childComponentView, uint32_t index) noexcept override;
void updateProps(facebook::react::Props::Shared const &props, facebook::react::Props::Shared const &oldProps) noexcept
override;
void updateState(facebook::react::State::Shared const &state, facebook::react::State::Shared const &oldState) noexcept
override;
void updateLayoutMetrics(
facebook::react::LayoutMetrics const &layoutMetrics,
facebook::react::LayoutMetrics const &oldLayoutMetrics) noexcept override;
void finalizeUpdates(RNComponentViewUpdateMask updateMask) noexcept override;
void prepareForRecycle() noexcept override;
facebook::react::SharedProps props() noexcept override;

const xaml::FrameworkElement Element() const noexcept override;

private:
facebook::react::SharedViewProps m_props;
facebook::react::LayoutMetrics m_layoutMetrics;
xaml::Controls::ProgressRing m_element;
};

} // namespace Microsoft::ReactNative
4 changes: 4 additions & 0 deletions vnext/Microsoft.ReactNative/Fabric/ComponentViewRegistry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <react/renderer/components/scrollview/ScrollViewShadowNode.h>
#pragma warning(pop)

#include <react/components/rnwcore/ShadowNodes.h>
#include <react/renderer/components/image/ImageShadowNode.h>
#include <react/renderer/components/root/RootShadowNode.h>
#include <react/renderer/components/text/ParagraphShadowNode.h>
Expand All @@ -18,6 +19,7 @@
#include <react/renderer/components/textinput/iostextinput/TextInputShadowNode.h>
#include <react/renderer/components/view/ViewShadowNode.h>

#include "ActivityIndicatorComponentView.h"
#include "ImageComponentView.h"
#include "ParagraphComponentView.h"
#include "ScrollViewComponentView.h"
Expand Down Expand Up @@ -45,6 +47,8 @@ ComponentViewDescriptor const &ComponentViewRegistry::dequeueComponentViewWithCo
view = std::make_shared<ScrollViewComponentView>();
} else if (componentHandle == facebook::react::ImageShadowNode::Handle()) {
view = std::make_shared<ImageComponentView>(m_context);
} else if (componentHandle == facebook::react::ActivityIndicatorViewShadowNode::Handle()) {
view = std::make_shared<ActivityIndicatorComponentView>();
} else {
// Just to keep track of what kinds of shadownodes we are being used verify we know about them here
assert(
Expand Down
3 changes: 3 additions & 0 deletions vnext/Microsoft.ReactNative/Fabric/FabricUIManagerModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <JSI/jsi.h>
#include <SchedulerSettings.h>
#include <UI.Xaml.Controls.h>
#include <react/components/rnwcore/ComponentDescriptors.h>
#include <react/renderer/componentregistry/ComponentDescriptorProviderRegistry.h>
#include <react/renderer/components/image/ImageComponentDescriptor.h>
#include <react/renderer/components/text/ParagraphComponentDescriptor.h>
Expand Down Expand Up @@ -134,6 +135,8 @@ class AsyncEventBeat final : public facebook::react::EventBeat { //, public face
std::shared_ptr<facebook::react::ComponentDescriptorProviderRegistry const> sharedProviderRegistry() {
static auto providerRegistry = []() -> std::shared_ptr<facebook::react::ComponentDescriptorProviderRegistry> {
auto providerRegistry = std::make_shared<facebook::react::ComponentDescriptorProviderRegistry>();
providerRegistry->add(facebook::react::concreteComponentDescriptorProvider<
facebook::react::ActivityIndicatorViewComponentDescriptor>());
providerRegistry->add(
facebook::react::concreteComponentDescriptorProvider<facebook::react::ImageComponentDescriptor>());
providerRegistry->add(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

// RN has some weird include directory redirections..this forwards the include to the right place
#include <react/renderer/components/image/conversions.h>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

// RN has some weird include directory redirections..this forwards the include to the right place
#include <react/renderer/components/view/ConcreteViewShadowNode.h>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

// RN has some weird include directory redirections..this forwards the include to the right place
#include <react/renderer/components/view/ViewEventEmitter.h>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

// RN has some weird include directory redirections..this forwards the include to the right place
#include <react/renderer/components/view/ViewProps.h>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

// RN has some weird include directory redirections..this forwards the include to the right place
#include <react/renderer/core/ConcreteComponentDescriptor.h>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

// RN has some weird include directory redirections..this forwards the include to the right place
#include <react/renderer/core/propsConversions.h>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

// RN has some weird include directory redirections..this forwards the include to the right place
#include <react/renderer/graphics/platform/cxx/react/renderer/graphics/Color.h>
Loading

0 comments on commit 36e48e2

Please sign in to comment.