Introducing Registry for C++ Components in React Native renderer

Summary:
This diff introduces the APIs that will be used to register C++ components in React Native Renderer for Android

changelog: [internal] internal

Reviewed By: sammy-SC

Differential Revision: D38725768

fbshipit-source-id: a7116b787f83544282230666d9d5acbfb1df4047
This commit is contained in:
David Vacca
2022-09-15 09:48:25 -07:00
committed by Facebook GitHub Bot
parent c74f91957e
commit 53d2f1891e
5 changed files with 263 additions and 0 deletions
@@ -0,0 +1,28 @@
/*
* 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 androidx.annotation.NonNull;
import com.facebook.jni.HybridData;
import com.facebook.proguard.annotations.DoNotStrip;
@DoNotStrip
public class CppComponentRegistry {
static {
FabricSoLoader.staticInit();
}
@NonNull private final HybridData mHybridData;
private static native HybridData initHybrid();
private CppComponentRegistry(HybridData hybridData) {
mHybridData = hybridData;
}
}
@@ -0,0 +1,51 @@
/*
* 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 "ComponentRegistryResolver.h"
#include <android/log.h>
namespace facebook {
namespace react {
void ComponentRegistryResolver::addComponentManager(
std::string name,
bool isRootComponent,
std::function<std::shared_ptr<facebook::react::ComponentManager>(
const std::string &name)> f) {
ComponentResolverData data = {isRootComponent, std::move(f)};
resolverMap_.insert({name, data});
}
bool ComponentRegistryResolver::containsComponentManager(
std::string componentName) const {
return resolverMap_.contains(componentName);
}
std::shared_ptr<facebook::react::ComponentManager>
ComponentRegistryResolver::getComponentManager(
std::string componentName) const {
auto iterator = resolverMap_.find(componentName);
if (iterator != resolverMap_.end()) {
return iterator->second.getComponentManagerFunction(componentName);
}
return nullptr;
}
bool ComponentRegistryResolver::isRootComponent(
std::string componentName) const {
auto iterator = resolverMap_.find(componentName);
if (iterator != resolverMap_.end()) {
return iterator->second.isRootComponent;
}
return false;
}
} // namespace react
} // namespace facebook
@@ -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.
*/
#pragma once
#include <fbjni/fbjni.h>
#include <react/fabric/ComponentManager.h>
namespace facebook {
namespace react {
struct ComponentResolverData {
bool isRootComponent;
std::function<std::shared_ptr<facebook::react::ComponentManager>(
const std::string &name)>
getComponentManagerFunction;
};
using ComponentResolverMap = butter::map<std::string, ComponentResolverData>;
class ComponentRegistryResolver {
public:
ComponentRegistryResolver(){};
void addComponentManager(
std::string name,
bool isRootComponent,
std::function<std::shared_ptr<facebook::react::ComponentManager>(
const std::string &name)> f);
bool containsComponentManager(std::string componentName) const;
bool isRootComponent(std::string componentName) const;
std::shared_ptr<facebook::react::ComponentManager> getComponentManager(
std::string name) const;
private:
butter::map<std::string, ComponentResolverData> resolverMap_{};
};
} // namespace react
} // namespace facebook
@@ -0,0 +1,73 @@
/*
* 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 "CppComponentRegistry.h"
#include <android/log.h>
#include <fbjni/fbjni.h>
#include <jsi/jsi.h>
#include <react/renderer/componentregistry/ComponentDescriptorRegistry.h>
using namespace facebook::jsi;
namespace facebook {
namespace react {
jni::local_ref<CppComponentRegistry::jhybriddata>
CppComponentRegistry::initHybrid(jni::alias_ref<jclass>) {
return makeCxxInstance();
}
void CppComponentRegistry::registerNatives() {
registerHybrid({
makeNativeMethod("initHybrid", CppComponentRegistry::initHybrid),
});
}
void CppComponentRegistry::addComponentManager(
std::string name,
bool isRootComponent,
std::function<std::shared_ptr<facebook::react::ComponentManager>(
const std::string &name)> f) {
componentManagerResolver_.addComponentManager(name, isRootComponent, f);
}
bool CppComponentRegistry::containsComponentManager(std::string name) const {
return componentManagerResolver_.containsComponentManager(name);
}
std::shared_ptr<facebook::react::ComponentManager>
CppComponentRegistry::getComponentManager(const std::string &name) const {
return componentManagerResolver_.getComponentManager(name);
}
std::shared_ptr<facebook::react::Component>
CppComponentRegistry::getComponentInstance(Tag tag) const {
return components_[tag];
}
bool CppComponentRegistry::isRootComponent(std::string name) const {
return componentManagerResolver_.isRootComponent(name);
}
std::shared_ptr<facebook::react::Component>
CppComponentRegistry::createComponentInstance(
const std::string &componentName,
Tag tag,
Props::Shared initialProps) const {
// TODO: cache component managers
auto componentManager = getComponentManager(componentName);
auto component = componentManager->createComponent(tag, initialProps);
components_[tag] = component;
return component;
}
void CppComponentRegistry::deleteComponentInstance(Tag tag) const {
components_.erase(tag);
}
} // namespace react
} // namespace facebook
@@ -0,0 +1,64 @@
/*
* 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 <fbjni/fbjni.h>
#include <glog/logging.h>
#include <jsi/jsi.h>
#include <react/utils/ContextContainer.h>
#include <mutex>
#include <unordered_set>
#include <react/fabric/Component.h>
#include <react/fabric/ComponentManager.h>
#include <react/fabric/ComponentRegistryResolver.h>
namespace facebook {
namespace react {
class Instance;
class CppComponentRegistry : public jni::HybridClass<CppComponentRegistry> {
public:
constexpr static const char *const kJavaDescriptor =
"Lcom/facebook/react/fabric/CppComponentRegistry;";
static void registerNatives();
void addComponentManager(
std::string name,
bool isRootComponent,
std::function<std::shared_ptr<facebook::react::ComponentManager>(
const std::string &name)> f);
bool isRootComponent(std::string name) const;
bool containsComponentManager(std::string name) const;
std::shared_ptr<facebook::react::ComponentManager> getComponentManager(
const std::string &name) const;
std::shared_ptr<facebook::react::Component> getComponentInstance(
Tag tag) const;
std::shared_ptr<facebook::react::Component> createComponentInstance(
const std::string &componentName,
Tag tag,
Props::Shared initialProps) const;
void deleteComponentInstance(Tag tag) const;
private:
static jni::local_ref<jhybriddata> initHybrid(jni::alias_ref<jclass>);
ComponentRegistryResolver componentManagerResolver_{};
mutable butter::map<Tag, std::shared_ptr<facebook::react::Component>>
components_{};
};
} // namespace react
} // namespace facebook