From 1719a072fd036a54db5ef6ddb4da8fdc7cf55033 Mon Sep 17 00:00:00 2001 From: Samuel Susla Date: Fri, 6 Oct 2023 07:44:50 -0700 Subject: [PATCH] Delete native UI template (#39487) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/39487 changelog: [internal] renderTemplateToSurface isn't used, let's remove it. Reviewed By: javache Differential Revision: D49313868 fbshipit-source-id: 9019d5b4adbd23632f27dd61bc18a97b447575d4 --- .../facebook/react/ReactInstanceManager.java | 3 +- .../com/facebook/react/ReactRootView.java | 18 +- .../com/facebook/react/bridge/UIManager.java | 3 +- .../com/facebook/react/fabric/Binding.java | 2 - .../facebook/react/fabric/BindingImpl.java | 3 - .../react/fabric/FabricUIManager.java | 6 +- .../facebook/react/uimanager/ReactRoot.java | 3 - .../react/uimanager/UIManagerModule.java | 5 +- .../ReactAndroid/src/main/jni/CMakeLists.txt | 3 - .../src/main/jni/react/fabric/Binding.cpp | 17 -- .../src/main/jni/react/fabric/Binding.h | 2 - .../src/main/jni/react/fabric/CMakeLists.txt | 1 - .../ComponentDescriptorRegistry.cpp | 27 --- .../ComponentDescriptorRegistry.h | 7 - .../react/renderer/scheduler/CMakeLists.txt | 1 - .../react/renderer/scheduler/Scheduler.cpp | 39 ---- .../react/renderer/scheduler/Scheduler.h | 4 - .../renderer/templateprocessor/CMakeLists.txt | 33 ---- .../templateprocessor/UITemplateProcessor.cpp | 153 ---------------- .../templateprocessor/UITemplateProcessor.h | 64 ------- .../tests/UITemplateProcessorTest.cpp | 166 ------------------ 21 files changed, 6 insertions(+), 554 deletions(-) delete mode 100644 packages/react-native/ReactCommon/react/renderer/templateprocessor/CMakeLists.txt delete mode 100644 packages/react-native/ReactCommon/react/renderer/templateprocessor/UITemplateProcessor.cpp delete mode 100644 packages/react-native/ReactCommon/react/renderer/templateprocessor/UITemplateProcessor.h delete mode 100644 packages/react-native/ReactCommon/react/renderer/templateprocessor/tests/UITemplateProcessorTest.cpp diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java index 7a56f1d1345f5c..846335c30e210a 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java @@ -1237,8 +1237,7 @@ private void attachRootViewToInstance(final ReactRoot reactRoot) { reactRoot.getRootViewGroup(), initialProperties == null ? new WritableNativeMap() - : Arguments.fromBundle(initialProperties), - reactRoot.getInitialUITemplate()); + : Arguments.fromBundle(initialProperties)); reactRoot.setRootViewTag(rootTag); reactRoot.runApplication(); } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactRootView.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactRootView.java index 8142f72c9271e4..731dcb9a6d9e2f 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactRootView.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactRootView.java @@ -94,7 +94,6 @@ public interface ReactRootViewEventListener { private @Nullable ReactInstanceManager mReactInstanceManager; private @Nullable String mJSModuleName; private @Nullable Bundle mAppProperties; - private @Nullable String mInitialUITemplate; private @Nullable CustomGlobalLayoutListener mCustomGlobalLayoutListener; private @Nullable ReactRootViewEventListener mRootViewEventListener; private int mRootViewTag = @@ -452,14 +451,6 @@ public void startReactApplication(ReactInstanceManager reactInstanceManager, Str startReactApplication(reactInstanceManager, moduleName, null); } - /** {@see #startReactApplication(ReactInstanceManager, String, android.os.Bundle, String)} */ - public void startReactApplication( - ReactInstanceManager reactInstanceManager, - String moduleName, - @Nullable Bundle initialProperties) { - startReactApplication(reactInstanceManager, moduleName, initialProperties, null); - } - /** * Schedule rendering of the react component rendered by the JS application from the given JS * module (@{param moduleName}) using provided {@param reactInstanceManager} to attach to the JS @@ -470,8 +461,7 @@ public void startReactApplication( public void startReactApplication( ReactInstanceManager reactInstanceManager, String moduleName, - @Nullable Bundle initialProperties, - @Nullable String initialUITemplate) { + @Nullable Bundle initialProperties) { Systrace.beginSection(TRACE_TAG_REACT_JAVA_BRIDGE, "startReactApplication"); try { UiThreadUtil.assertOnUiThread(); @@ -486,7 +476,6 @@ public void startReactApplication( mReactInstanceManager = reactInstanceManager; mJSModuleName = moduleName; mAppProperties = initialProperties; - mInitialUITemplate = initialUITemplate; mReactInstanceManager.createReactContextInBackground(); // if in this experiment, we initialize the root earlier in startReactApplication @@ -651,11 +640,6 @@ public String getJSModuleName() { return mAppProperties; } - @Override - public @Nullable String getInitialUITemplate() { - return mInitialUITemplate; - } - @ThreadConfined(UI) public void setAppProperties(@Nullable Bundle appProperties) { UiThreadUtil.assertOnUiThread(); diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/UIManager.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/UIManager.java index f3c3ede01a5348..0419a8395b4b1a 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/UIManager.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/UIManager.java @@ -21,8 +21,7 @@ public interface UIManager extends JSIModule, PerformanceCounter { @UiThread @ThreadConfined(UI) @Deprecated - int addRootView( - final T rootView, WritableMap initialProps, @Nullable String initialUITemplate); + int addRootView(final T rootView, WritableMap initialProps); /** Registers a new root view with width and height. */ @AnyThread diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/Binding.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/Binding.java index e99632b25bed77..7a6da825c687df 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/Binding.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/Binding.java @@ -33,8 +33,6 @@ public void startSurfaceWithConstraints( boolean isRTL, boolean doLeftAndRightSwapInRTL); - public void renderTemplateToSurface(int surfaceId, String uiTemplate); - public void stopSurface(int surfaceId); public void setPixelDensity(float pointScaleFactor); diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/BindingImpl.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/BindingImpl.java index a05dc0ef207bed..b3c203f5aab5e0 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/BindingImpl.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/BindingImpl.java @@ -63,9 +63,6 @@ public native void startSurfaceWithConstraints( boolean isRTL, boolean doLeftAndRightSwapInRTL); - @Override - public native void renderTemplateToSurface(int surfaceId, String uiTemplate); - @Override public native void stopSurface(int surfaceId); diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java index 765487f043cdcd..f21ef5af64ca6c 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java @@ -237,8 +237,7 @@ public FabricUIManager( @UiThread @ThreadConfined(UI) @Deprecated - public int addRootView( - final T rootView, final WritableMap initialProps, final @Nullable String initialUITemplate) { + public int addRootView(final T rootView, final WritableMap initialProps) { ReactSoftExceptionLogger.logSoftException( TAG, new IllegalViewOperationException( @@ -256,9 +255,6 @@ public int addRootView( FLog.d(TAG, "Starting surface for module: %s and reactTag: %d", moduleName, rootTag); } mBinding.startSurface(rootTag, moduleName, (NativeMap) initialProps); - if (initialUITemplate != null) { - mBinding.renderTemplateToSurface(rootTag, initialUITemplate); - } return rootTag; } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactRoot.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactRoot.java index ddbb7932439ee6..e8ddb4b4b18d68 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactRoot.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactRoot.java @@ -25,9 +25,6 @@ public interface ReactRoot { @Nullable Bundle getAppProperties(); - @Nullable - String getInitialUITemplate(); - String getJSModuleName(); /** Fabric or Default UI Manager, see {@link UIManagerType} */ diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModule.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModule.java index 8ef20ad609a5df..ba2b8f3362df85 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModule.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModule.java @@ -313,7 +313,7 @@ public Map getPerformanceCounters() { } public int addRootView(final T rootView) { - return addRootView(rootView, null, null); + return addRootView(rootView, null); } /** @@ -341,8 +341,7 @@ public void synchronouslyUpdateViewOnUIThread(int tag, ReadableMap props) { *

TODO(6242243): Make addRootView thread safe NB: this method is horribly not-thread-safe. */ @Override - public int addRootView( - final T rootView, WritableMap initialProps, @Nullable String initialUITemplate) { + public int addRootView(final T rootView, WritableMap initialProps) { Systrace.beginSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, "UIManagerModule.addRootView"); final int tag = ReactRootViewTagGenerator.getNextRootViewTag(); final ReactApplicationContext reactApplicationContext = getReactApplicationContext(); diff --git a/packages/react-native/ReactAndroid/src/main/jni/CMakeLists.txt b/packages/react-native/ReactAndroid/src/main/jni/CMakeLists.txt index 64102e3db2d436..e71987bab948c0 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/CMakeLists.txt +++ b/packages/react-native/ReactAndroid/src/main/jni/CMakeLists.txt @@ -77,7 +77,6 @@ add_react_common_subdir(react/renderer/componentregistry) add_react_common_subdir(react/renderer/mounting) add_react_common_subdir(react/renderer/scheduler) add_react_common_subdir(react/renderer/telemetry) -add_react_common_subdir(react/renderer/templateprocessor) add_react_common_subdir(react/renderer/uimanager) add_react_common_subdir(react/renderer/core) add_react_common_subdir(react/renderer/element) @@ -164,7 +163,6 @@ add_executable(reactnative_unittest ${REACT_COMMON_DIR}/react/renderer/runtimescheduler/tests/RuntimeSchedulerTest.cpp ${REACT_COMMON_DIR}/react/renderer/runtimescheduler/tests/SchedulerPriorityTest.cpp ${REACT_COMMON_DIR}/react/renderer/telemetry/tests/TransactionTelemetryTest.cpp - ${REACT_COMMON_DIR}/react/renderer/templateprocessor/tests/UITemplateProcessorTest.cpp ${REACT_COMMON_DIR}/react/renderer/textlayoutmanager/tests/TextLayoutManagerTest.cpp ${REACT_COMMON_DIR}/react/renderer/uimanager/tests/FabricUIManagerTest.cpp @@ -209,7 +207,6 @@ add_executable(reactnative_unittest react_render_graphics react_render_mapbuffer react_render_mounting - react_render_templateprocessor react_render_textlayoutmanager react_render_uimanager react_utils diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/Binding.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/Binding.cpp index e61652c54720f6..27e48acbf3b8e7 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/Binding.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/Binding.cpp @@ -219,21 +219,6 @@ void Binding::startSurfaceWithConstraints( mountingManager->onSurfaceStart(surfaceId); } -void Binding::renderTemplateToSurface(jint surfaceId, jstring uiTemplate) { - SystraceSection s("FabricUIManagerBinding::renderTemplateToSurface"); - - auto scheduler = getScheduler(); - if (!scheduler) { - LOG(ERROR) << "Binding::renderTemplateToSurface: scheduler disappeared"; - return; - } - - auto env = jni::Environment::current(); - const char* nativeString = env->GetStringUTFChars(uiTemplate, JNI_FALSE); - scheduler->renderTemplateToSurface(surfaceId, nativeString); - env->ReleaseStringUTFChars(uiTemplate, nativeString); -} - void Binding::stopSurface(jint surfaceId) { SystraceSection s("FabricUIManagerBinding::stopSurface"); @@ -581,8 +566,6 @@ void Binding::registerNatives() { "getInspectorDataForInstance", Binding::getInspectorDataForInstance), makeNativeMethod( "startSurfaceWithConstraints", Binding::startSurfaceWithConstraints), - makeNativeMethod( - "renderTemplateToSurface", Binding::renderTemplateToSurface), makeNativeMethod("stopSurface", Binding::stopSurface), makeNativeMethod("setConstraints", Binding::setConstraints), makeNativeMethod("setPixelDensity", Binding::setPixelDensity), diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/Binding.h b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/Binding.h index d4266bcab6f2da..d447a501ef0394 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/Binding.h +++ b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/Binding.h @@ -88,8 +88,6 @@ class Binding : public jni::HybridClass, jboolean isRTL, jboolean doLeftAndRightSwapInRTL); - void renderTemplateToSurface(jint surfaceId, jstring uiTemplate); - void stopSurface(jint surfaceId); void registerSurface(SurfaceHandlerBinding* surfaceHandler); diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/CMakeLists.txt b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/CMakeLists.txt index 3e75ad4eed65b0..afaca0d1916e52 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/CMakeLists.txt +++ b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/CMakeLists.txt @@ -38,7 +38,6 @@ target_link_libraries( react_render_runtimescheduler react_render_scheduler react_render_telemetry - react_render_templateprocessor react_render_textlayoutmanager react_render_uimanager react_utils diff --git a/packages/react-native/ReactCommon/react/renderer/componentregistry/ComponentDescriptorRegistry.cpp b/packages/react-native/ReactCommon/react/renderer/componentregistry/ComponentDescriptorRegistry.cpp index d7b4e6eb0deb36..7c650cf21c0d98 100644 --- a/packages/react-native/ReactCommon/react/renderer/componentregistry/ComponentDescriptorRegistry.cpp +++ b/packages/react-native/ReactCommon/react/renderer/componentregistry/ComponentDescriptorRegistry.cpp @@ -121,33 +121,6 @@ bool ComponentDescriptorRegistry::hasComponentDescriptorAt( return iterator != _registryByHandle.end(); } -ShadowNode::Shared ComponentDescriptorRegistry::createNode( - Tag tag, - const std::string& viewName, - SurfaceId surfaceId, - const folly::dynamic& propsDynamic, - const InstanceHandle::Shared& instanceHandle) const { - auto unifiedComponentName = componentNameByReactViewName(viewName); - const auto& componentDescriptor = this->at(unifiedComponentName); - - const auto fragment = - ShadowNodeFamilyFragment{tag, surfaceId, instanceHandle}; - auto family = componentDescriptor.createFamily(fragment); - const auto props = componentDescriptor.cloneProps( - PropsParserContext{surfaceId, *contextContainer_.get()}, - nullptr, - RawProps(propsDynamic)); - const auto state = componentDescriptor.createInitialState(props, family); - - return componentDescriptor.createShadowNode( - { - /* .props = */ props, - /* .children = */ ShadowNodeFragment::childrenPlaceholder(), - /* .state = */ state, - }, - family); -} - void ComponentDescriptorRegistry::setFallbackComponentDescriptor( const SharedComponentDescriptor& descriptor) { _fallbackComponentDescriptor = descriptor; diff --git a/packages/react-native/ReactCommon/react/renderer/componentregistry/ComponentDescriptorRegistry.h b/packages/react-native/ReactCommon/react/renderer/componentregistry/ComponentDescriptorRegistry.h index 08c6e524fe25ea..20bce41f2dcf47 100644 --- a/packages/react-native/ReactCommon/react/renderer/componentregistry/ComponentDescriptorRegistry.h +++ b/packages/react-native/ReactCommon/react/renderer/componentregistry/ComponentDescriptorRegistry.h @@ -54,13 +54,6 @@ class ComponentDescriptorRegistry { bool hasComponentDescriptorAt(ComponentHandle componentHandle) const; - ShadowNode::Shared createNode( - Tag tag, - const std::string& viewName, - SurfaceId surfaceId, - const folly::dynamic& props, - const InstanceHandle::Shared& instanceHandle) const; - void setFallbackComponentDescriptor( const SharedComponentDescriptor& descriptor); ComponentDescriptor::Shared getFallbackComponentDescriptor() const; diff --git a/packages/react-native/ReactCommon/react/renderer/scheduler/CMakeLists.txt b/packages/react-native/ReactCommon/react/renderer/scheduler/CMakeLists.txt index fd7f93db411371..56659df31176b7 100644 --- a/packages/react-native/ReactCommon/react/renderer/scheduler/CMakeLists.txt +++ b/packages/react-native/ReactCommon/react/renderer/scheduler/CMakeLists.txt @@ -32,7 +32,6 @@ target_link_libraries(react_render_scheduler react_render_graphics react_render_mounting react_render_runtimescheduler - react_render_templateprocessor react_render_uimanager react_utils rrc_root diff --git a/packages/react-native/ReactCommon/react/renderer/scheduler/Scheduler.cpp b/packages/react-native/ReactCommon/react/renderer/scheduler/Scheduler.cpp index b381de0a82652c..b52841fb8ea322 100644 --- a/packages/react-native/ReactCommon/react/renderer/scheduler/Scheduler.cpp +++ b/packages/react-native/ReactCommon/react/renderer/scheduler/Scheduler.cpp @@ -18,7 +18,6 @@ #include #include #include -#include #include #include @@ -256,44 +255,6 @@ void Scheduler::unregisterSurface( surfaceHandler.setUIManager(nullptr); } -void Scheduler::renderTemplateToSurface( - SurfaceId surfaceId, - const std::string& uiTemplate) { - SystraceSection s("Scheduler::renderTemplateToSurface"); - try { - if (uiTemplate.empty()) { - return; - } - NativeModuleRegistry nMR; - auto tree = UITemplateProcessor::buildShadowTree( - uiTemplate, - surfaceId, - folly::dynamic::object(), - *componentDescriptorRegistry_, - nMR, - reactNativeConfig_); - - uiManager_->getShadowTreeRegistry().visit( - surfaceId, [=](const ShadowTree& shadowTree) { - return shadowTree.tryCommit( - [&](RootShadowNode const& oldRootShadowNode) { - return std::make_shared( - oldRootShadowNode, - ShadowNodeFragment{ - /* .props = */ ShadowNodeFragment::propsPlaceholder(), - /* .children = */ - std::make_shared( - ShadowNode::ListOfShared{tree}), - }); - }, - {/* default commit options */}); - }); - } catch (const std::exception& e) { - LOG(ERROR) << " >>>> EXCEPTION <<< rendering uiTemplate in " - << "Scheduler::renderTemplateToSurface: " << e.what(); - } -} - const ComponentDescriptor* Scheduler::findComponentDescriptorByHandle_DO_NOT_USE_THIS_IS_BROKEN( ComponentHandle handle) const { diff --git a/packages/react-native/ReactCommon/react/renderer/scheduler/Scheduler.h b/packages/react-native/ReactCommon/react/renderer/scheduler/Scheduler.h index a784a09744a727..2df6472ab6a68f 100644 --- a/packages/react-native/ReactCommon/react/renderer/scheduler/Scheduler.h +++ b/packages/react-native/ReactCommon/react/renderer/scheduler/Scheduler.h @@ -54,10 +54,6 @@ class Scheduler final : public UIManagerDelegate { InspectorData getInspectorDataForInstance( const EventEmitter& eventEmitter) const noexcept; - void renderTemplateToSurface( - SurfaceId surfaceId, - const std::string& uiTemplate); - /* * This is broken. Please do not use. * `ComponentDescriptor`s are not designed to be used outside of `UIManager`, diff --git a/packages/react-native/ReactCommon/react/renderer/templateprocessor/CMakeLists.txt b/packages/react-native/ReactCommon/react/renderer/templateprocessor/CMakeLists.txt deleted file mode 100644 index ce1065135e4f07..00000000000000 --- a/packages/react-native/ReactCommon/react/renderer/templateprocessor/CMakeLists.txt +++ /dev/null @@ -1,33 +0,0 @@ -# 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. - -cmake_minimum_required(VERSION 3.13) -set(CMAKE_VERBOSE_MAKEFILE on) - -add_compile_options( - -fexceptions - -frtti - -std=c++20 - -Wall - -Wpedantic - -Wno-gnu-zero-variadic-macro-arguments - -DLOG_TAG=\"Fabric\") - -file(GLOB react_render_templateprocessor_SRC CONFIGURE_DEPENDS *.cpp) -add_library(react_render_templateprocessor SHARED ${react_render_templateprocessor_SRC}) - -target_include_directories(react_render_templateprocessor PUBLIC ${REACT_COMMON_DIR}) - -target_link_libraries(react_render_templateprocessor - folly_runtime - glog - jsi - react_config - react_render_componentregistry - react_render_core - react_render_debug - react_render_uimanager - react_utils -) diff --git a/packages/react-native/ReactCommon/react/renderer/templateprocessor/UITemplateProcessor.cpp b/packages/react-native/ReactCommon/react/renderer/templateprocessor/UITemplateProcessor.cpp deleted file mode 100644 index 79d54b5ee04fb5..00000000000000 --- a/packages/react-native/ReactCommon/react/renderer/templateprocessor/UITemplateProcessor.cpp +++ /dev/null @@ -1,153 +0,0 @@ -/* - * 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 "UITemplateProcessor.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace facebook::react { - -bool constexpr DEBUG_FLY = false; - -struct RBCContext { - const Tag rootTag; - const std::vector& nodes; - const std::vector& registers; - const ComponentDescriptorRegistry& componentDescriptorRegistry; - const NativeModuleRegistry& nativeModuleRegistry; -}; - -// TODO: use RBCContext instead of all the separate arguments. -ShadowNode::Shared UITemplateProcessor::runCommand( - const folly::dynamic& command, - SurfaceId surfaceId, - std::vector& nodes, - std::vector& registers, - const ComponentDescriptorRegistry& componentDescriptorRegistry, - const NativeModuleRegistry& nativeModuleRegistry, - const std::shared_ptr& reactNativeConfig) { - const std::string& opcode = command[0].asString(); - const int tagOffset = 420000; - // TODO: change to integer codes and a switch statement - if (opcode == "createNode") { - Tag tag = static_cast(command[1].asInt()); - const auto& type = command[2].asString(); - const auto parentTag = command[3].asInt(); - const auto& props = command[4]; - nodes[tag] = componentDescriptorRegistry.createNode( - tag + tagOffset, type, surfaceId, props, nullptr); - if (parentTag > -1) { // parentTag == -1 indicates root node - auto parentShadowNode = nodes[static_cast(parentTag)]; - const auto& componentDescriptor = componentDescriptorRegistry.at( - parentShadowNode->getComponentHandle()); - componentDescriptor.appendChild(parentShadowNode, nodes[tag]); - } - } else if (opcode == "returnRoot") { - if (DEBUG_FLY) { - LOG(INFO) - << "(stop) UITemplateProcessor inject serialized 'server rendered' view tree"; - } - return nodes[static_cast(command[1].asInt())]; - } else if (opcode == "loadNativeBool") { - auto registerNumber = static_cast(command[1].asInt()); - std::string param = command[4][0].asString(); - registers[registerNumber] = reactNativeConfig->getBool(param); - } else if (opcode == "conditional") { - auto registerNumber = static_cast(command[1].asInt()); - auto conditionDynamic = registers[registerNumber]; - if (conditionDynamic.isNull()) { - // TODO: provide original command or command line? - auto err = std::runtime_error( - "register " + command[1].asString() + " wasn't loaded before access"); - throw err; - } else if (conditionDynamic.type() != folly::dynamic::BOOL) { - // TODO: provide original command or command line? - auto err = std::runtime_error( - "register " + command[1].asString() + " had type '" + - conditionDynamic.typeName() + - "' but needs to be 'boolean' for conditionals"); - throw err; - } - const auto& nextCommands = - conditionDynamic.asBool() ? command[2] : command[3]; - for (const auto& nextCommand : nextCommands) { - runCommand( - nextCommand, - surfaceId, - nodes, - registers, - componentDescriptorRegistry, - nativeModuleRegistry, - reactNativeConfig); - } - } else { - throw std::runtime_error("Unsupported opcode: " + command[0].asString()); - } - return nullptr; -} - -ShadowNode::Shared UITemplateProcessor::buildShadowTree( - const std::string& jsonStr, - SurfaceId surfaceId, - const folly::dynamic& params, - const ComponentDescriptorRegistry& componentDescriptorRegistry, - const NativeModuleRegistry& nativeModuleRegistry, - const std::shared_ptr& reactNativeConfig) { - if (DEBUG_FLY) { - LOG(INFO) - << "(strt) UITemplateProcessor inject hardcoded 'server rendered' view tree"; - } - - std::string content = jsonStr; - for (const auto& param : params.items()) { - const auto& key = param.first.asString(); - size_t start_pos = content.find(key); - if (start_pos != std::string::npos) { - content.replace(start_pos, key.length(), param.second.asString()); - } - } - auto parsed = folly::parseJson(content); - auto commands = parsed["commands"]; - std::vector nodes(commands.size() * 2); - std::vector registers(32); - for (const auto& command : commands) { - try { - if (DEBUG_FLY) { - LOG(INFO) << "try to run command " << folly::toJson(command); - } - auto ret = runCommand( - command, - surfaceId, - nodes, - registers, - componentDescriptorRegistry, - nativeModuleRegistry, - reactNativeConfig); - if (ret != nullptr) { - return ret; - } - } catch (const std::exception& e) { - LOG(ERROR) << " >>> Exception <<< running previous command '" - << folly::toJson(command) << "': '" << e.what() << "'"; - } - } - LOG(ERROR) << "react ui template missing returnRoot command :("; - throw std::runtime_error( - "Missing returnRoot command in template content:\n" + content); - return ShadowNode::Shared{}; -} - -} // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/renderer/templateprocessor/UITemplateProcessor.h b/packages/react-native/ReactCommon/react/renderer/templateprocessor/UITemplateProcessor.h deleted file mode 100644 index 791a6a02b4726c..00000000000000 --- a/packages/react-native/ReactCommon/react/renderer/templateprocessor/UITemplateProcessor.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * 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 - -#include - -#include -#include -#include -#include - -namespace facebook::react { - -// Temporary NativeModuleRegistry definition -using NativeModuleCallFn = - std::function; - -class NativeModuleRegistry { - public: - void registerModule( - const std::string& moduleName, - NativeModuleCallFn callFn) { - modules_.emplace(moduleName, callFn); - } - - folly::dynamic call( - const std::string& moduleName, - const std::string& methodName, - const folly::dynamic& args) const { - return modules_.at(moduleName)(methodName, args); - } - - private: - std::unordered_map modules_; -}; - -class UITemplateProcessor { - public: - static ShadowNode::Shared buildShadowTree( - const std::string& jsonStr, - int surfaceId, - const folly::dynamic& params, - const ComponentDescriptorRegistry& componentDescriptorRegistry, - const NativeModuleRegistry& nativeModuleRegistry, - const std::shared_ptr& reactNativeConfig); - - private: - static ShadowNode::Shared runCommand( - const folly::dynamic& command, - Tag surfaceId, - std::vector& nodes, - std::vector& registers, - const ComponentDescriptorRegistry& componentDescriptorRegistry, - const NativeModuleRegistry& nativeModuleRegistry, - const std::shared_ptr& reactNativeConfig); -}; -} // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/renderer/templateprocessor/tests/UITemplateProcessorTest.cpp b/packages/react-native/ReactCommon/react/renderer/templateprocessor/tests/UITemplateProcessorTest.cpp deleted file mode 100644 index b0b4ddbd925164..00000000000000 --- a/packages/react-native/ReactCommon/react/renderer/templateprocessor/tests/UITemplateProcessorTest.cpp +++ /dev/null @@ -1,166 +0,0 @@ -/* - * 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 - -#include -#include -#include -#include - -using namespace facebook::react; - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace facebook::react { - -static ComponentRegistryFactory getComponentRegistryFactory() { - return [](const EventDispatcher::Weak& eventDispatcher, - const ContextContainer::Shared& contextContainer) { - ComponentDescriptorProviderRegistry providerRegistry{}; - providerRegistry.add( - concreteComponentDescriptorProvider()); - providerRegistry.add( - concreteComponentDescriptorProvider()); - providerRegistry.add(concreteComponentDescriptorProvider< - ActivityIndicatorViewComponentDescriptor>()); - return providerRegistry.createComponentDescriptorRegistry( - {eventDispatcher, contextContainer}); - }; -} - -bool mockSimpleTestValue_; - -NativeModuleRegistry buildNativeModuleRegistry(); - -NativeModuleRegistry buildNativeModuleRegistry() { - NativeModuleRegistry nMR; - nMR.registerModule( - "MobileConfig", - [&](const std::string& /*unused*/, const folly::dynamic& /*unused*/) { - return mockSimpleTestValue_; - }); - return nMR; -} - -class MockReactNativeConfig : public ReactNativeConfig { - public: - MockReactNativeConfig() = default; - bool getBool(const std::string& /*param*/) const override { - return mockSimpleTestValue_; - } - - std::string getString(const std::string& /*param*/) const override { - return ""; - } - - int64_t getInt64(const std::string& /*param*/) const override { - return 0; - } - - double getDouble(const std::string& /*param*/) const override { - return 0.0; - } -}; - -std::shared_ptr mockReactNativeConfig_ = - std::make_shared(); - -} // namespace facebook::react - -TEST(UITemplateProcessorTest, testSimpleBytecode) { - auto surfaceId = 11; - auto eventDispatcher = std::shared_ptr(); - auto componentDescriptorRegistry = - getComponentRegistryFactory()(eventDispatcher, nullptr); - auto nativeModuleRegistry = buildNativeModuleRegistry(); - - auto bytecode = R"delim({"version":0.1,"commands":[ - ["createNode",2,"RCTView",-1,{"opacity": 0.5, "testID": "root"}], - ["createNode",4,"RCTView",2,{"testID": "child"}], - ["returnRoot",2] - ]})delim"; - - mockSimpleTestValue_ = true; - - auto root1 = UITemplateProcessor::buildShadowTree( - bytecode, - surfaceId, - folly::dynamic::object(), - *componentDescriptorRegistry, - nativeModuleRegistry, - mockReactNativeConfig_); -#ifndef NDEBUG - LOG(INFO) << std::endl << root1->getDebugDescription(); -#endif - auto props1 = std::static_pointer_cast(root1->getProps()); - EXPECT_NEAR(props1->opacity, 0.5, 0.001); - ASSERT_STREQ(props1->testId.c_str(), "root"); - auto children1 = root1->getChildren(); - EXPECT_EQ(children1.size(), 1); - auto child_props1 = - std::static_pointer_cast(children1.at(0)->getProps()); - ASSERT_STREQ(child_props1->testId.c_str(), "child"); -} - -TEST(UITemplateProcessorTest, testConditionalBytecode) { - auto surfaceId = 11; - auto eventDispatcher = std::shared_ptr(); - auto componentDescriptorRegistry = - getComponentRegistryFactory()(eventDispatcher, nullptr); - auto nativeModuleRegistry = buildNativeModuleRegistry(); - - auto bytecode = R"delim({"version":0.1,"commands":[ - ["createNode",2,"RCTView",-1,{"testID": "root"}], - ["loadNativeBool",1,"MobileConfig","getBool",["qe:simple_test"]], - ["conditional",1, - [["createNode",4,"RCTView",2,{"testID": "cond_true"}]], - [["createNode",4,"RCTView",2,{"testID": "cond_false"}]] - ], - ["returnRoot",2] - ]})delim"; - - mockSimpleTestValue_ = true; - - auto root1 = UITemplateProcessor::buildShadowTree( - bytecode, - surfaceId, - folly::dynamic::object(), - *componentDescriptorRegistry, - nativeModuleRegistry, - mockReactNativeConfig_); -#ifndef NDEBUG - LOG(INFO) << std::endl << root1->getDebugDescription(); -#endif - auto props1 = std::static_pointer_cast(root1->getProps()); - ASSERT_STREQ(props1->testId.c_str(), "root"); - auto children1 = root1->getChildren(); - EXPECT_EQ(children1.size(), 1); - auto child_props1 = - std::static_pointer_cast(children1.at(0)->getProps()); - ASSERT_STREQ(child_props1->testId.c_str(), "cond_true"); - - mockSimpleTestValue_ = false; - - auto root2 = UITemplateProcessor::buildShadowTree( - bytecode, - surfaceId, - folly::dynamic::object(), - *componentDescriptorRegistry, - nativeModuleRegistry, - mockReactNativeConfig_); - auto child_props2 = std::static_pointer_cast( - root2->getChildren().at(0)->getProps()); - ASSERT_STREQ(child_props2->testId.c_str(), "cond_false"); -}