mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-04-28 12:15:37 +08:00
Summary:
JSCallInvoker requires a `std::weak_ptr<Instance>` to create. In our C++, `CatalystInstance` is responsible for creating this `Instance` object. This `CatalystInstance` C++ initialization is separate from the `TurboModuleManager` C++ initialization. Therefore, in this diff, I made `CatalystInstance` responsible for creating the `JSCallInvoker`. It then exposes the `JSCallInvoker` using a hybrid class called `JSCallInvokerHolder`, which contains a `std::shared_ptr<JSCallInvoker>` member variable. Using `CatalystInstance.getJSCallInvokerHolder()` in TurboModuleManager.java, we get a handle to this hybrid container. Then, we pass it this hybrid object to `TurboModuleManager::initHybrid`, which retrieves the `std::shared_ptr<JSCallInvoker>` from the `JavaJSCallInvokerHandler`.
There were a few cyclic dependencies, so I had to break down the buck targets:
- `CatalystInstanceImpl.java` depends on `JSCallInvokerHolderImpl.java`, and `TurboModuleManager.java` depends on classes that are packaged with `CatalystInstanceImpl.java`. So, I had to put `JSCallInvokerHolderImpl.java` in its own buck target.
- `CatalystInstance.cpp` depends on `JavaJSCallInvokerHolder.cpp`, and `TurboModuleManager.cpp` depends on classes that are build with `CatalystInstance.cpp`. So, I had to put `JavaJSCallInvokerHolder.cpp` in its own buck target. To make things simpler, I also moved `JSCallInvoker.{cpp,h}` files into the same buck target as `JavaJSCallInvokerHolder.{cpp,h}`.
I think these steps should be enough to create the TurboModuleManager without needing a bridge:
1. Make `JSCallInvoker` an abstract base class.
2. On Android, create another derived class of `JSCallInvoker` that doesn't depend on Instance.
3. Create `JavaJSCallInvokerHolder` using an instance of this new class somewhere in C++.
4. Pass this instance of `JavaJSCallInvokerHolder` to Java and use it to create/instatiate `TurboModuleManager`.
Regarding steps 1 and 2, we can also make JSCallInvoker accept a lambda.
Reviewed By: mdvacca
Differential Revision: D15055511
fbshipit-source-id: 0ad72a86599819ec35d421dbee7e140959a26ab6
69 lines
1.6 KiB
C++
69 lines
1.6 KiB
C++
/**
|
|
* Copyright (c) Facebook, Inc. and its 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 <string>
|
|
#include <unordered_map>
|
|
|
|
#include <jsi/jsi.h>
|
|
|
|
#include <jsireact/JSCallInvoker.h>
|
|
|
|
namespace facebook {
|
|
namespace react {
|
|
|
|
/**
|
|
* For now, support the same set of return types as existing impl.
|
|
* This can be improved to support richer typed objects.
|
|
*/
|
|
enum TurboModuleMethodValueKind {
|
|
VoidKind,
|
|
BooleanKind,
|
|
NumberKind,
|
|
StringKind,
|
|
ObjectKind,
|
|
ArrayKind,
|
|
FunctionKind,
|
|
PromiseKind,
|
|
};
|
|
|
|
/**
|
|
* Base HostObject class for every module to be exposed to JS
|
|
*/
|
|
class JSI_EXPORT TurboModule : public facebook::jsi::HostObject {
|
|
public:
|
|
TurboModule(const std::string &name, std::shared_ptr<JSCallInvoker> jsInvoker);
|
|
virtual ~TurboModule();
|
|
|
|
virtual facebook::jsi::Value get(facebook::jsi::Runtime& runtime, const facebook::jsi::PropNameID& propName) override;
|
|
|
|
const std::string name_;
|
|
std::shared_ptr<JSCallInvoker> jsInvoker_;
|
|
|
|
protected:
|
|
struct MethodMetadata {
|
|
size_t argCount;
|
|
facebook::jsi::Value (*invoker)(
|
|
facebook::jsi::Runtime& rt,
|
|
TurboModule &turboModule,
|
|
const facebook::jsi::Value* args,
|
|
size_t count);
|
|
};
|
|
|
|
std::unordered_map<std::string, MethodMetadata> methodMap_;
|
|
};
|
|
|
|
/**
|
|
* An app/platform-specific provider function to get an instance of a module given a name.
|
|
*/
|
|
using TurboModuleProviderFunctionType = std::function<std::shared_ptr<TurboModule>(
|
|
const std::string &name)>;
|
|
|
|
} // namespace react
|
|
} // namespace facebook
|