Skip to content

Commit

Permalink
Expose UIManager.getConstants instead of getNativeViewConfig to JS in…
Browse files Browse the repository at this point in the history
… bridgeless mode (#37865)

Summary:
Pull Request resolved: #37865

In bridge mode UIManager's `constants` contain view configs for every registered native component and possibly some extra data.

On iOS there is no extra data, but on Android in addition to view configs there are `genericBubblingEventTypes` and `genericDirectEventTypes`. They are then [merged](https://github.com/facebook/react-native/blob/main/packages/react-native/Libraries/ReactNative/getNativeComponentAttributes.js#L110-L116) into `bubblingEventTypes` and `directEventTypes` of every view config.

This diff replaces `getNativeViewConfig` binding with `getConstants` to make this behaviour possible in the bridgeless mode.

This diff also removes caching on native side with the expectation that `constants` will be cached on JS side just as [it is done](https://github.com/facebook/react-native/blob/main/packages/react-native/Libraries/ReactNative/PaperUIManager.js#L24-L32) in bridge mode.

Changelog: [Internal] - Expose UIManager.getConstants instead of getNativeViewConfig to JS in bridgeless mode.

Reviewed By: RSNara

Differential Revision: D46698717

fbshipit-source-id: f9c96e220e49f6947766336ea545c01e38cb46ac
  • Loading branch information
dmytrorykun authored and facebook-github-bot committed Jun 28, 2023
1 parent c803a5b commit a9618b3
Show file tree
Hide file tree
Showing 8 changed files with 95 additions and 105 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,26 @@
* LICENSE file in the root directory of this source tree.
*/

#include "NativeViewConfigProviderBinding.h"
#include "LegacyUIManagerConstantsProviderBinding.h"

namespace facebook::react::NativeViewConfigProviderBinding {
namespace facebook::react::LegacyUIManagerConstantsProviderBinding {

void install(jsi::Runtime &runtime, ProviderType &&provider) {
auto name = "RN$NativeComponentRegistry_getNativeViewConfig";
auto name = "RN$LegacyInterop_UIManager_getConstants";
auto hostFunction = [provider = std::move(provider)](
jsi::Runtime &runtime,
jsi::Value const & /*thisValue*/,
jsi::Value const *args,
jsi::Value const * /*arguments*/,
size_t count) -> jsi::Value {
if (count != 1 || !args[0].isString()) {
throw new jsi::JSError(runtime, "1 argument of type String expected.");
if (count != 0) {
throw new jsi::JSError(runtime, "0 arguments expected.");
}
return provider(args[0].getString(runtime).utf8(runtime));
return provider();
};

auto jsiFunction = jsi::Function::createFromHostFunction(
runtime, jsi::PropNameID::forAscii(runtime, name), 2, hostFunction);

runtime.global().setProperty(runtime, name, jsiFunction);
}
} // namespace facebook::react::NativeViewConfigProviderBinding
} // namespace facebook::react::LegacyUIManagerConstantsProviderBinding
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

#pragma once

#include <jsi/jsi.h>

namespace facebook::react::LegacyUIManagerConstantsProviderBinding {

using ProviderType = std::function<jsi::Value()>;

/*
* Installs RN$LegacyInterop_UIManager_getConstants binding into JavaScript
* runtime. It is supposed to be used as a substitute to UIManager.getConstants
* in bridgeless mode.
*/
void install(jsi::Runtime &runtime, ProviderType &&provider);
} // namespace facebook::react::LegacyUIManagerConstantsProviderBinding

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
#import <React/RCTModuleData.h>
#import <React/RCTPerformanceLogger.h>
#import <React/RCTSurfacePresenter.h>
#import <ReactCommon/RCTNativeViewConfigProvider.h>
#import <ReactCommon/RCTLegacyUIManagerConstantsProvider.h>
#import <ReactCommon/RCTTurboModuleManager.h>
#import <ReactCommon/RuntimeExecutor.h>
#import <cxxreact/ReactMarker.h>
Expand Down Expand Up @@ -296,7 +296,7 @@ - (void)_start
RCTInstallNativeComponentRegistryBinding(runtime);

if (RCTGetUseNativeViewConfigsInBridgelessMode()) {
installNativeViewConfigProviderBinding(runtime);
installLegacyUIManagerConstantsProviderBinding(runtime);
}

[strongSelf->_delegate instance:strongSelf didInitializeRuntime:runtime];
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

#pragma once

#include <jsi/jsi.h>

namespace facebook::react {
/*
* Installs UIManger constants provider into JavaScript runtime. This is needed
* to implement UIManager.getConstants in bridgeless mode. The constants object
* contains view configs for every legacy native component.
*/
void installLegacyUIManagerConstantsProviderBinding(jsi::Runtime &runtime);
} // namespace facebook::react
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

#include "RCTLegacyUIManagerConstantsProvider.h"

#import <React/RCTBridge+Private.h>
#import <React/RCTComponentData.h>
#import <React/RCTUIManager.h>
#import <React/RCTViewManager.h>
#import <ReactCommon/RCTTurboModule.h>
#import <react/bridgeless/nativeviewconfig/LegacyUIManagerConstantsProviderBinding.h>

namespace facebook::react {
namespace {

jsi::Value getConstants(facebook::jsi::Runtime &runtime)
{
static NSMutableDictionary<NSString *, NSObject *> *result = [NSMutableDictionary new];
auto directEvents = [NSMutableDictionary new];
auto bubblingEvents = [NSMutableDictionary new];
for (Class moduleClass in RCTGetModuleClasses()) {
if ([moduleClass isSubclassOfClass:RCTViewManager.class]) {
auto name = RCTViewManagerModuleNameForClass(moduleClass);
auto viewConfig = [RCTComponentData viewConfigForViewMangerClass:moduleClass];
auto moduleConstants =
RCTModuleConstantsForDestructuredComponent(directEvents, bubblingEvents, moduleClass, name, viewConfig);
result[name] = moduleConstants;
}
}
return TurboModuleConvertUtils::convertObjCObjectToJSIValue(runtime, result);
};

} // namespace

void installLegacyUIManagerConstantsProviderBinding(jsi::Runtime &runtime)
{
auto constantsProvider = [&runtime]() -> jsi::Value { return getConstants(runtime); };
LegacyUIManagerConstantsProviderBinding::install(runtime, std::move(constantsProvider));
}
} // namespace facebook::react

This file was deleted.

This file was deleted.

0 comments on commit a9618b3

Please sign in to comment.