mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
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
This commit is contained in:
committed by
Facebook GitHub Bot
parent
d0f750e15d
commit
1719a072fd
+1
-2
@@ -1237,8 +1237,7 @@ public class ReactInstanceManager {
|
||||
reactRoot.getRootViewGroup(),
|
||||
initialProperties == null
|
||||
? new WritableNativeMap()
|
||||
: Arguments.fromBundle(initialProperties),
|
||||
reactRoot.getInitialUITemplate());
|
||||
: Arguments.fromBundle(initialProperties));
|
||||
reactRoot.setRootViewTag(rootTag);
|
||||
reactRoot.runApplication();
|
||||
}
|
||||
|
||||
+1
-17
@@ -94,7 +94,6 @@ public class ReactRootView extends FrameLayout implements RootView, ReactRoot {
|
||||
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 class ReactRootView extends FrameLayout implements RootView, ReactRoot {
|
||||
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 class ReactRootView extends FrameLayout implements RootView, ReactRoot {
|
||||
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 class ReactRootView extends FrameLayout implements RootView, ReactRoot {
|
||||
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 class ReactRootView extends FrameLayout implements RootView, ReactRoot {
|
||||
return mAppProperties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable String getInitialUITemplate() {
|
||||
return mInitialUITemplate;
|
||||
}
|
||||
|
||||
@ThreadConfined(UI)
|
||||
public void setAppProperties(@Nullable Bundle appProperties) {
|
||||
UiThreadUtil.assertOnUiThread();
|
||||
|
||||
+1
-2
@@ -21,8 +21,7 @@ public interface UIManager extends JSIModule, PerformanceCounter {
|
||||
@UiThread
|
||||
@ThreadConfined(UI)
|
||||
@Deprecated
|
||||
<T extends View> int addRootView(
|
||||
final T rootView, WritableMap initialProps, @Nullable String initialUITemplate);
|
||||
<T extends View> int addRootView(final T rootView, WritableMap initialProps);
|
||||
|
||||
/** Registers a new root view with width and height. */
|
||||
@AnyThread
|
||||
|
||||
-2
@@ -33,8 +33,6 @@ public interface Binding {
|
||||
boolean isRTL,
|
||||
boolean doLeftAndRightSwapInRTL);
|
||||
|
||||
public void renderTemplateToSurface(int surfaceId, String uiTemplate);
|
||||
|
||||
public void stopSurface(int surfaceId);
|
||||
|
||||
public void setPixelDensity(float pointScaleFactor);
|
||||
|
||||
-3
@@ -63,9 +63,6 @@ public class BindingImpl implements Binding {
|
||||
boolean isRTL,
|
||||
boolean doLeftAndRightSwapInRTL);
|
||||
|
||||
@Override
|
||||
public native void renderTemplateToSurface(int surfaceId, String uiTemplate);
|
||||
|
||||
@Override
|
||||
public native void stopSurface(int surfaceId);
|
||||
|
||||
|
||||
+1
-5
@@ -237,8 +237,7 @@ public class FabricUIManager implements UIManager, LifecycleEventListener {
|
||||
@UiThread
|
||||
@ThreadConfined(UI)
|
||||
@Deprecated
|
||||
public <T extends View> int addRootView(
|
||||
final T rootView, final WritableMap initialProps, final @Nullable String initialUITemplate) {
|
||||
public <T extends View> int addRootView(final T rootView, final WritableMap initialProps) {
|
||||
ReactSoftExceptionLogger.logSoftException(
|
||||
TAG,
|
||||
new IllegalViewOperationException(
|
||||
@@ -256,9 +255,6 @@ public class FabricUIManager implements UIManager, LifecycleEventListener {
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
-3
@@ -25,9 +25,6 @@ public interface ReactRoot {
|
||||
@Nullable
|
||||
Bundle getAppProperties();
|
||||
|
||||
@Nullable
|
||||
String getInitialUITemplate();
|
||||
|
||||
String getJSModuleName();
|
||||
|
||||
/** Fabric or Default UI Manager, see {@link UIManagerType} */
|
||||
|
||||
+2
-3
@@ -313,7 +313,7 @@ public class UIManagerModule extends ReactContextBaseJavaModule
|
||||
}
|
||||
|
||||
public <T extends View> int addRootView(final T rootView) {
|
||||
return addRootView(rootView, null, null);
|
||||
return addRootView(rootView, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -341,8 +341,7 @@ public class UIManagerModule extends ReactContextBaseJavaModule
|
||||
* <p>TODO(6242243): Make addRootView thread safe NB: this method is horribly not-thread-safe.
|
||||
*/
|
||||
@Override
|
||||
public <T extends View> int addRootView(
|
||||
final T rootView, WritableMap initialProps, @Nullable String initialUITemplate) {
|
||||
public <T extends View> 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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -88,8 +88,6 @@ class Binding : public jni::HybridClass<Binding>,
|
||||
jboolean isRTL,
|
||||
jboolean doLeftAndRightSwapInRTL);
|
||||
|
||||
void renderTemplateToSurface(jint surfaceId, jstring uiTemplate);
|
||||
|
||||
void stopSurface(jint surfaceId);
|
||||
|
||||
void registerSurface(SurfaceHandlerBinding* surfaceHandler);
|
||||
|
||||
@@ -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
|
||||
|
||||
-27
@@ -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;
|
||||
|
||||
-7
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
#include <react/renderer/mounting/MountingOverrideDelegate.h>
|
||||
#include <react/renderer/mounting/ShadowViewMutation.h>
|
||||
#include <react/renderer/runtimescheduler/RuntimeScheduler.h>
|
||||
#include <react/renderer/templateprocessor/UITemplateProcessor.h>
|
||||
#include <react/renderer/uimanager/UIManager.h>
|
||||
#include <react/renderer/uimanager/UIManagerBinding.h>
|
||||
|
||||
@@ -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<RootShadowNode>(
|
||||
oldRootShadowNode,
|
||||
ShadowNodeFragment{
|
||||
/* .props = */ ShadowNodeFragment::propsPlaceholder(),
|
||||
/* .children = */
|
||||
std::make_shared<ShadowNode::ListOfShared>(
|
||||
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 {
|
||||
|
||||
@@ -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`,
|
||||
|
||||
@@ -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
|
||||
)
|
||||
-153
@@ -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 <folly/json.h>
|
||||
#include <glog/logging.h>
|
||||
#include <react/renderer/components/view/ViewComponentDescriptor.h>
|
||||
#include <react/renderer/components/view/ViewProps.h>
|
||||
#include <react/renderer/components/view/ViewShadowNode.h>
|
||||
#include <react/renderer/core/ComponentDescriptor.h>
|
||||
#include <react/renderer/core/LayoutContext.h>
|
||||
#include <react/renderer/core/ShadowNodeFragment.h>
|
||||
#include <react/renderer/debug/DebugStringConvertible.h>
|
||||
#include <react/renderer/debug/DebugStringConvertibleItem.h>
|
||||
|
||||
namespace facebook::react {
|
||||
|
||||
bool constexpr DEBUG_FLY = false;
|
||||
|
||||
struct RBCContext {
|
||||
const Tag rootTag;
|
||||
const std::vector<ShadowNode::Shared>& nodes;
|
||||
const std::vector<folly::dynamic>& 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<ShadowNode::Shared>& nodes,
|
||||
std::vector<folly::dynamic>& registers,
|
||||
const ComponentDescriptorRegistry& componentDescriptorRegistry,
|
||||
const NativeModuleRegistry& nativeModuleRegistry,
|
||||
const std::shared_ptr<const ReactNativeConfig>& 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<Tag>(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<size_t>(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<Tag>(command[1].asInt())];
|
||||
} else if (opcode == "loadNativeBool") {
|
||||
auto registerNumber = static_cast<size_t>(command[1].asInt());
|
||||
std::string param = command[4][0].asString();
|
||||
registers[registerNumber] = reactNativeConfig->getBool(param);
|
||||
} else if (opcode == "conditional") {
|
||||
auto registerNumber = static_cast<size_t>(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<const ReactNativeConfig>& 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<ShadowNode::Shared> nodes(commands.size() * 2);
|
||||
std::vector<folly::dynamic> 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
|
||||
-64
@@ -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 <memory>
|
||||
|
||||
#include <folly/dynamic.h>
|
||||
|
||||
#include <react/config/ReactNativeConfig.h>
|
||||
#include <react/renderer/componentregistry/ComponentDescriptorRegistry.h>
|
||||
#include <react/renderer/core/ShadowNode.h>
|
||||
#include <react/renderer/uimanager/UIManagerDelegate.h>
|
||||
|
||||
namespace facebook::react {
|
||||
|
||||
// Temporary NativeModuleRegistry definition
|
||||
using NativeModuleCallFn =
|
||||
std::function<folly::dynamic(const std::string&, const folly::dynamic&)>;
|
||||
|
||||
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<std::string, NativeModuleCallFn> 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<const ReactNativeConfig>& reactNativeConfig);
|
||||
|
||||
private:
|
||||
static ShadowNode::Shared runCommand(
|
||||
const folly::dynamic& command,
|
||||
Tag surfaceId,
|
||||
std::vector<ShadowNode::Shared>& nodes,
|
||||
std::vector<folly::dynamic>& registers,
|
||||
const ComponentDescriptorRegistry& componentDescriptorRegistry,
|
||||
const NativeModuleRegistry& nativeModuleRegistry,
|
||||
const std::shared_ptr<const ReactNativeConfig>& reactNativeConfig);
|
||||
};
|
||||
} // namespace facebook::react
|
||||
-166
@@ -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 <exception>
|
||||
|
||||
#include <glog/logging.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include <react/renderer/componentregistry/ComponentDescriptorFactory.h>
|
||||
#include <react/renderer/templateprocessor/UITemplateProcessor.h>
|
||||
|
||||
using namespace facebook::react;
|
||||
|
||||
#include <react/config/ReactNativeConfig.h>
|
||||
#include <react/renderer/componentregistry/ComponentDescriptorFactory.h>
|
||||
#include <react/renderer/componentregistry/ComponentDescriptorProviderRegistry.h>
|
||||
#include <react/renderer/componentregistry/ComponentDescriptorRegistry.h>
|
||||
#include <react/renderer/components/rncore/ComponentDescriptors.h>
|
||||
#include <react/renderer/components/scrollview/ScrollViewComponentDescriptor.h>
|
||||
#include <react/renderer/components/view/ViewComponentDescriptor.h>
|
||||
#include <react/utils/ContextContainer.h>
|
||||
|
||||
namespace facebook::react {
|
||||
|
||||
static ComponentRegistryFactory getComponentRegistryFactory() {
|
||||
return [](const EventDispatcher::Weak& eventDispatcher,
|
||||
const ContextContainer::Shared& contextContainer) {
|
||||
ComponentDescriptorProviderRegistry providerRegistry{};
|
||||
providerRegistry.add(
|
||||
concreteComponentDescriptorProvider<ViewComponentDescriptor>());
|
||||
providerRegistry.add(
|
||||
concreteComponentDescriptorProvider<ScrollViewComponentDescriptor>());
|
||||
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<const ReactNativeConfig> mockReactNativeConfig_ =
|
||||
std::make_shared<const MockReactNativeConfig>();
|
||||
|
||||
} // namespace facebook::react
|
||||
|
||||
TEST(UITemplateProcessorTest, testSimpleBytecode) {
|
||||
auto surfaceId = 11;
|
||||
auto eventDispatcher = std::shared_ptr<const EventDispatcher>();
|
||||
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<const ViewProps>(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<const ViewProps>(children1.at(0)->getProps());
|
||||
ASSERT_STREQ(child_props1->testId.c_str(), "child");
|
||||
}
|
||||
|
||||
TEST(UITemplateProcessorTest, testConditionalBytecode) {
|
||||
auto surfaceId = 11;
|
||||
auto eventDispatcher = std::shared_ptr<const EventDispatcher>();
|
||||
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<const ViewProps>(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<const ViewProps>(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<const ViewProps>(
|
||||
root2->getChildren().at(0)->getProps());
|
||||
ASSERT_STREQ(child_props2->testId.c_str(), "cond_false");
|
||||
}
|
||||
Reference in New Issue
Block a user