diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/CppViewMutationsWrapper.java b/ReactAndroid/src/main/java/com/facebook/react/fabric/CppViewMutationsWrapper.java new file mode 100644 index 00000000000..2df36efac12 --- /dev/null +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/CppViewMutationsWrapper.java @@ -0,0 +1,47 @@ +/* + * 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. + */ + +package com.facebook.react.fabric; + +import android.annotation.SuppressLint; +import com.facebook.jni.HybridData; +import com.facebook.proguard.annotations.DoNotStrip; + +/** + * This class holds reference to the C++ CppViewMutations object. Instances of this class are + * created on the Bindings.cpp, where the pointer to the cppViewMutations is set. + */ +@SuppressLint("MissingNativeLoadLibrary") +public class CppViewMutationsWrapper { + + static { + FabricSoLoader.staticInit(); + } + + @DoNotStrip private final HybridData mHybridData; + + private static native HybridData initHybrid(); + + private CppViewMutationsWrapper() { + mHybridData = initHybrid(); + } + + public native void runCppViewMutations(); + + public synchronized void destroy() { + if (mHybridData != null) { + mHybridData.resetNative(); + } + } + + private boolean isValid() { + if (mHybridData != null) { + return mHybridData.isValid(); + } + return false; + } +} diff --git a/ReactAndroid/src/main/jni/react/fabric/CppViewMutationsWrapper.cpp b/ReactAndroid/src/main/jni/react/fabric/CppViewMutationsWrapper.cpp new file mode 100644 index 00000000000..eb85fae4fe7 --- /dev/null +++ b/ReactAndroid/src/main/jni/react/fabric/CppViewMutationsWrapper.cpp @@ -0,0 +1,100 @@ +/* + * 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 "CppViewMutationsWrapper.h" + +#include + +#include +#include + +using namespace facebook::jni; + +namespace facebook { +namespace react { + +jni::local_ref +CppViewMutationsWrapper::initHybrid(jni::alias_ref) { + return makeCxxInstance(); +} + +void CppViewMutationsWrapper::registerNatives() { + registerHybrid({ + makeNativeMethod("initHybrid", CppViewMutationsWrapper::initHybrid), + makeNativeMethod( + "runCppViewMutations", CppViewMutationsWrapper::runCppViewMutations), + }); +} + +void CppViewMutationsWrapper::runCppViewMutations() { + // TODO implement rendering logic: + // - caching of componengtManagers of views into maps + // - caching of allocated views + // - logic for each mutation instruction + // - Define API in ComponentManager + // - Define API in Component + // - see RCTMountingManager.mm for logic + for (const auto &mutation : *cppViewMutations) { + const auto &newChildShadowView = mutation.newChildShadowView; + auto &mutationType = mutation.type; + auto componentName = newChildShadowView.componentName; + auto tag = mutation.newChildShadowView.tag; + + switch (mutationType) { + case ShadowViewMutation::Create: { + auto component = cppComponentRegistry->createComponentInstance( + componentName, tag, newChildShadowView.props); + break; + } + case ShadowViewMutation::Remove: { + auto parentTag = mutation.parentShadowView.tag; + auto parentComponent = + cppComponentRegistry->getComponentInstance(parentTag); + auto childComponent = cppComponentRegistry->getComponentInstance( + mutation.newChildShadowView.tag); + parentComponent->unmountChildComponent(childComponent, mutation.index); + break; + } + case ShadowViewMutation::Delete: { + cppComponentRegistry->deleteComponentInstance(tag); + break; + } + case ShadowViewMutation::Update: { + auto component = cppComponentRegistry->getComponentInstance(tag); + if (mutation.oldChildShadowView.props != + mutation.newChildShadowView.props) { + component->updateProps( + mutation.oldChildShadowView.props, + mutation.newChildShadowView.props); + } + break; + } + case ShadowViewMutation::Insert: { + auto parentTag = mutation.parentShadowView.tag; + auto parentComponent = + cppComponentRegistry->getComponentInstance(parentTag); + auto childTag = mutation.newChildShadowView.tag; + auto childComponent = + cppComponentRegistry->getComponentInstance(childTag); + auto oldProps = mutation.oldChildShadowView.props; + auto newProps = mutation.newChildShadowView.props; + childComponent->updateProps(oldProps, newProps); + + if (childComponent && parentComponent) { + parentComponent->mountChildComponent(childComponent, mutation.index); + } + break; + } + default: { + break; + } + } + } +} + +} // namespace react +} // namespace facebook diff --git a/ReactAndroid/src/main/jni/react/fabric/CppViewMutationsWrapper.h b/ReactAndroid/src/main/jni/react/fabric/CppViewMutationsWrapper.h new file mode 100644 index 00000000000..6e875b6d647 --- /dev/null +++ b/ReactAndroid/src/main/jni/react/fabric/CppViewMutationsWrapper.h @@ -0,0 +1,39 @@ +/* + * 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 + +namespace facebook { +namespace react { + +class CppViewMutationsWrapper + : public jni::HybridClass { + public: + constexpr static const char *const kJavaDescriptor = + "Lcom/facebook/react/fabric/CppViewMutationsWrapper;"; + + static void registerNatives(); + + // TODO move this to a constructor or init methods + std::shared_ptr cppViewMutations; + + std::shared_ptr cppComponentRegistry; + + void runCppViewMutations(); + + private: + static jni::local_ref initHybrid(jni::alias_ref); +}; + +} // namespace react +} // namespace facebook diff --git a/ReactAndroid/src/main/jni/react/fabric/OnLoad.cpp b/ReactAndroid/src/main/jni/react/fabric/OnLoad.cpp index 7ebf9b5247e..b7825d4bb9f 100644 --- a/ReactAndroid/src/main/jni/react/fabric/OnLoad.cpp +++ b/ReactAndroid/src/main/jni/react/fabric/OnLoad.cpp @@ -10,6 +10,7 @@ #include "Binding.h" #include "ComponentFactory.h" #include "CoreComponentsRegistry.h" +#include "CppViewMutationsWrapper.h" #include "EventBeatManager.h" #include "EventEmitterWrapper.h" #include "StateWrapperImpl.h" @@ -20,6 +21,7 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) { facebook::react::Binding::registerNatives(); facebook::react::EventBeatManager::registerNatives(); facebook::react::EventEmitterWrapper::registerNatives(); + facebook::react::CppViewMutationsWrapper::registerNatives(); facebook::react::StateWrapperImpl::registerNatives(); facebook::react::ComponentFactory::registerNatives(); facebook::react::CoreComponentsRegistry::registerNatives();