clang-format cpp
Summary: Ran `arc f` against some CPP files to be modified with the next diff to reduce the churn on it. ## Changelog [Android] [Changed] - Formatted cpp/h code with clang-format Reviewed By: javache Differential Revision: D19371785 fbshipit-source-id: b7f7b92c4cb9ec7f8da728bb577db29cf11fbb39
This commit is contained in:
Родитель
8d57691a60
Коммит
d5ba113bb2
|
@ -16,9 +16,9 @@
|
||||||
#include <jsi/JSIDynamic.h>
|
#include <jsi/JSIDynamic.h>
|
||||||
#include <jsi/jsi.h>
|
#include <jsi/jsi.h>
|
||||||
#include <react/components/scrollview/ScrollViewProps.h>
|
#include <react/components/scrollview/ScrollViewProps.h>
|
||||||
#include <react/core/conversions.h>
|
|
||||||
#include <react/core/EventBeat.h>
|
#include <react/core/EventBeat.h>
|
||||||
#include <react/core/EventEmitter.h>
|
#include <react/core/EventEmitter.h>
|
||||||
|
#include <react/core/conversions.h>
|
||||||
#include <react/debug/SystraceSection.h>
|
#include <react/debug/SystraceSection.h>
|
||||||
#include <react/uimanager/ComponentDescriptorFactory.h>
|
#include <react/uimanager/ComponentDescriptorFactory.h>
|
||||||
#include <react/uimanager/Scheduler.h>
|
#include <react/uimanager/Scheduler.h>
|
||||||
|
@ -73,7 +73,6 @@ std::shared_ptr<Scheduler> Binding::getScheduler() {
|
||||||
return scheduler_;
|
return scheduler_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Binding::startSurface(
|
void Binding::startSurface(
|
||||||
jint surfaceId,
|
jint surfaceId,
|
||||||
jni::alias_ref<jstring> moduleName,
|
jni::alias_ref<jstring> moduleName,
|
||||||
|
@ -89,7 +88,11 @@ void Binding::startSurface(
|
||||||
LayoutContext context;
|
LayoutContext context;
|
||||||
context.pointScaleFactor = pointScaleFactor_;
|
context.pointScaleFactor = pointScaleFactor_;
|
||||||
scheduler->startSurface(
|
scheduler->startSurface(
|
||||||
surfaceId, moduleName->toStdString(), initialProps->consume(), {}, context);
|
surfaceId,
|
||||||
|
moduleName->toStdString(),
|
||||||
|
initialProps->consume(),
|
||||||
|
{},
|
||||||
|
context);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Binding::startSurfaceWithConstraints(
|
void Binding::startSurfaceWithConstraints(
|
||||||
|
@ -200,10 +203,12 @@ void Binding::installFabricUIManager(
|
||||||
LOG(WARNING) << "Binding::installFabricUIManager() was called (address: "
|
LOG(WARNING) << "Binding::installFabricUIManager() was called (address: "
|
||||||
<< this << ").";
|
<< this << ").";
|
||||||
|
|
||||||
// Use std::lock and std::adopt_lock to prevent deadlocks by locking mutexes at the same time
|
// Use std::lock and std::adopt_lock to prevent deadlocks by locking mutexes
|
||||||
|
// at the same time
|
||||||
std::lock(schedulerMutex_, javaUIManagerMutex_);
|
std::lock(schedulerMutex_, javaUIManagerMutex_);
|
||||||
std::lock_guard<std::mutex> schedulerLock(schedulerMutex_, std::adopt_lock);
|
std::lock_guard<std::mutex> schedulerLock(schedulerMutex_, std::adopt_lock);
|
||||||
std::lock_guard<std::mutex> uiManagerLock(javaUIManagerMutex_, std::adopt_lock);
|
std::lock_guard<std::mutex> uiManagerLock(
|
||||||
|
javaUIManagerMutex_, std::adopt_lock);
|
||||||
|
|
||||||
javaUIManager_ = make_global(javaUIManager);
|
javaUIManager_ = make_global(javaUIManager);
|
||||||
|
|
||||||
|
@ -226,13 +231,15 @@ void Binding::installFabricUIManager(
|
||||||
// TODO: T31905686 Create synchronous Event Beat
|
// TODO: T31905686 Create synchronous Event Beat
|
||||||
jni::global_ref<jobject> localJavaUIManager = javaUIManager_;
|
jni::global_ref<jobject> localJavaUIManager = javaUIManager_;
|
||||||
EventBeat::Factory synchronousBeatFactory =
|
EventBeat::Factory synchronousBeatFactory =
|
||||||
[eventBeatManager, runtimeExecutor, localJavaUIManager](EventBeat::SharedOwnerBox const &ownerBox) {
|
[eventBeatManager, runtimeExecutor, localJavaUIManager](
|
||||||
|
EventBeat::SharedOwnerBox const &ownerBox) {
|
||||||
return std::make_unique<AsyncEventBeat>(
|
return std::make_unique<AsyncEventBeat>(
|
||||||
ownerBox, eventBeatManager, runtimeExecutor, localJavaUIManager);
|
ownerBox, eventBeatManager, runtimeExecutor, localJavaUIManager);
|
||||||
};
|
};
|
||||||
|
|
||||||
EventBeat::Factory asynchronousBeatFactory =
|
EventBeat::Factory asynchronousBeatFactory =
|
||||||
[eventBeatManager, runtimeExecutor, localJavaUIManager](EventBeat::SharedOwnerBox const &ownerBox) {
|
[eventBeatManager, runtimeExecutor, localJavaUIManager](
|
||||||
|
EventBeat::SharedOwnerBox const &ownerBox) {
|
||||||
return std::make_unique<AsyncEventBeat>(
|
return std::make_unique<AsyncEventBeat>(
|
||||||
ownerBox, eventBeatManager, runtimeExecutor, localJavaUIManager);
|
ownerBox, eventBeatManager, runtimeExecutor, localJavaUIManager);
|
||||||
};
|
};
|
||||||
|
@ -244,12 +251,14 @@ void Binding::installFabricUIManager(
|
||||||
|
|
||||||
// Keep reference to config object and cache some feature flags here
|
// Keep reference to config object and cache some feature flags here
|
||||||
reactNativeConfig_ = config;
|
reactNativeConfig_ = config;
|
||||||
shouldCollateRemovesAndDeletes_ = reactNativeConfig_->getBool("react_fabric:enable_removedelete_collation_android");
|
shouldCollateRemovesAndDeletes_ = reactNativeConfig_->getBool(
|
||||||
|
"react_fabric:enable_removedelete_collation_android");
|
||||||
collapseDeleteCreateMountingInstructions_ = reactNativeConfig_->getBool(
|
collapseDeleteCreateMountingInstructions_ = reactNativeConfig_->getBool(
|
||||||
"react_fabric:enabled_collapse_delete_create_mounting_instructions");
|
"react_fabric:enabled_collapse_delete_create_mounting_instructions");
|
||||||
;
|
;
|
||||||
|
|
||||||
disablePreallocateViews_ = reactNativeConfig_->getBool("react_fabric:disabled_view_preallocation_android");
|
disablePreallocateViews_ = reactNativeConfig_->getBool(
|
||||||
|
"react_fabric:disabled_view_preallocation_android");
|
||||||
|
|
||||||
auto toolbox = SchedulerToolbox{};
|
auto toolbox = SchedulerToolbox{};
|
||||||
toolbox.contextContainer = contextContainer;
|
toolbox.contextContainer = contextContainer;
|
||||||
|
@ -263,10 +272,12 @@ void Binding::installFabricUIManager(
|
||||||
void Binding::uninstallFabricUIManager() {
|
void Binding::uninstallFabricUIManager() {
|
||||||
LOG(WARNING) << "Binding::uninstallFabricUIManager() was called (address: "
|
LOG(WARNING) << "Binding::uninstallFabricUIManager() was called (address: "
|
||||||
<< this << ").";
|
<< this << ").";
|
||||||
// Use std::lock and std::adopt_lock to prevent deadlocks by locking mutexes at the same time
|
// Use std::lock and std::adopt_lock to prevent deadlocks by locking mutexes
|
||||||
|
// at the same time
|
||||||
std::lock(schedulerMutex_, javaUIManagerMutex_);
|
std::lock(schedulerMutex_, javaUIManagerMutex_);
|
||||||
std::lock_guard<std::mutex> schedulerLock(schedulerMutex_, std::adopt_lock);
|
std::lock_guard<std::mutex> schedulerLock(schedulerMutex_, std::adopt_lock);
|
||||||
std::lock_guard<std::mutex> uiManagerLock(javaUIManagerMutex_, std::adopt_lock);
|
std::lock_guard<std::mutex> uiManagerLock(
|
||||||
|
javaUIManagerMutex_, std::adopt_lock);
|
||||||
|
|
||||||
scheduler_ = nullptr;
|
scheduler_ = nullptr;
|
||||||
javaUIManager_ = nullptr;
|
javaUIManager_ = nullptr;
|
||||||
|
@ -279,8 +290,9 @@ inline local_ref<ReadableMap::javaobject> castReadableMap(
|
||||||
}
|
}
|
||||||
|
|
||||||
inline local_ref<ReadableArray::javaobject> castReadableArray(
|
inline local_ref<ReadableArray::javaobject> castReadableArray(
|
||||||
local_ref<ReadableNativeArray::javaobject> nativeArray) {
|
local_ref<ReadableNativeArray::javaobject> nativeArray) {
|
||||||
return make_local(reinterpret_cast<ReadableArray::javaobject>(nativeArray.get()));
|
return make_local(
|
||||||
|
reinterpret_cast<ReadableArray::javaobject>(nativeArray.get()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: this method will be removed when binding for components are code-gen
|
// TODO: this method will be removed when binding for components are code-gen
|
||||||
|
@ -351,8 +363,8 @@ local_ref<JMountItem::javaobject> createUpdateLayoutMountItem(
|
||||||
oldChildShadowView.layoutMetrics != newChildShadowView.layoutMetrics) {
|
oldChildShadowView.layoutMetrics != newChildShadowView.layoutMetrics) {
|
||||||
static auto updateLayoutInstruction =
|
static auto updateLayoutInstruction =
|
||||||
jni::findClassStatic(UIManagerJavaDescriptor)
|
jni::findClassStatic(UIManagerJavaDescriptor)
|
||||||
->getMethod<alias_ref<JMountItem>(jint, jint, jint, jint, jint, jint)>(
|
->getMethod<alias_ref<JMountItem>(
|
||||||
"updateLayoutMountItem");
|
jint, jint, jint, jint, jint, jint)>("updateLayoutMountItem");
|
||||||
auto layoutMetrics = newChildShadowView.layoutMetrics;
|
auto layoutMetrics = newChildShadowView.layoutMetrics;
|
||||||
auto pointScaleFactor = layoutMetrics.pointScaleFactor;
|
auto pointScaleFactor = layoutMetrics.pointScaleFactor;
|
||||||
auto frame = layoutMetrics.frame;
|
auto frame = layoutMetrics.frame;
|
||||||
|
@ -361,7 +373,8 @@ local_ref<JMountItem::javaobject> createUpdateLayoutMountItem(
|
||||||
int y = round(frame.origin.y * pointScaleFactor);
|
int y = round(frame.origin.y * pointScaleFactor);
|
||||||
int w = round(frame.size.width * pointScaleFactor);
|
int w = round(frame.size.width * pointScaleFactor);
|
||||||
int h = round(frame.size.height * pointScaleFactor);
|
int h = round(frame.size.height * pointScaleFactor);
|
||||||
auto layoutDirection = toInt(newChildShadowView.layoutMetrics.layoutDirection);
|
auto layoutDirection =
|
||||||
|
toInt(newChildShadowView.layoutMetrics.layoutDirection);
|
||||||
return updateLayoutInstruction(
|
return updateLayoutInstruction(
|
||||||
javaUIManager, newChildShadowView.tag, x, y, w, h, layoutDirection);
|
javaUIManager, newChildShadowView.tag, x, y, w, h, layoutDirection);
|
||||||
}
|
}
|
||||||
|
@ -370,20 +383,20 @@ local_ref<JMountItem::javaobject> createUpdateLayoutMountItem(
|
||||||
}
|
}
|
||||||
|
|
||||||
local_ref<JMountItem::javaobject> createUpdatePaddingMountItem(
|
local_ref<JMountItem::javaobject> createUpdatePaddingMountItem(
|
||||||
const jni::global_ref<jobject> &javaUIManager,
|
const jni::global_ref<jobject> &javaUIManager,
|
||||||
const ShadowViewMutation &mutation) {
|
const ShadowViewMutation &mutation) {
|
||||||
|
|
||||||
auto oldChildShadowView = mutation.oldChildShadowView;
|
auto oldChildShadowView = mutation.oldChildShadowView;
|
||||||
auto newChildShadowView = mutation.newChildShadowView;
|
auto newChildShadowView = mutation.newChildShadowView;
|
||||||
|
|
||||||
if (oldChildShadowView.layoutMetrics.contentInsets == newChildShadowView.layoutMetrics.contentInsets) {
|
if (oldChildShadowView.layoutMetrics.contentInsets ==
|
||||||
|
newChildShadowView.layoutMetrics.contentInsets) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static auto updateLayoutInstruction =
|
static auto updateLayoutInstruction =
|
||||||
jni::findClassStatic(UIManagerJavaDescriptor)
|
jni::findClassStatic(UIManagerJavaDescriptor)
|
||||||
->getMethod<alias_ref<JMountItem>(jint, jint, jint, jint, jint)>(
|
->getMethod<alias_ref<JMountItem>(jint, jint, jint, jint, jint)>(
|
||||||
"updatePaddingMountItem");
|
"updatePaddingMountItem");
|
||||||
|
|
||||||
auto layoutMetrics = newChildShadowView.layoutMetrics;
|
auto layoutMetrics = newChildShadowView.layoutMetrics;
|
||||||
auto pointScaleFactor = layoutMetrics.pointScaleFactor;
|
auto pointScaleFactor = layoutMetrics.pointScaleFactor;
|
||||||
|
@ -394,7 +407,8 @@ local_ref<JMountItem::javaobject> createUpdatePaddingMountItem(
|
||||||
int right = round(contentInsets.right * pointScaleFactor);
|
int right = round(contentInsets.right * pointScaleFactor);
|
||||||
int bottom = round(contentInsets.bottom * pointScaleFactor);
|
int bottom = round(contentInsets.bottom * pointScaleFactor);
|
||||||
|
|
||||||
return updateLayoutInstruction(javaUIManager, newChildShadowView.tag, left, top, right, bottom);
|
return updateLayoutInstruction(
|
||||||
|
javaUIManager, newChildShadowView.tag, left, top, right, bottom);
|
||||||
}
|
}
|
||||||
|
|
||||||
local_ref<JMountItem::javaobject> createInsertMountItem(
|
local_ref<JMountItem::javaobject> createInsertMountItem(
|
||||||
|
@ -439,9 +453,9 @@ local_ref<JMountItem::javaobject> createUpdateStateMountItem(
|
||||||
const jni::global_ref<jobject> &javaUIManager,
|
const jni::global_ref<jobject> &javaUIManager,
|
||||||
const ShadowViewMutation &mutation) {
|
const ShadowViewMutation &mutation) {
|
||||||
static auto updateStateInstruction =
|
static auto updateStateInstruction =
|
||||||
jni::findClassStatic(UIManagerJavaDescriptor)
|
jni::findClassStatic(UIManagerJavaDescriptor)
|
||||||
->getMethod<alias_ref<JMountItem>(jint, jobject)>(
|
->getMethod<alias_ref<JMountItem>(jint, jobject)>(
|
||||||
"updateStateMountItem");
|
"updateStateMountItem");
|
||||||
|
|
||||||
auto state = mutation.newChildShadowView.state;
|
auto state = mutation.newChildShadowView.state;
|
||||||
|
|
||||||
|
@ -456,9 +470,9 @@ local_ref<JMountItem::javaobject> createUpdateStateMountItem(
|
||||||
}
|
}
|
||||||
|
|
||||||
return updateStateInstruction(
|
return updateStateInstruction(
|
||||||
javaUIManager,
|
javaUIManager,
|
||||||
mutation.newChildShadowView.tag,
|
mutation.newChildShadowView.tag,
|
||||||
(javaStateWrapper != nullptr ? javaStateWrapper.get() : nullptr));
|
(javaStateWrapper != nullptr ? javaStateWrapper.get() : nullptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
local_ref<JMountItem::javaobject> createRemoveMountItem(
|
local_ref<JMountItem::javaobject> createRemoveMountItem(
|
||||||
|
@ -487,14 +501,13 @@ local_ref<JMountItem::javaobject> createDeleteMountItem(
|
||||||
}
|
}
|
||||||
|
|
||||||
local_ref<JMountItem::javaobject> createRemoveAndDeleteMultiMountItem(
|
local_ref<JMountItem::javaobject> createRemoveAndDeleteMultiMountItem(
|
||||||
const jni::global_ref<jobject> &javaUIManager,
|
const jni::global_ref<jobject> &javaUIManager,
|
||||||
const std::vector<RemoveDeleteMetadata> &metadata) {
|
const std::vector<RemoveDeleteMetadata> &metadata) {
|
||||||
|
|
||||||
auto env = Environment::current();
|
auto env = Environment::current();
|
||||||
auto removeAndDeleteArray = env->NewIntArray(metadata.size()*4);
|
auto removeAndDeleteArray = env->NewIntArray(metadata.size() * 4);
|
||||||
int position = 0;
|
int position = 0;
|
||||||
jint temp[4];
|
jint temp[4];
|
||||||
for (const auto& x : metadata) {
|
for (const auto &x : metadata) {
|
||||||
temp[0] = x.tag;
|
temp[0] = x.tag;
|
||||||
temp[1] = x.parentTag;
|
temp[1] = x.parentTag;
|
||||||
temp[2] = x.index;
|
temp[2] = x.index;
|
||||||
|
@ -504,30 +517,34 @@ local_ref<JMountItem::javaobject> createRemoveAndDeleteMultiMountItem(
|
||||||
}
|
}
|
||||||
|
|
||||||
static auto removeDeleteMultiInstruction =
|
static auto removeDeleteMultiInstruction =
|
||||||
jni::findClassStatic(UIManagerJavaDescriptor)
|
jni::findClassStatic(UIManagerJavaDescriptor)
|
||||||
->getMethod<alias_ref<JMountItem>(jintArray)>("removeDeleteMultiMountItem");
|
->getMethod<alias_ref<JMountItem>(jintArray)>(
|
||||||
|
"removeDeleteMultiMountItem");
|
||||||
|
|
||||||
auto ret = removeDeleteMultiInstruction(javaUIManager, removeAndDeleteArray);
|
auto ret = removeDeleteMultiInstruction(javaUIManager, removeAndDeleteArray);
|
||||||
|
|
||||||
// It is not strictly necessary to manually delete the ref here, in this particular case.
|
// It is not strictly necessary to manually delete the ref here, in this
|
||||||
// If JNI memory is being allocated in a loop, it's easy to overload the localref table
|
// particular case. If JNI memory is being allocated in a loop, it's easy to
|
||||||
// and crash; this is not possible in this case since the JNI would automatically clear this
|
// overload the localref table and crash; this is not possible in this case
|
||||||
// ref when it goes out of scope, anyway. However, this is being left here as a reminder of
|
// since the JNI would automatically clear this ref when it goes out of scope,
|
||||||
// good hygiene and to be careful with JNI-allocated memory in general.
|
// anyway. However, this is being left here as a reminder of good hygiene and
|
||||||
|
// to be careful with JNI-allocated memory in general.
|
||||||
env->DeleteLocalRef(removeAndDeleteArray);
|
env->DeleteLocalRef(removeAndDeleteArray);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO T48019320: because we pass initial props and state to the Create (and preallocate) mount instruction,
|
// TODO T48019320: because we pass initial props and state to the Create (and
|
||||||
// we technically don't need to pass the first Update to any components. Dedupe?
|
// preallocate) mount instruction, we technically don't need to pass the first
|
||||||
|
// Update to any components. Dedupe?
|
||||||
local_ref<JMountItem::javaobject> createCreateMountItem(
|
local_ref<JMountItem::javaobject> createCreateMountItem(
|
||||||
const jni::global_ref<jobject> &javaUIManager,
|
const jni::global_ref<jobject> &javaUIManager,
|
||||||
const ShadowViewMutation &mutation,
|
const ShadowViewMutation &mutation,
|
||||||
const Tag surfaceId) {
|
const Tag surfaceId) {
|
||||||
static auto createJavaInstruction =
|
static auto createJavaInstruction =
|
||||||
jni::findClassStatic(UIManagerJavaDescriptor)
|
jni::findClassStatic(UIManagerJavaDescriptor)
|
||||||
->getMethod<alias_ref<JMountItem>(jstring, ReadableMap::javaobject, jobject, jint, jint, jboolean)>(
|
->getMethod<alias_ref<JMountItem>(
|
||||||
|
jstring, ReadableMap::javaobject, jobject, jint, jint, jboolean)>(
|
||||||
"createMountItem");
|
"createMountItem");
|
||||||
|
|
||||||
auto newChildShadowView = mutation.newChildShadowView;
|
auto newChildShadowView = mutation.newChildShadowView;
|
||||||
|
@ -539,7 +556,7 @@ local_ref<JMountItem::javaobject> createCreateMountItem(
|
||||||
newChildShadowView.layoutMetrics != EmptyLayoutMetrics;
|
newChildShadowView.layoutMetrics != EmptyLayoutMetrics;
|
||||||
|
|
||||||
local_ref<ReadableMap::javaobject> props = castReadableMap(
|
local_ref<ReadableMap::javaobject> props = castReadableMap(
|
||||||
ReadableNativeMap::newObjectCxxArgs(newChildShadowView.props->rawProps));
|
ReadableNativeMap::newObjectCxxArgs(newChildShadowView.props->rawProps));
|
||||||
|
|
||||||
// Do not hold onto Java object from C
|
// Do not hold onto Java object from C
|
||||||
// We DO want to hold onto C object from Java, since we don't know the
|
// We DO want to hold onto C object from Java, since we don't know the
|
||||||
|
@ -570,7 +587,8 @@ void Binding::schedulerDidFinishTransaction(
|
||||||
|
|
||||||
jni::global_ref<jobject> localJavaUIManager = getJavaUIManager();
|
jni::global_ref<jobject> localJavaUIManager = getJavaUIManager();
|
||||||
if (!localJavaUIManager) {
|
if (!localJavaUIManager) {
|
||||||
LOG(ERROR) << "Binding::schedulerDidFinishTransaction: JavaUIManager disappeared";
|
LOG(ERROR)
|
||||||
|
<< "Binding::schedulerDidFinishTransaction: JavaUIManager disappeared";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -651,16 +669,20 @@ void Binding::schedulerDidFinishTransaction(
|
||||||
oldChildShadowView.layoutMetrics == EmptyLayoutMetrics;
|
oldChildShadowView.layoutMetrics == EmptyLayoutMetrics;
|
||||||
|
|
||||||
// Handle accumulated removals/deletions
|
// Handle accumulated removals/deletions
|
||||||
if (shouldCollateRemovesAndDeletes_ && mutation.type != ShadowViewMutation::Remove && mutation.type != ShadowViewMutation::Delete) {
|
if (shouldCollateRemovesAndDeletes_ &&
|
||||||
|
mutation.type != ShadowViewMutation::Remove &&
|
||||||
|
mutation.type != ShadowViewMutation::Delete) {
|
||||||
if (toRemove.size() > 0) {
|
if (toRemove.size() > 0) {
|
||||||
mountItems[position++] = createRemoveAndDeleteMultiMountItem(localJavaUIManager, toRemove);
|
mountItems[position++] =
|
||||||
|
createRemoveAndDeleteMultiMountItem(localJavaUIManager, toRemove);
|
||||||
toRemove.clear();
|
toRemove.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (mutation.type) {
|
switch (mutation.type) {
|
||||||
case ShadowViewMutation::Create: {
|
case ShadowViewMutation::Create: {
|
||||||
if (disablePreallocateViews_ || mutation.newChildShadowView.props->revision > 1 ||
|
if (disablePreallocateViews_ ||
|
||||||
|
mutation.newChildShadowView.props->revision > 1 ||
|
||||||
deletedViewTags.find(mutation.newChildShadowView.tag) !=
|
deletedViewTags.find(mutation.newChildShadowView.tag) !=
|
||||||
deletedViewTags.end()) {
|
deletedViewTags.end()) {
|
||||||
mountItems[position++] =
|
mountItems[position++] =
|
||||||
|
@ -671,9 +693,15 @@ void Binding::schedulerDidFinishTransaction(
|
||||||
case ShadowViewMutation::Remove: {
|
case ShadowViewMutation::Remove: {
|
||||||
if (!isVirtual) {
|
if (!isVirtual) {
|
||||||
if (shouldCollateRemovesAndDeletes_) {
|
if (shouldCollateRemovesAndDeletes_) {
|
||||||
toRemove.push_back(RemoveDeleteMetadata{mutation.oldChildShadowView.tag, mutation.parentShadowView.tag, mutation.index, true, false});
|
toRemove.push_back(
|
||||||
|
RemoveDeleteMetadata{mutation.oldChildShadowView.tag,
|
||||||
|
mutation.parentShadowView.tag,
|
||||||
|
mutation.index,
|
||||||
|
true,
|
||||||
|
false});
|
||||||
} else {
|
} else {
|
||||||
mountItems[position++] = createRemoveMountItem(localJavaUIManager, mutation);
|
mountItems[position++] =
|
||||||
|
createRemoveMountItem(localJavaUIManager, mutation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -681,15 +709,22 @@ void Binding::schedulerDidFinishTransaction(
|
||||||
case ShadowViewMutation::Delete: {
|
case ShadowViewMutation::Delete: {
|
||||||
if (shouldCollateRemovesAndDeletes_) {
|
if (shouldCollateRemovesAndDeletes_) {
|
||||||
// It is impossible to delete without removing node first
|
// It is impossible to delete without removing node first
|
||||||
const auto& it = std::find_if(std::begin(toRemove), std::end(toRemove), [&mutation](const auto& x) { return x.tag == mutation.oldChildShadowView.tag; });
|
const auto &it = std::find_if(
|
||||||
|
std::begin(toRemove),
|
||||||
|
std::end(toRemove),
|
||||||
|
[&mutation](const auto &x) {
|
||||||
|
return x.tag == mutation.oldChildShadowView.tag;
|
||||||
|
});
|
||||||
|
|
||||||
if (it != std::end(toRemove)) {
|
if (it != std::end(toRemove)) {
|
||||||
it->shouldDelete = true;
|
it->shouldDelete = true;
|
||||||
} else {
|
} else {
|
||||||
toRemove.push_back(RemoveDeleteMetadata{mutation.oldChildShadowView.tag, -1, -1, false, true});
|
toRemove.push_back(RemoveDeleteMetadata{
|
||||||
|
mutation.oldChildShadowView.tag, -1, -1, false, true});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
mountItems[position++] = createDeleteMountItem(localJavaUIManager, mutation);
|
mountItems[position++] =
|
||||||
|
createDeleteMountItem(localJavaUIManager, mutation);
|
||||||
}
|
}
|
||||||
|
|
||||||
deletedViewTags.insert(mutation.oldChildShadowView.tag);
|
deletedViewTags.insert(mutation.oldChildShadowView.tag);
|
||||||
|
@ -719,7 +754,8 @@ void Binding::schedulerDidFinishTransaction(
|
||||||
mountItems[position++] = updateLayoutMountItem;
|
mountItems[position++] = updateLayoutMountItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto updatePaddingMountItem = createUpdatePaddingMountItem(localJavaUIManager, mutation);
|
auto updatePaddingMountItem =
|
||||||
|
createUpdatePaddingMountItem(localJavaUIManager, mutation);
|
||||||
if (updatePaddingMountItem) {
|
if (updatePaddingMountItem) {
|
||||||
mountItems[position++] = updatePaddingMountItem;
|
mountItems[position++] = updatePaddingMountItem;
|
||||||
}
|
}
|
||||||
|
@ -741,7 +777,8 @@ void Binding::schedulerDidFinishTransaction(
|
||||||
mountItems[position++] =
|
mountItems[position++] =
|
||||||
createInsertMountItem(localJavaUIManager, mutation);
|
createInsertMountItem(localJavaUIManager, mutation);
|
||||||
|
|
||||||
if (disablePreallocateViews_ || mutation.newChildShadowView.props->revision > 1 ||
|
if (disablePreallocateViews_ ||
|
||||||
|
mutation.newChildShadowView.props->revision > 1 ||
|
||||||
deletedViewTags.find(mutation.newChildShadowView.tag) !=
|
deletedViewTags.find(mutation.newChildShadowView.tag) !=
|
||||||
deletedViewTags.end()) {
|
deletedViewTags.end()) {
|
||||||
mountItems[position++] =
|
mountItems[position++] =
|
||||||
|
@ -769,7 +806,7 @@ void Binding::schedulerDidFinishTransaction(
|
||||||
|
|
||||||
// Padding
|
// Padding
|
||||||
auto updatePaddingMountItem =
|
auto updatePaddingMountItem =
|
||||||
createUpdatePaddingMountItem(localJavaUIManager, mutation);
|
createUpdatePaddingMountItem(localJavaUIManager, mutation);
|
||||||
if (updatePaddingMountItem) {
|
if (updatePaddingMountItem) {
|
||||||
mountItems[position++] = updatePaddingMountItem;
|
mountItems[position++] = updatePaddingMountItem;
|
||||||
}
|
}
|
||||||
|
@ -792,12 +829,14 @@ void Binding::schedulerDidFinishTransaction(
|
||||||
|
|
||||||
// Handle remaining removals and deletions
|
// Handle remaining removals and deletions
|
||||||
if (shouldCollateRemovesAndDeletes_ && toRemove.size() > 0) {
|
if (shouldCollateRemovesAndDeletes_ && toRemove.size() > 0) {
|
||||||
mountItems[position++] = createRemoveAndDeleteMultiMountItem(localJavaUIManager, toRemove);
|
mountItems[position++] =
|
||||||
|
createRemoveAndDeleteMultiMountItem(localJavaUIManager, toRemove);
|
||||||
toRemove.clear();
|
toRemove.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (position <= 0) {
|
if (position <= 0) {
|
||||||
// If there are no mountItems to be sent to the platform, then it is not necessary to even call.
|
// If there are no mountItems to be sent to the platform, then it is not
|
||||||
|
// necessary to even call.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -810,10 +849,17 @@ void Binding::schedulerDidFinishTransaction(
|
||||||
auto batch = createMountItemsBatchContainer(
|
auto batch = createMountItemsBatchContainer(
|
||||||
localJavaUIManager, mountItemsArray.get(), position, commitNumber);
|
localJavaUIManager, mountItemsArray.get(), position, commitNumber);
|
||||||
|
|
||||||
static auto scheduleMountItem =
|
static auto scheduleMountItem = jni::findClassStatic(UIManagerJavaDescriptor)
|
||||||
jni::findClassStatic(UIManagerJavaDescriptor)
|
->getMethod<void(
|
||||||
->getMethod<void(JMountItem::javaobject, jint, jlong, jlong, jlong, jlong, jlong, jlong, jlong)>(
|
JMountItem::javaobject,
|
||||||
"scheduleMountItem");
|
jint,
|
||||||
|
jlong,
|
||||||
|
jlong,
|
||||||
|
jlong,
|
||||||
|
jlong,
|
||||||
|
jlong,
|
||||||
|
jlong,
|
||||||
|
jlong)>("scheduleMountItem");
|
||||||
|
|
||||||
long finishTransactionEndTime = monotonicTimeInMilliseconds();
|
long finishTransactionEndTime = monotonicTimeInMilliseconds();
|
||||||
|
|
||||||
|
@ -837,14 +883,14 @@ void Binding::setPixelDensity(float pointScaleFactor) {
|
||||||
void Binding::schedulerDidRequestPreliminaryViewAllocation(
|
void Binding::schedulerDidRequestPreliminaryViewAllocation(
|
||||||
const SurfaceId surfaceId,
|
const SurfaceId surfaceId,
|
||||||
const ShadowView &shadowView) {
|
const ShadowView &shadowView) {
|
||||||
|
|
||||||
if (disablePreallocateViews_) {
|
if (disablePreallocateViews_) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
jni::global_ref<jobject> localJavaUIManager = getJavaUIManager();
|
jni::global_ref<jobject> localJavaUIManager = getJavaUIManager();
|
||||||
if (!localJavaUIManager) {
|
if (!localJavaUIManager) {
|
||||||
LOG(ERROR) << "Binding::schedulerDidRequestPreliminaryViewAllocation: JavaUIManager disappeared";
|
LOG(ERROR)
|
||||||
|
<< "Binding::schedulerDidRequestPreliminaryViewAllocation: JavaUIManager disappeared";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -881,28 +927,28 @@ void Binding::schedulerDidRequestPreliminaryViewAllocation(
|
||||||
}
|
}
|
||||||
|
|
||||||
void Binding::schedulerDidDispatchCommand(
|
void Binding::schedulerDidDispatchCommand(
|
||||||
const ShadowView &shadowView,
|
const ShadowView &shadowView,
|
||||||
std::string const &commandName,
|
std::string const &commandName,
|
||||||
folly::dynamic const args) {
|
folly::dynamic const args) {
|
||||||
|
|
||||||
jni::global_ref<jobject> localJavaUIManager = getJavaUIManager();
|
jni::global_ref<jobject> localJavaUIManager = getJavaUIManager();
|
||||||
if (!localJavaUIManager) {
|
if (!localJavaUIManager) {
|
||||||
LOG(ERROR) << "Binding::schedulerDidDispatchCommand: JavaUIManager disappeared";
|
LOG(ERROR)
|
||||||
|
<< "Binding::schedulerDidDispatchCommand: JavaUIManager disappeared";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static auto dispatchCommand =
|
static auto dispatchCommand =
|
||||||
jni::findClassStatic(UIManagerJavaDescriptor)
|
jni::findClassStatic(UIManagerJavaDescriptor)
|
||||||
->getMethod<void(
|
->getMethod<void(jint, jstring, ReadableArray::javaobject)>(
|
||||||
jint, jstring, ReadableArray::javaobject)>(
|
"dispatchCommand");
|
||||||
"dispatchCommand");
|
|
||||||
|
|
||||||
local_ref<JString> command = make_jstring(commandName);
|
local_ref<JString> command = make_jstring(commandName);
|
||||||
|
|
||||||
local_ref<ReadableArray::javaobject> argsArray = castReadableArray(
|
local_ref<ReadableArray::javaobject> argsArray =
|
||||||
ReadableNativeArray::newObjectCxxArgs(args));
|
castReadableArray(ReadableNativeArray::newObjectCxxArgs(args));
|
||||||
|
|
||||||
dispatchCommand(localJavaUIManager, shadowView.tag, command.get(), argsArray.get());
|
dispatchCommand(
|
||||||
|
localJavaUIManager, shadowView.tag, command.get(), argsArray.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Binding::schedulerDidSetJSResponder(
|
void Binding::schedulerDidSetJSResponder(
|
||||||
|
@ -910,7 +956,6 @@ void Binding::schedulerDidSetJSResponder(
|
||||||
const ShadowView &shadowView,
|
const ShadowView &shadowView,
|
||||||
const ShadowView &initialShadowView,
|
const ShadowView &initialShadowView,
|
||||||
bool blockNativeResponder) {
|
bool blockNativeResponder) {
|
||||||
|
|
||||||
jni::global_ref<jobject> localJavaUIManager = getJavaUIManager();
|
jni::global_ref<jobject> localJavaUIManager = getJavaUIManager();
|
||||||
if (!localJavaUIManager) {
|
if (!localJavaUIManager) {
|
||||||
LOG(ERROR) << "Binding::schedulerSetJSResponder: JavaUIManager disappeared";
|
LOG(ERROR) << "Binding::schedulerSetJSResponder: JavaUIManager disappeared";
|
||||||
|
@ -919,23 +964,25 @@ void Binding::schedulerDidSetJSResponder(
|
||||||
|
|
||||||
static auto setJSResponder =
|
static auto setJSResponder =
|
||||||
jni::findClassStatic(UIManagerJavaDescriptor)
|
jni::findClassStatic(UIManagerJavaDescriptor)
|
||||||
->getMethod<void(
|
->getMethod<void(jint, jint, jboolean)>("setJSResponder");
|
||||||
jint, jint, jboolean)>(
|
|
||||||
"setJSResponder");
|
|
||||||
|
|
||||||
setJSResponder(localJavaUIManager, shadowView.tag, initialShadowView.tag, (jboolean) blockNativeResponder);
|
setJSResponder(
|
||||||
|
localJavaUIManager,
|
||||||
|
shadowView.tag,
|
||||||
|
initialShadowView.tag,
|
||||||
|
(jboolean)blockNativeResponder);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Binding::schedulerDidClearJSResponder() {
|
void Binding::schedulerDidClearJSResponder() {
|
||||||
jni::global_ref<jobject> localJavaUIManager = getJavaUIManager();
|
jni::global_ref<jobject> localJavaUIManager = getJavaUIManager();
|
||||||
if (!localJavaUIManager) {
|
if (!localJavaUIManager) {
|
||||||
LOG(ERROR) << "Binding::schedulerClearJSResponder: JavaUIManager disappeared";
|
LOG(ERROR)
|
||||||
|
<< "Binding::schedulerClearJSResponder: JavaUIManager disappeared";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static auto clearJSResponder =
|
static auto clearJSResponder = jni::findClassStatic(UIManagerJavaDescriptor)
|
||||||
jni::findClassStatic(UIManagerJavaDescriptor)
|
->getMethod<void()>("clearJSResponder");
|
||||||
->getMethod<void()>("clearJSResponder");
|
|
||||||
|
|
||||||
clearJSResponder(localJavaUIManager);
|
clearJSResponder(localJavaUIManager);
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,17 +76,17 @@ class Binding : public jni::HybridClass<Binding>, public SchedulerDelegate {
|
||||||
const ShadowView &shadowView);
|
const ShadowView &shadowView);
|
||||||
|
|
||||||
void schedulerDidDispatchCommand(
|
void schedulerDidDispatchCommand(
|
||||||
const ShadowView &shadowView,
|
const ShadowView &shadowView,
|
||||||
std::string const &commandName,
|
std::string const &commandName,
|
||||||
folly::dynamic const args);
|
folly::dynamic const args);
|
||||||
|
|
||||||
void setPixelDensity(float pointScaleFactor);
|
void setPixelDensity(float pointScaleFactor);
|
||||||
|
|
||||||
void schedulerDidSetJSResponder(
|
void schedulerDidSetJSResponder(
|
||||||
SurfaceId surfaceId,
|
SurfaceId surfaceId,
|
||||||
const ShadowView &shadowView,
|
const ShadowView &shadowView,
|
||||||
const ShadowView &initialShadowView,
|
const ShadowView &initialShadowView,
|
||||||
bool blockNativeResponder);
|
bool blockNativeResponder);
|
||||||
|
|
||||||
void schedulerDidClearJSResponder();
|
void schedulerDidClearJSResponder();
|
||||||
|
|
||||||
|
|
|
@ -10,8 +10,8 @@
|
||||||
#include <fb/fbjni.h>
|
#include <fb/fbjni.h>
|
||||||
#include <jsi/jsi.h>
|
#include <jsi/jsi.h>
|
||||||
#include <react/uimanager/ComponentDescriptorRegistry.h>
|
#include <react/uimanager/ComponentDescriptorRegistry.h>
|
||||||
#include <react/utils/ContextContainer.h>
|
|
||||||
#include <react/uimanager/Scheduler.h>
|
#include <react/uimanager/Scheduler.h>
|
||||||
|
#include <react/utils/ContextContainer.h>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ class Instance;
|
||||||
class ComponentFactoryDelegate
|
class ComponentFactoryDelegate
|
||||||
: public jni::HybridClass<ComponentFactoryDelegate> {
|
: public jni::HybridClass<ComponentFactoryDelegate> {
|
||||||
public:
|
public:
|
||||||
constexpr static const char* const kJavaDescriptor =
|
constexpr static const char *const kJavaDescriptor =
|
||||||
"Lcom/facebook/react/fabric/ComponentFactoryDelegate;";
|
"Lcom/facebook/react/fabric/ComponentFactoryDelegate;";
|
||||||
|
|
||||||
static void registerNatives();
|
static void registerNatives();
|
||||||
|
|
|
@ -13,8 +13,8 @@ namespace facebook {
|
||||||
namespace react {
|
namespace react {
|
||||||
|
|
||||||
EventBeatManager::EventBeatManager(
|
EventBeatManager::EventBeatManager(
|
||||||
jni::alias_ref<EventBeatManager::jhybriddata> jhybridobject)
|
jni::alias_ref<EventBeatManager::jhybriddata> jhybridobject)
|
||||||
: jhybridobject_(jhybridobject) {}
|
: jhybridobject_(jhybridobject) {}
|
||||||
|
|
||||||
jni::local_ref<EventBeatManager::jhybriddata> EventBeatManager::initHybrid(
|
jni::local_ref<EventBeatManager::jhybriddata> EventBeatManager::initHybrid(
|
||||||
jni::alias_ref<EventBeatManager::jhybriddata> jhybridobject) {
|
jni::alias_ref<EventBeatManager::jhybriddata> jhybridobject) {
|
||||||
|
|
|
@ -20,7 +20,7 @@ EventEmitterWrapper::initHybrid(jni::alias_ref<jclass>) {
|
||||||
|
|
||||||
void EventEmitterWrapper::invokeEvent(
|
void EventEmitterWrapper::invokeEvent(
|
||||||
std::string eventName,
|
std::string eventName,
|
||||||
NativeMap* payload) {
|
NativeMap *payload) {
|
||||||
eventEmitter->dispatchEvent(
|
eventEmitter->dispatchEvent(
|
||||||
eventName, payload->consume(), EventPriority::AsynchronousBatched);
|
eventName, payload->consume(), EventPriority::AsynchronousBatched);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,14 +18,14 @@ class Instance;
|
||||||
|
|
||||||
class EventEmitterWrapper : public jni::HybridClass<EventEmitterWrapper> {
|
class EventEmitterWrapper : public jni::HybridClass<EventEmitterWrapper> {
|
||||||
public:
|
public:
|
||||||
constexpr static const char* const kJavaDescriptor =
|
constexpr static const char *const kJavaDescriptor =
|
||||||
"Lcom/facebook/react/fabric/events/EventEmitterWrapper;";
|
"Lcom/facebook/react/fabric/events/EventEmitterWrapper;";
|
||||||
|
|
||||||
static void registerNatives();
|
static void registerNatives();
|
||||||
|
|
||||||
SharedEventEmitter eventEmitter;
|
SharedEventEmitter eventEmitter;
|
||||||
|
|
||||||
void invokeEvent(std::string eventName, NativeMap* params);
|
void invokeEvent(std::string eventName, NativeMap *params);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static jni::local_ref<jhybriddata> initHybrid(jni::alias_ref<jclass>);
|
static jni::local_ref<jhybriddata> initHybrid(jni::alias_ref<jclass>);
|
||||||
|
|
|
@ -14,8 +14,8 @@ using namespace facebook::jni;
|
||||||
namespace facebook {
|
namespace facebook {
|
||||||
namespace react {
|
namespace react {
|
||||||
|
|
||||||
jni::local_ref<NodeStateWrapper::jhybriddata>
|
jni::local_ref<NodeStateWrapper::jhybriddata> NodeStateWrapper::initHybrid(
|
||||||
NodeStateWrapper::initHybrid(jni::alias_ref<jclass>) {
|
jni::alias_ref<jclass>) {
|
||||||
return makeCxxInstance();
|
return makeCxxInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ jni::local_ref<ReadableNativeMap::jhybridobject> NodeStateWrapper::getState() {
|
||||||
return readableNativeMap;
|
return readableNativeMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodeStateWrapper::updateState(ReadableNativeMap* map) {
|
void NodeStateWrapper::updateState(ReadableNativeMap *map) {
|
||||||
// Get folly::dynamic from map
|
// Get folly::dynamic from map
|
||||||
auto dynamicMap = map->consume();
|
auto dynamicMap = map->consume();
|
||||||
// Set state
|
// Set state
|
||||||
|
|
|
@ -16,7 +16,7 @@ namespace react {
|
||||||
|
|
||||||
class NodeStateWrapper : public jni::HybridClass<NodeStateWrapper> {
|
class NodeStateWrapper : public jni::HybridClass<NodeStateWrapper> {
|
||||||
public:
|
public:
|
||||||
constexpr static const char* const kJavaDescriptor =
|
constexpr static const char *const kJavaDescriptor =
|
||||||
"Lcom/facebook/react/fabric/NodeStateWrapper;";
|
"Lcom/facebook/react/fabric/NodeStateWrapper;";
|
||||||
|
|
||||||
NodeStateWrapper() {}
|
NodeStateWrapper() {}
|
||||||
|
@ -24,9 +24,10 @@ class NodeStateWrapper : public jni::HybridClass<NodeStateWrapper> {
|
||||||
static void registerNatives();
|
static void registerNatives();
|
||||||
|
|
||||||
jni::local_ref<ReadableNativeMap::jhybridobject> getState();
|
jni::local_ref<ReadableNativeMap::jhybridobject> getState();
|
||||||
void updateState(ReadableNativeMap* map);
|
void updateState(ReadableNativeMap *map);
|
||||||
|
|
||||||
|
const State *state_;
|
||||||
|
|
||||||
const State* state_;
|
|
||||||
private:
|
private:
|
||||||
static jni::local_ref<jhybriddata> initHybrid(jni::alias_ref<jclass>);
|
static jni::local_ref<jhybriddata> initHybrid(jni::alias_ref<jclass>);
|
||||||
};
|
};
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
#include "EventEmitterWrapper.h"
|
#include "EventEmitterWrapper.h"
|
||||||
#include "StateWrapperImpl.h"
|
#include "StateWrapperImpl.h"
|
||||||
|
|
||||||
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void*) {
|
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) {
|
||||||
return facebook::xplat::initialize(vm, [] {
|
return facebook::xplat::initialize(vm, [] {
|
||||||
facebook::react::Binding::registerNatives();
|
facebook::react::Binding::registerNatives();
|
||||||
facebook::react::EventBeatManager::registerNatives();
|
facebook::react::EventBeatManager::registerNatives();
|
||||||
|
|
|
@ -11,14 +11,14 @@
|
||||||
|
|
||||||
using namespace facebook::react;
|
using namespace facebook::react;
|
||||||
|
|
||||||
bool ReactNativeConfigHolder::getBool(const std::string& param) const {
|
bool ReactNativeConfigHolder::getBool(const std::string ¶m) const {
|
||||||
static const auto method = facebook::jni::findClassStatic(
|
static const auto method = facebook::jni::findClassStatic(
|
||||||
"com/facebook/react/fabric/ReactNativeConfig")
|
"com/facebook/react/fabric/ReactNativeConfig")
|
||||||
->getMethod<jboolean(jstring)>("getBool");
|
->getMethod<jboolean(jstring)>("getBool");
|
||||||
return method(reactNativeConfig_, facebook::jni::make_jstring(param).get());
|
return method(reactNativeConfig_, facebook::jni::make_jstring(param).get());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ReactNativeConfigHolder::getString(const std::string& param) const {
|
std::string ReactNativeConfigHolder::getString(const std::string ¶m) const {
|
||||||
static const auto method = facebook::jni::findClassStatic(
|
static const auto method = facebook::jni::findClassStatic(
|
||||||
"com/facebook/react/fabric/ReactNativeConfig")
|
"com/facebook/react/fabric/ReactNativeConfig")
|
||||||
->getMethod<jstring(jstring)>("getString");
|
->getMethod<jstring(jstring)>("getString");
|
||||||
|
@ -26,14 +26,14 @@ std::string ReactNativeConfigHolder::getString(const std::string& param) const {
|
||||||
->toString();
|
->toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t ReactNativeConfigHolder::getInt64(const std::string& param) const {
|
int64_t ReactNativeConfigHolder::getInt64(const std::string ¶m) const {
|
||||||
static const auto method = facebook::jni::findClassStatic(
|
static const auto method = facebook::jni::findClassStatic(
|
||||||
"com/facebook/react/fabric/ReactNativeConfig")
|
"com/facebook/react/fabric/ReactNativeConfig")
|
||||||
->getMethod<jint(jstring)>("getInt64");
|
->getMethod<jint(jstring)>("getInt64");
|
||||||
return method(reactNativeConfig_, facebook::jni::make_jstring(param).get());
|
return method(reactNativeConfig_, facebook::jni::make_jstring(param).get());
|
||||||
}
|
}
|
||||||
|
|
||||||
double ReactNativeConfigHolder::getDouble(const std::string& param) const {
|
double ReactNativeConfigHolder::getDouble(const std::string ¶m) const {
|
||||||
static const auto method = facebook::jni::findClassStatic(
|
static const auto method = facebook::jni::findClassStatic(
|
||||||
"com/facebook/react/fabric/ReactNativeConfig")
|
"com/facebook/react/fabric/ReactNativeConfig")
|
||||||
->getMethod<jdouble(jstring)>("getDouble");
|
->getMethod<jdouble(jstring)>("getDouble");
|
||||||
|
|
|
@ -25,10 +25,10 @@ class ReactNativeConfigHolder : public ReactNativeConfig {
|
||||||
ReactNativeConfigHolder(jni::alias_ref<jobject> reactNativeConfig)
|
ReactNativeConfigHolder(jni::alias_ref<jobject> reactNativeConfig)
|
||||||
: reactNativeConfig_(make_global(reactNativeConfig)){};
|
: reactNativeConfig_(make_global(reactNativeConfig)){};
|
||||||
|
|
||||||
bool getBool(const std::string& param) const override;
|
bool getBool(const std::string ¶m) const override;
|
||||||
std::string getString(const std::string& param) const override;
|
std::string getString(const std::string ¶m) const override;
|
||||||
int64_t getInt64(const std::string& param) const override;
|
int64_t getInt64(const std::string ¶m) const override;
|
||||||
double getDouble(const std::string& param) const override;
|
double getDouble(const std::string ¶m) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
jni::global_ref<jobject> reactNativeConfig_;
|
jni::global_ref<jobject> reactNativeConfig_;
|
||||||
|
|
|
@ -17,8 +17,8 @@ namespace react {
|
||||||
/**
|
/**
|
||||||
* Called from Java constructor through the JNI.
|
* Called from Java constructor through the JNI.
|
||||||
*/
|
*/
|
||||||
jni::local_ref<StateWrapperImpl::jhybriddata>
|
jni::local_ref<StateWrapperImpl::jhybriddata> StateWrapperImpl::initHybrid(
|
||||||
StateWrapperImpl::initHybrid(jni::alias_ref<jclass>) {
|
jni::alias_ref<jclass>) {
|
||||||
return makeCxxInstance();
|
return makeCxxInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ jni::local_ref<ReadableNativeMap::jhybridobject> StateWrapperImpl::getState() {
|
||||||
return readableNativeMap;
|
return readableNativeMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StateWrapperImpl::updateStateImpl(NativeMap* map) {
|
void StateWrapperImpl::updateStateImpl(NativeMap *map) {
|
||||||
// Get folly::dynamic from map
|
// Get folly::dynamic from map
|
||||||
auto dynamicMap = map->consume();
|
auto dynamicMap = map->consume();
|
||||||
// Set state
|
// Set state
|
||||||
|
@ -38,8 +38,8 @@ void StateWrapperImpl::updateStateImpl(NativeMap* map) {
|
||||||
|
|
||||||
void StateWrapperImpl::registerNatives() {
|
void StateWrapperImpl::registerNatives() {
|
||||||
registerHybrid({
|
registerHybrid({
|
||||||
makeNativeMethod("initHybrid", StateWrapperImpl::initHybrid),
|
makeNativeMethod("initHybrid", StateWrapperImpl::initHybrid),
|
||||||
makeNativeMethod("getState", StateWrapperImpl::getState),
|
makeNativeMethod("getState", StateWrapperImpl::getState),
|
||||||
makeNativeMethod("updateStateImpl", StateWrapperImpl::updateStateImpl),
|
makeNativeMethod("updateStateImpl", StateWrapperImpl::updateStateImpl),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ class Instance;
|
||||||
|
|
||||||
class StateWrapperImpl : public jni::HybridClass<StateWrapperImpl> {
|
class StateWrapperImpl : public jni::HybridClass<StateWrapperImpl> {
|
||||||
public:
|
public:
|
||||||
constexpr static const char* const kJavaDescriptor =
|
constexpr static const char *const kJavaDescriptor =
|
||||||
"Lcom/facebook/react/fabric/StateWrapperImpl;";
|
"Lcom/facebook/react/fabric/StateWrapperImpl;";
|
||||||
|
|
||||||
static void registerNatives();
|
static void registerNatives();
|
||||||
|
@ -27,6 +27,7 @@ class StateWrapperImpl : public jni::HybridClass<StateWrapperImpl> {
|
||||||
void updateStateImpl(NativeMap *map);
|
void updateStateImpl(NativeMap *map);
|
||||||
|
|
||||||
State::Shared state_;
|
State::Shared state_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
jni::alias_ref<StateWrapperImpl::jhybriddata> jhybridobject_;
|
jni::alias_ref<StateWrapperImpl::jhybriddata> jhybridobject_;
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ BlobCollector::BlobCollector(
|
||||||
BlobCollector::~BlobCollector() {
|
BlobCollector::~BlobCollector() {
|
||||||
jni::ThreadScope::WithClassLoader([&] {
|
jni::ThreadScope::WithClassLoader([&] {
|
||||||
static auto removeMethod = jni::findClassStatic(kBlobModuleJavaDescriptor)
|
static auto removeMethod = jni::findClassStatic(kBlobModuleJavaDescriptor)
|
||||||
->getMethod<void(jstring)>("remove");
|
->getMethod<void(jstring)>("remove");
|
||||||
removeMethod(blobModule_, jni::make_jstring(blobId_).get());
|
removeMethod(blobModule_, jni::make_jstring(blobId_).get());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ void BlobCollector::nativeInstall(
|
||||||
jni::alias_ref<jhybridobject> jThis,
|
jni::alias_ref<jhybridobject> jThis,
|
||||||
jni::alias_ref<jobject> blobModule,
|
jni::alias_ref<jobject> blobModule,
|
||||||
jlong jsContextNativePointer) {
|
jlong jsContextNativePointer) {
|
||||||
auto &runtime = *((jsi::Runtime *) jsContextNativePointer);
|
auto &runtime = *((jsi::Runtime *)jsContextNativePointer);
|
||||||
auto blobModuleRef = jni::make_global(blobModule);
|
auto blobModuleRef = jni::make_global(blobModule);
|
||||||
runtime.global().setProperty(
|
runtime.global().setProperty(
|
||||||
runtime,
|
runtime,
|
||||||
|
|
|
@ -7,15 +7,14 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <fb/fbjni.h>
|
|
||||||
#include <ReactCommon/CallInvoker.h>
|
#include <ReactCommon/CallInvoker.h>
|
||||||
|
#include <fb/fbjni.h>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
namespace facebook {
|
namespace facebook {
|
||||||
namespace react {
|
namespace react {
|
||||||
|
|
||||||
class CallInvokerHolder
|
class CallInvokerHolder : public jni::HybridClass<CallInvokerHolder> {
|
||||||
: public jni::HybridClass<CallInvokerHolder> {
|
|
||||||
public:
|
public:
|
||||||
static auto constexpr kJavaDescriptor =
|
static auto constexpr kJavaDescriptor =
|
||||||
"Lcom/facebook/react/turbomodule/core/CallInvokerHolderImpl;";
|
"Lcom/facebook/react/turbomodule/core/CallInvokerHolderImpl;";
|
||||||
|
|
|
@ -12,7 +12,8 @@
|
||||||
|
|
||||||
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) {
|
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) {
|
||||||
return facebook::xplat::initialize(vm, [] {
|
return facebook::xplat::initialize(vm, [] {
|
||||||
// TODO: dvacca ramanpreet unify this with the way "ComponentDescriptorFactory" is defined in Fabric
|
// TODO: dvacca ramanpreet unify this with the way
|
||||||
|
// "ComponentDescriptorFactory" is defined in Fabric
|
||||||
facebook::react::TurboModuleManager::registerNatives();
|
facebook::react::TurboModuleManager::registerNatives();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,8 +11,8 @@
|
||||||
#include <fb/fbjni.h>
|
#include <fb/fbjni.h>
|
||||||
#include <jsi/jsi.h>
|
#include <jsi/jsi.h>
|
||||||
|
|
||||||
#include <ReactCommon/TurboModuleBinding.h>
|
|
||||||
#include <ReactCommon/TurboCxxModule.h>
|
#include <ReactCommon/TurboCxxModule.h>
|
||||||
|
#include <ReactCommon/TurboModuleBinding.h>
|
||||||
#include <react/jni/JMessageQueueThread.h>
|
#include <react/jni/JMessageQueueThread.h>
|
||||||
|
|
||||||
#include "TurboModuleManager.h"
|
#include "TurboModuleManager.h"
|
||||||
|
@ -21,37 +21,40 @@ namespace facebook {
|
||||||
namespace react {
|
namespace react {
|
||||||
|
|
||||||
TurboModuleManager::TurboModuleManager(
|
TurboModuleManager::TurboModuleManager(
|
||||||
jni::alias_ref<TurboModuleManager::javaobject> jThis,
|
jni::alias_ref<TurboModuleManager::javaobject> jThis,
|
||||||
jsi::Runtime* rt,
|
jsi::Runtime *rt,
|
||||||
std::shared_ptr<CallInvoker> jsCallInvoker,
|
std::shared_ptr<CallInvoker> jsCallInvoker,
|
||||||
std::shared_ptr<CallInvoker> nativeCallInvoker,
|
std::shared_ptr<CallInvoker> nativeCallInvoker,
|
||||||
jni::alias_ref<TurboModuleManagerDelegate::javaobject> delegate
|
jni::alias_ref<TurboModuleManagerDelegate::javaobject> delegate)
|
||||||
):
|
: javaPart_(jni::make_global(jThis)),
|
||||||
javaPart_(jni::make_global(jThis)),
|
runtime_(rt),
|
||||||
runtime_(rt),
|
jsCallInvoker_(jsCallInvoker),
|
||||||
jsCallInvoker_(jsCallInvoker),
|
nativeCallInvoker_(nativeCallInvoker),
|
||||||
nativeCallInvoker_(nativeCallInvoker),
|
delegate_(jni::make_global(delegate)),
|
||||||
delegate_(jni::make_global(delegate)),
|
turboModuleCache_(std::make_shared<TurboModuleCache>()) {}
|
||||||
turboModuleCache_(std::make_shared<TurboModuleCache>())
|
|
||||||
{}
|
|
||||||
|
|
||||||
jni::local_ref<TurboModuleManager::jhybriddata> TurboModuleManager::initHybrid(
|
jni::local_ref<TurboModuleManager::jhybriddata> TurboModuleManager::initHybrid(
|
||||||
jni::alias_ref<jhybridobject> jThis,
|
jni::alias_ref<jhybridobject> jThis,
|
||||||
jlong jsContext,
|
jlong jsContext,
|
||||||
jni::alias_ref<CallInvokerHolder::javaobject> jsCallInvokerHolder,
|
jni::alias_ref<CallInvokerHolder::javaobject> jsCallInvokerHolder,
|
||||||
jni::alias_ref<CallInvokerHolder::javaobject> nativeCallInvokerHolder,
|
jni::alias_ref<CallInvokerHolder::javaobject> nativeCallInvokerHolder,
|
||||||
jni::alias_ref<TurboModuleManagerDelegate::javaobject> delegate
|
jni::alias_ref<TurboModuleManagerDelegate::javaobject> delegate) {
|
||||||
) {
|
|
||||||
auto jsCallInvoker = jsCallInvokerHolder->cthis()->getCallInvoker();
|
auto jsCallInvoker = jsCallInvokerHolder->cthis()->getCallInvoker();
|
||||||
auto nativeCallInvoker = nativeCallInvokerHolder->cthis()->getCallInvoker();
|
auto nativeCallInvoker = nativeCallInvokerHolder->cthis()->getCallInvoker();
|
||||||
|
|
||||||
return makeCxxInstance(jThis, (jsi::Runtime *) jsContext, jsCallInvoker, nativeCallInvoker, delegate);
|
return makeCxxInstance(
|
||||||
|
jThis,
|
||||||
|
(jsi::Runtime *)jsContext,
|
||||||
|
jsCallInvoker,
|
||||||
|
nativeCallInvoker,
|
||||||
|
delegate);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TurboModuleManager::registerNatives() {
|
void TurboModuleManager::registerNatives() {
|
||||||
registerHybrid({
|
registerHybrid({
|
||||||
makeNativeMethod("initHybrid", TurboModuleManager::initHybrid),
|
makeNativeMethod("initHybrid", TurboModuleManager::initHybrid),
|
||||||
makeNativeMethod("installJSIBindings", TurboModuleManager::installJSIBindings),
|
makeNativeMethod(
|
||||||
|
"installJSIBindings", TurboModuleManager::installJSIBindings),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,57 +63,67 @@ void TurboModuleManager::installJSIBindings() {
|
||||||
return; // Runtime doesn't exist when attached to Chrome debugger.
|
return; // Runtime doesn't exist when attached to Chrome debugger.
|
||||||
}
|
}
|
||||||
|
|
||||||
TurboModuleBinding::install(*runtime_, std::make_shared<TurboModuleBinding>(
|
TurboModuleBinding::install(
|
||||||
[
|
*runtime_,
|
||||||
turboModuleCache_ = std::weak_ptr<TurboModuleCache>(turboModuleCache_),
|
std::make_shared<TurboModuleBinding>(
|
||||||
jsCallInvoker_ = std::weak_ptr<CallInvoker>(jsCallInvoker_),
|
[turboModuleCache_ =
|
||||||
nativeCallInvoker_ = std::weak_ptr<CallInvoker>(nativeCallInvoker_),
|
std::weak_ptr<TurboModuleCache>(turboModuleCache_),
|
||||||
delegate_ = jni::make_weak(delegate_),
|
jsCallInvoker_ = std::weak_ptr<CallInvoker>(jsCallInvoker_),
|
||||||
javaPart_ = jni::make_weak(javaPart_)
|
nativeCallInvoker_ = std::weak_ptr<CallInvoker>(nativeCallInvoker_),
|
||||||
]
|
delegate_ = jni::make_weak(delegate_),
|
||||||
(const std::string &name) -> std::shared_ptr<TurboModule> {
|
javaPart_ = jni::make_weak(javaPart_)](
|
||||||
auto turboModuleCache = turboModuleCache_.lock();
|
const std::string &name) -> std::shared_ptr<TurboModule> {
|
||||||
auto jsCallInvoker = jsCallInvoker_.lock();
|
auto turboModuleCache = turboModuleCache_.lock();
|
||||||
auto nativeCallInvoker = nativeCallInvoker_.lock();
|
auto jsCallInvoker = jsCallInvoker_.lock();
|
||||||
auto delegate = delegate_.lockLocal();
|
auto nativeCallInvoker = nativeCallInvoker_.lock();
|
||||||
auto javaPart = javaPart_.lockLocal();
|
auto delegate = delegate_.lockLocal();
|
||||||
|
auto javaPart = javaPart_.lockLocal();
|
||||||
|
|
||||||
if (!turboModuleCache || !jsCallInvoker || !nativeCallInvoker || !delegate || !javaPart) {
|
if (!turboModuleCache || !jsCallInvoker || !nativeCallInvoker ||
|
||||||
return nullptr;
|
!delegate || !javaPart) {
|
||||||
}
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
auto turboModuleLookup = turboModuleCache->find(name);
|
auto turboModuleLookup = turboModuleCache->find(name);
|
||||||
if (turboModuleLookup != turboModuleCache->end()) {
|
if (turboModuleLookup != turboModuleCache->end()) {
|
||||||
return turboModuleLookup->second;
|
return turboModuleLookup->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto cxxModule = delegate->cthis()->getTurboModule(name, jsCallInvoker);
|
auto cxxModule =
|
||||||
if (cxxModule) {
|
delegate->cthis()->getTurboModule(name, jsCallInvoker);
|
||||||
turboModuleCache->insert({name, cxxModule});
|
if (cxxModule) {
|
||||||
return cxxModule;
|
turboModuleCache->insert({name, cxxModule});
|
||||||
}
|
return cxxModule;
|
||||||
|
}
|
||||||
|
|
||||||
static auto getLegacyCxxModule = delegate->getClass()->getMethod<jni::alias_ref<CxxModuleWrapper::javaobject>(const std::string&)>("getLegacyCxxModule");
|
static auto getLegacyCxxModule =
|
||||||
auto legacyCxxModule = getLegacyCxxModule(delegate.get(), name);
|
delegate->getClass()
|
||||||
|
->getMethod<jni::alias_ref<CxxModuleWrapper::javaobject>(
|
||||||
|
const std::string &)>("getLegacyCxxModule");
|
||||||
|
auto legacyCxxModule = getLegacyCxxModule(delegate.get(), name);
|
||||||
|
|
||||||
if (legacyCxxModule) {
|
if (legacyCxxModule) {
|
||||||
auto turboModule = std::make_shared<react::TurboCxxModule>(legacyCxxModule->cthis()->getModule(), jsCallInvoker);
|
auto turboModule = std::make_shared<react::TurboCxxModule>(
|
||||||
turboModuleCache->insert({name, turboModule});
|
legacyCxxModule->cthis()->getModule(), jsCallInvoker);
|
||||||
return turboModule;
|
turboModuleCache->insert({name, turboModule});
|
||||||
}
|
return turboModule;
|
||||||
|
}
|
||||||
|
|
||||||
static auto getJavaModule = javaPart->getClass()->getMethod<jni::alias_ref<JTurboModule>(const std::string&)>("getJavaModule");
|
static auto getJavaModule =
|
||||||
auto moduleInstance = getJavaModule(javaPart.get(), name);
|
javaPart->getClass()
|
||||||
|
->getMethod<jni::alias_ref<JTurboModule>(
|
||||||
|
const std::string &)>("getJavaModule");
|
||||||
|
auto moduleInstance = getJavaModule(javaPart.get(), name);
|
||||||
|
|
||||||
if (moduleInstance) {
|
if (moduleInstance) {
|
||||||
auto turboModule = delegate->cthis()->getTurboModule(name, moduleInstance, jsCallInvoker, nativeCallInvoker);
|
auto turboModule = delegate->cthis()->getTurboModule(
|
||||||
turboModuleCache->insert({name, turboModule});
|
name, moduleInstance, jsCallInvoker, nativeCallInvoker);
|
||||||
return turboModule;
|
turboModuleCache->insert({name, turboModule});
|
||||||
}
|
return turboModule;
|
||||||
|
}
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
})
|
}));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace react
|
} // namespace react
|
||||||
|
|
|
@ -7,40 +7,42 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <memory>
|
#include <ReactCommon/CallInvokerHolder.h>
|
||||||
#include <unordered_map>
|
#include <ReactCommon/JavaTurboModule.h>
|
||||||
|
#include <ReactCommon/TurboModule.h>
|
||||||
|
#include <ReactCommon/TurboModuleManagerDelegate.h>
|
||||||
#include <fb/fbjni.h>
|
#include <fb/fbjni.h>
|
||||||
#include <jsi/jsi.h>
|
#include <jsi/jsi.h>
|
||||||
#include <ReactCommon/TurboModule.h>
|
|
||||||
#include <ReactCommon/JavaTurboModule.h>
|
|
||||||
#include <react/jni/CxxModuleWrapper.h>
|
#include <react/jni/CxxModuleWrapper.h>
|
||||||
#include <react/jni/JMessageQueueThread.h>
|
#include <react/jni/JMessageQueueThread.h>
|
||||||
#include <ReactCommon/CallInvokerHolder.h>
|
#include <memory>
|
||||||
#include <ReactCommon/TurboModuleManagerDelegate.h>
|
#include <unordered_map>
|
||||||
|
|
||||||
namespace facebook {
|
namespace facebook {
|
||||||
namespace react {
|
namespace react {
|
||||||
|
|
||||||
class TurboModuleManager : public jni::HybridClass<TurboModuleManager> {
|
class TurboModuleManager : public jni::HybridClass<TurboModuleManager> {
|
||||||
public:
|
public:
|
||||||
static auto constexpr kJavaDescriptor = "Lcom/facebook/react/turbomodule/core/TurboModuleManager;";
|
static auto constexpr kJavaDescriptor =
|
||||||
|
"Lcom/facebook/react/turbomodule/core/TurboModuleManager;";
|
||||||
static jni::local_ref<jhybriddata> initHybrid(
|
static jni::local_ref<jhybriddata> initHybrid(
|
||||||
jni::alias_ref<jhybridobject> jThis,
|
jni::alias_ref<jhybridobject> jThis,
|
||||||
jlong jsContext,
|
jlong jsContext,
|
||||||
jni::alias_ref<CallInvokerHolder::javaobject> jsCallInvokerHolder,
|
jni::alias_ref<CallInvokerHolder::javaobject> jsCallInvokerHolder,
|
||||||
jni::alias_ref<CallInvokerHolder::javaobject> nativeCallInvokerHolder,
|
jni::alias_ref<CallInvokerHolder::javaobject> nativeCallInvokerHolder,
|
||||||
jni::alias_ref<TurboModuleManagerDelegate::javaobject> delegate
|
jni::alias_ref<TurboModuleManagerDelegate::javaobject> delegate);
|
||||||
);
|
|
||||||
static void registerNatives();
|
static void registerNatives();
|
||||||
private:
|
|
||||||
|
private:
|
||||||
friend HybridBase;
|
friend HybridBase;
|
||||||
jni::global_ref<TurboModuleManager::javaobject> javaPart_;
|
jni::global_ref<TurboModuleManager::javaobject> javaPart_;
|
||||||
jsi::Runtime* runtime_;
|
jsi::Runtime *runtime_;
|
||||||
std::shared_ptr<CallInvoker> jsCallInvoker_;
|
std::shared_ptr<CallInvoker> jsCallInvoker_;
|
||||||
std::shared_ptr<CallInvoker> nativeCallInvoker_;
|
std::shared_ptr<CallInvoker> nativeCallInvoker_;
|
||||||
jni::global_ref<TurboModuleManagerDelegate::javaobject> delegate_;
|
jni::global_ref<TurboModuleManagerDelegate::javaobject> delegate_;
|
||||||
|
|
||||||
using TurboModuleCache = std::unordered_map<std::string, std::shared_ptr<react::TurboModule>>;
|
using TurboModuleCache =
|
||||||
|
std::unordered_map<std::string, std::shared_ptr<react::TurboModule>>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO(T48018690):
|
* TODO(T48018690):
|
||||||
|
@ -52,12 +54,11 @@ private:
|
||||||
|
|
||||||
void installJSIBindings();
|
void installJSIBindings();
|
||||||
explicit TurboModuleManager(
|
explicit TurboModuleManager(
|
||||||
jni::alias_ref<TurboModuleManager::jhybridobject> jThis,
|
jni::alias_ref<TurboModuleManager::jhybridobject> jThis,
|
||||||
jsi::Runtime *rt,
|
jsi::Runtime *rt,
|
||||||
std::shared_ptr<CallInvoker> jsCallInvoker,
|
std::shared_ptr<CallInvoker> jsCallInvoker,
|
||||||
std::shared_ptr<CallInvoker> nativeCallInvoker,
|
std::shared_ptr<CallInvoker> nativeCallInvoker,
|
||||||
jni::alias_ref<TurboModuleManagerDelegate::javaobject> delegate
|
jni::alias_ref<TurboModuleManagerDelegate::javaobject> delegate);
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace react
|
} // namespace react
|
||||||
|
|
|
@ -7,23 +7,31 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <fb/fbjni.h>
|
|
||||||
#include <ReactCommon/JavaTurboModule.h>
|
|
||||||
#include <ReactCommon/CallInvoker.h>
|
#include <ReactCommon/CallInvoker.h>
|
||||||
#include <string>
|
#include <ReactCommon/JavaTurboModule.h>
|
||||||
|
#include <fb/fbjni.h>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
namespace facebook {
|
namespace facebook {
|
||||||
namespace react {
|
namespace react {
|
||||||
|
|
||||||
class TurboModuleManagerDelegate : public jni::HybridClass<TurboModuleManagerDelegate> {
|
class TurboModuleManagerDelegate
|
||||||
public:
|
: public jni::HybridClass<TurboModuleManagerDelegate> {
|
||||||
static auto constexpr kJavaDescriptor = "Lcom/facebook/react/turbomodule/core/TurboModuleManagerDelegate;";
|
public:
|
||||||
|
static auto constexpr kJavaDescriptor =
|
||||||
|
"Lcom/facebook/react/turbomodule/core/TurboModuleManagerDelegate;";
|
||||||
|
|
||||||
virtual std::shared_ptr<TurboModule> getTurboModule(std::string name, jni::alias_ref<JTurboModule> turboModule, std::shared_ptr<CallInvoker> jsInvoker, std::shared_ptr<CallInvoker> nativeInvoker) = 0;
|
virtual std::shared_ptr<TurboModule> getTurboModule(
|
||||||
virtual std::shared_ptr<TurboModule> getTurboModule(std::string name, std::shared_ptr<CallInvoker> jsInvoker) = 0;
|
std::string name,
|
||||||
|
jni::alias_ref<JTurboModule> turboModule,
|
||||||
|
std::shared_ptr<CallInvoker> jsInvoker,
|
||||||
|
std::shared_ptr<CallInvoker> nativeInvoker) = 0;
|
||||||
|
virtual std::shared_ptr<TurboModule> getTurboModule(
|
||||||
|
std::string name,
|
||||||
|
std::shared_ptr<CallInvoker> jsInvoker) = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend HybridBase;
|
friend HybridBase;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -290,8 +290,8 @@ void CatalystInstanceImpl::handleMemoryPressure(int pressureLevel) {
|
||||||
jni::alias_ref<CallInvokerHolder::javaobject>
|
jni::alias_ref<CallInvokerHolder::javaobject>
|
||||||
CatalystInstanceImpl::getJSCallInvokerHolder() {
|
CatalystInstanceImpl::getJSCallInvokerHolder() {
|
||||||
if (!jsCallInvokerHolder_) {
|
if (!jsCallInvokerHolder_) {
|
||||||
jsCallInvokerHolder_ =
|
jsCallInvokerHolder_ = jni::make_global(CallInvokerHolder::newObjectCxxArgs(
|
||||||
jni::make_global(CallInvokerHolder::newObjectCxxArgs(std::make_shared<BridgeJSCallInvoker>(instance_)));
|
std::make_shared<BridgeJSCallInvoker>(instance_)));
|
||||||
}
|
}
|
||||||
|
|
||||||
return jsCallInvokerHolder_;
|
return jsCallInvokerHolder_;
|
||||||
|
@ -301,7 +301,9 @@ jni::alias_ref<CallInvokerHolder::javaobject>
|
||||||
CatalystInstanceImpl::getNativeCallInvokerHolder() {
|
CatalystInstanceImpl::getNativeCallInvokerHolder() {
|
||||||
if (!nativeCallInvokerHolder_) {
|
if (!nativeCallInvokerHolder_) {
|
||||||
nativeCallInvokerHolder_ =
|
nativeCallInvokerHolder_ =
|
||||||
jni::make_global(CallInvokerHolder::newObjectCxxArgs(std::make_shared<MessageQueueThreadCallInvoker>(moduleMessageQueue_)));
|
jni::make_global(CallInvokerHolder::newObjectCxxArgs(
|
||||||
|
std::make_shared<MessageQueueThreadCallInvoker>(
|
||||||
|
moduleMessageQueue_)));
|
||||||
}
|
}
|
||||||
|
|
||||||
return nativeCallInvokerHolder_;
|
return nativeCallInvokerHolder_;
|
||||||
|
|
|
@ -18,7 +18,7 @@ namespace react {
|
||||||
|
|
||||||
struct JNativeModule : jni::JavaClass<JNativeModule> {
|
struct JNativeModule : jni::JavaClass<JNativeModule> {
|
||||||
constexpr static const char *const kJavaDescriptor =
|
constexpr static const char *const kJavaDescriptor =
|
||||||
"Lcom/facebook/react/bridge/NativeModule;";
|
"Lcom/facebook/react/bridge/NativeModule;";
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -26,15 +26,14 @@ struct JNativeModule : jni::JavaClass<JNativeModule> {
|
||||||
* must extend this base class.
|
* must extend this base class.
|
||||||
*/
|
*/
|
||||||
class CxxModuleWrapperBase
|
class CxxModuleWrapperBase
|
||||||
: public jni::HybridClass<CxxModuleWrapperBase, JNativeModule> {
|
: public jni::HybridClass<CxxModuleWrapperBase, JNativeModule> {
|
||||||
public:
|
public:
|
||||||
constexpr static const char *const kJavaDescriptor =
|
constexpr static const char *const kJavaDescriptor =
|
||||||
"Lcom/facebook/react/bridge/CxxModuleWrapperBase;";
|
"Lcom/facebook/react/bridge/CxxModuleWrapperBase;";
|
||||||
|
|
||||||
static void registerNatives() {
|
static void registerNatives() {
|
||||||
registerHybrid({
|
registerHybrid(
|
||||||
makeNativeMethod("getName", CxxModuleWrapperBase::getName)
|
{makeNativeMethod("getName", CxxModuleWrapperBase::getName)});
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// JNI method
|
// JNI method
|
||||||
|
@ -44,5 +43,5 @@ public:
|
||||||
virtual std::unique_ptr<xplat::module::CxxModule> getModule() = 0;
|
virtual std::unique_ptr<xplat::module::CxxModule> getModule() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace react
|
||||||
}
|
} // namespace facebook
|
||||||
|
|
|
@ -20,30 +20,33 @@ namespace react {
|
||||||
class Instance;
|
class Instance;
|
||||||
|
|
||||||
struct JCallback : public jni::JavaClass<JCallback> {
|
struct JCallback : public jni::JavaClass<JCallback> {
|
||||||
constexpr static auto kJavaDescriptor = "Lcom/facebook/react/bridge/Callback;";
|
constexpr static auto kJavaDescriptor =
|
||||||
|
"Lcom/facebook/react/bridge/Callback;";
|
||||||
};
|
};
|
||||||
|
|
||||||
class JCxxCallbackImpl : public jni::HybridClass<JCxxCallbackImpl, JCallback> {
|
class JCxxCallbackImpl : public jni::HybridClass<JCxxCallbackImpl, JCallback> {
|
||||||
public:
|
public:
|
||||||
constexpr static auto kJavaDescriptor = "Lcom/facebook/react/bridge/CxxCallbackImpl;";
|
constexpr static auto kJavaDescriptor =
|
||||||
|
"Lcom/facebook/react/bridge/CxxCallbackImpl;";
|
||||||
|
|
||||||
static void registerNatives() {
|
static void registerNatives() {
|
||||||
javaClassStatic()->registerNatives({
|
javaClassStatic()->registerNatives({
|
||||||
makeNativeMethod("nativeInvoke", JCxxCallbackImpl::invoke),
|
makeNativeMethod("nativeInvoke", JCxxCallbackImpl::invoke),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
private:
|
|
||||||
|
private:
|
||||||
friend HybridBase;
|
friend HybridBase;
|
||||||
|
|
||||||
using Callback = std::function<void(folly::dynamic)>;
|
using Callback = std::function<void(folly::dynamic)>;
|
||||||
JCxxCallbackImpl(Callback callback) : callback_(std::move(callback)) {}
|
JCxxCallbackImpl(Callback callback) : callback_(std::move(callback)) {}
|
||||||
|
|
||||||
void invoke(NativeArray* arguments) {
|
void invoke(NativeArray *arguments) {
|
||||||
callback_(arguments->consume());
|
callback_(arguments->consume());
|
||||||
}
|
}
|
||||||
|
|
||||||
Callback callback_;
|
Callback callback_;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace react
|
||||||
}
|
} // namespace facebook
|
||||||
|
|
|
@ -19,23 +19,27 @@ namespace facebook {
|
||||||
namespace react {
|
namespace react {
|
||||||
|
|
||||||
class JPage : public jni::JavaClass<JPage> {
|
class JPage : public jni::JavaClass<JPage> {
|
||||||
public:
|
public:
|
||||||
static constexpr auto kJavaDescriptor = "Lcom/facebook/react/bridge/Inspector$Page;";
|
static constexpr auto kJavaDescriptor =
|
||||||
|
"Lcom/facebook/react/bridge/Inspector$Page;";
|
||||||
|
|
||||||
static jni::local_ref<JPage::javaobject> create(int id, const std::string& title, const std::string& vm);
|
static jni::local_ref<JPage::javaobject>
|
||||||
|
create(int id, const std::string &title, const std::string &vm);
|
||||||
};
|
};
|
||||||
|
|
||||||
class JRemoteConnection : public jni::JavaClass<JRemoteConnection> {
|
class JRemoteConnection : public jni::JavaClass<JRemoteConnection> {
|
||||||
public:
|
public:
|
||||||
static constexpr auto kJavaDescriptor = "Lcom/facebook/react/bridge/Inspector$RemoteConnection;";
|
static constexpr auto kJavaDescriptor =
|
||||||
|
"Lcom/facebook/react/bridge/Inspector$RemoteConnection;";
|
||||||
|
|
||||||
void onMessage(const std::string& message) const;
|
void onMessage(const std::string &message) const;
|
||||||
void onDisconnect() const;
|
void onDisconnect() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class JLocalConnection : public jni::HybridClass<JLocalConnection> {
|
class JLocalConnection : public jni::HybridClass<JLocalConnection> {
|
||||||
public:
|
public:
|
||||||
static constexpr auto kJavaDescriptor = "Lcom/facebook/react/bridge/Inspector$LocalConnection;";
|
static constexpr auto kJavaDescriptor =
|
||||||
|
"Lcom/facebook/react/bridge/Inspector$LocalConnection;";
|
||||||
|
|
||||||
JLocalConnection(std::unique_ptr<ILocalConnection> connection);
|
JLocalConnection(std::unique_ptr<ILocalConnection> connection);
|
||||||
|
|
||||||
|
@ -43,29 +47,35 @@ public:
|
||||||
void disconnect();
|
void disconnect();
|
||||||
|
|
||||||
static void registerNatives();
|
static void registerNatives();
|
||||||
private:
|
|
||||||
|
private:
|
||||||
std::unique_ptr<ILocalConnection> connection_;
|
std::unique_ptr<ILocalConnection> connection_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class JInspector : public jni::HybridClass<JInspector> {
|
class JInspector : public jni::HybridClass<JInspector> {
|
||||||
public:
|
public:
|
||||||
static constexpr auto kJavaDescriptor = "Lcom/facebook/react/bridge/Inspector;";
|
static constexpr auto kJavaDescriptor =
|
||||||
|
"Lcom/facebook/react/bridge/Inspector;";
|
||||||
|
|
||||||
static jni::global_ref<JInspector::javaobject> instance(jni::alias_ref<jclass>);
|
static jni::global_ref<JInspector::javaobject> instance(
|
||||||
|
jni::alias_ref<jclass>);
|
||||||
|
|
||||||
jni::local_ref<jni::JArrayClass<JPage::javaobject>> getPages();
|
jni::local_ref<jni::JArrayClass<JPage::javaobject>> getPages();
|
||||||
jni::local_ref<JLocalConnection::javaobject> connect(int pageId, jni::alias_ref<JRemoteConnection::javaobject> remote);
|
jni::local_ref<JLocalConnection::javaobject> connect(
|
||||||
|
int pageId,
|
||||||
|
jni::alias_ref<JRemoteConnection::javaobject> remote);
|
||||||
|
|
||||||
static void registerNatives();
|
static void registerNatives();
|
||||||
private:
|
|
||||||
|
private:
|
||||||
friend HybridBase;
|
friend HybridBase;
|
||||||
|
|
||||||
JInspector(IInspector* inspector) : inspector_(inspector) {}
|
JInspector(IInspector *inspector) : inspector_(inspector) {}
|
||||||
|
|
||||||
IInspector* inspector_;
|
IInspector *inspector_;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace react
|
||||||
}
|
} // namespace facebook
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -22,16 +22,17 @@ namespace react {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
struct JavaJSException : jni::JavaClass<JavaJSException, JThrowable> {
|
struct JavaJSException : jni::JavaClass<JavaJSException, JThrowable> {
|
||||||
static constexpr auto kJavaDescriptor = "Lcom/facebook/react/devsupport/JSException;";
|
static constexpr auto kJavaDescriptor =
|
||||||
|
"Lcom/facebook/react/devsupport/JSException;";
|
||||||
|
|
||||||
static local_ref<JavaJSException> create(const char* message, const char* stack,
|
static local_ref<JavaJSException>
|
||||||
const std::exception& ex) {
|
create(const char *message, const char *stack, const std::exception &ex) {
|
||||||
local_ref<jthrowable> cause = jni::JCppException::create(ex);
|
local_ref<jthrowable> cause = jni::JCppException::create(ex);
|
||||||
return newInstance(make_jstring(message), make_jstring(stack), cause.get());
|
return newInstance(make_jstring(message), make_jstring(stack), cause.get());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::function<void()> wrapRunnable(std::function<void()>&& runnable) {
|
std::function<void()> wrapRunnable(std::function<void()> &&runnable) {
|
||||||
return [runnable = std::move(runnable)]() mutable {
|
return [runnable = std::move(runnable)]() mutable {
|
||||||
if (!runnable) {
|
if (!runnable) {
|
||||||
// Runnable is empty, nothing to run.
|
// Runnable is empty, nothing to run.
|
||||||
|
@ -46,33 +47,39 @@ std::function<void()> wrapRunnable(std::function<void()>&& runnable) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
localRunnable();
|
localRunnable();
|
||||||
} catch (const jsi::JSError& ex) {
|
} catch (const jsi::JSError &ex) {
|
||||||
throwNewJavaException(
|
throwNewJavaException(
|
||||||
JavaJSException::create(ex.getMessage().c_str(), ex.getStack().c_str(), ex)
|
JavaJSException::create(
|
||||||
.get());
|
ex.getMessage().c_str(), ex.getStack().c_str(), ex)
|
||||||
|
.get());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace
|
||||||
|
|
||||||
JMessageQueueThread::JMessageQueueThread(alias_ref<JavaMessageQueueThread::javaobject> jobj) :
|
JMessageQueueThread::JMessageQueueThread(
|
||||||
m_jobj(make_global(jobj)) {
|
alias_ref<JavaMessageQueueThread::javaobject> jobj)
|
||||||
}
|
: m_jobj(make_global(jobj)) {}
|
||||||
|
|
||||||
void JMessageQueueThread::runOnQueue(std::function<void()>&& runnable) {
|
void JMessageQueueThread::runOnQueue(std::function<void()> &&runnable) {
|
||||||
// For C++ modules, this can be called from an arbitrary thread
|
// For C++ modules, this can be called from an arbitrary thread
|
||||||
// managed by the module, via callJSCallback or callJSFunction. So,
|
// managed by the module, via callJSCallback or callJSFunction. So,
|
||||||
// we ensure that it is registered with the JVM.
|
// we ensure that it is registered with the JVM.
|
||||||
jni::ThreadScope guard;
|
jni::ThreadScope guard;
|
||||||
static auto method = JavaMessageQueueThread::javaClassStatic()->
|
static auto method =
|
||||||
getMethod<void(Runnable::javaobject)>("runOnQueue");
|
JavaMessageQueueThread::javaClassStatic()
|
||||||
method(m_jobj, JNativeRunnable::newObjectCxxArgs(wrapRunnable(std::move(runnable))).get());
|
->getMethod<void(Runnable::javaobject)>("runOnQueue");
|
||||||
|
method(
|
||||||
|
m_jobj,
|
||||||
|
JNativeRunnable::newObjectCxxArgs(wrapRunnable(std::move(runnable)))
|
||||||
|
.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
void JMessageQueueThread::runOnQueueSync(std::function<void()>&& runnable) {
|
void JMessageQueueThread::runOnQueueSync(std::function<void()> &&runnable) {
|
||||||
static auto jIsOnThread = JavaMessageQueueThread::javaClassStatic()->
|
static auto jIsOnThread =
|
||||||
getMethod<jboolean()>("isOnThread");
|
JavaMessageQueueThread::javaClassStatic()->getMethod<jboolean()>(
|
||||||
|
"isOnThread");
|
||||||
|
|
||||||
if (jIsOnThread(m_jobj)) {
|
if (jIsOnThread(m_jobj)) {
|
||||||
wrapRunnable(std::move(runnable))();
|
wrapRunnable(std::move(runnable))();
|
||||||
|
@ -81,7 +88,7 @@ void JMessageQueueThread::runOnQueueSync(std::function<void()>&& runnable) {
|
||||||
std::condition_variable signalCv;
|
std::condition_variable signalCv;
|
||||||
bool runnableComplete = false;
|
bool runnableComplete = false;
|
||||||
|
|
||||||
runOnQueue([&] () mutable {
|
runOnQueue([&]() mutable {
|
||||||
std::lock_guard<std::mutex> lock(signalMutex);
|
std::lock_guard<std::mutex> lock(signalMutex);
|
||||||
|
|
||||||
runnable();
|
runnable();
|
||||||
|
@ -96,9 +103,11 @@ void JMessageQueueThread::runOnQueueSync(std::function<void()>&& runnable) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void JMessageQueueThread::quitSynchronous() {
|
void JMessageQueueThread::quitSynchronous() {
|
||||||
static auto method = JavaMessageQueueThread::javaClassStatic()->
|
static auto method =
|
||||||
getMethod<void()>("quitSynchronous");
|
JavaMessageQueueThread::javaClassStatic()->getMethod<void()>(
|
||||||
|
"quitSynchronous");
|
||||||
method(m_jobj);
|
method(m_jobj);
|
||||||
}
|
}
|
||||||
|
|
||||||
} }
|
} // namespace react
|
||||||
|
} // namespace facebook
|
||||||
|
|
|
@ -18,29 +18,30 @@ namespace facebook {
|
||||||
namespace react {
|
namespace react {
|
||||||
|
|
||||||
class JavaMessageQueueThread : public jni::JavaClass<JavaMessageQueueThread> {
|
class JavaMessageQueueThread : public jni::JavaClass<JavaMessageQueueThread> {
|
||||||
public:
|
public:
|
||||||
static constexpr auto kJavaDescriptor = "Lcom/facebook/react/bridge/queue/MessageQueueThread;";
|
static constexpr auto kJavaDescriptor =
|
||||||
|
"Lcom/facebook/react/bridge/queue/MessageQueueThread;";
|
||||||
};
|
};
|
||||||
|
|
||||||
class JMessageQueueThread : public MessageQueueThread {
|
class JMessageQueueThread : public MessageQueueThread {
|
||||||
public:
|
public:
|
||||||
JMessageQueueThread(alias_ref<JavaMessageQueueThread::javaobject> jobj);
|
JMessageQueueThread(alias_ref<JavaMessageQueueThread::javaobject> jobj);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enqueues the given function to run on this MessageQueueThread.
|
* Enqueues the given function to run on this MessageQueueThread.
|
||||||
*/
|
*/
|
||||||
void runOnQueue(std::function<void()>&& runnable) override;
|
void runOnQueue(std::function<void()> &&runnable) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Synchronously executes the given function to run on this
|
* Synchronously executes the given function to run on this
|
||||||
* MessageQueueThread, waiting until it completes. Can be called from any
|
* MessageQueueThread, waiting until it completes. Can be called from any
|
||||||
* thread, but will block if not called on this MessageQueueThread.
|
* thread, but will block if not called on this MessageQueueThread.
|
||||||
*/
|
*/
|
||||||
void runOnQueueSync(std::function<void()>&& runnable) override;
|
void runOnQueueSync(std::function<void()> &&runnable) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Synchronously quits the current MessageQueueThread. Can be called from any thread, but will
|
* Synchronously quits the current MessageQueueThread. Can be called from any
|
||||||
* block if not called on this MessageQueueThread.
|
* thread, but will block if not called on this MessageQueueThread.
|
||||||
*/
|
*/
|
||||||
void quitSynchronous() override;
|
void quitSynchronous() override;
|
||||||
|
|
||||||
|
@ -48,8 +49,9 @@ public:
|
||||||
return m_jobj.get();
|
return m_jobj.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
global_ref<JavaMessageQueueThread::javaobject> m_jobj;
|
global_ref<JavaMessageQueueThread::javaobject> m_jobj;
|
||||||
};
|
};
|
||||||
|
|
||||||
} }
|
} // namespace react
|
||||||
|
} // namespace facebook
|
||||||
|
|
|
@ -6,33 +6,38 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "JReactMarker.h"
|
#include "JReactMarker.h"
|
||||||
#include <mutex>
|
|
||||||
#include <cxxreact/ReactMarker.h>
|
#include <cxxreact/ReactMarker.h>
|
||||||
#include <fb/fbjni.h>
|
#include <fb/fbjni.h>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
namespace facebook {
|
namespace facebook {
|
||||||
namespace react {
|
namespace react {
|
||||||
|
|
||||||
void JReactMarker::setLogPerfMarkerIfNeeded() {
|
void JReactMarker::setLogPerfMarkerIfNeeded() {
|
||||||
static std::once_flag flag {};
|
static std::once_flag flag{};
|
||||||
std::call_once(flag, [](){
|
std::call_once(flag, []() {
|
||||||
ReactMarker::logTaggedMarker = JReactMarker::logPerfMarker;
|
ReactMarker::logTaggedMarker = JReactMarker::logPerfMarker;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void JReactMarker::logMarker(const std::string& marker) {
|
void JReactMarker::logMarker(const std::string &marker) {
|
||||||
static auto cls = javaClassStatic();
|
static auto cls = javaClassStatic();
|
||||||
static auto meth = cls->getStaticMethod<void(std::string)>("logMarker");
|
static auto meth = cls->getStaticMethod<void(std::string)>("logMarker");
|
||||||
meth(cls, marker);
|
meth(cls, marker);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JReactMarker::logMarker(const std::string& marker, const std::string& tag) {
|
void JReactMarker::logMarker(
|
||||||
|
const std::string &marker,
|
||||||
|
const std::string &tag) {
|
||||||
static auto cls = javaClassStatic();
|
static auto cls = javaClassStatic();
|
||||||
static auto meth = cls->getStaticMethod<void(std::string, std::string)>("logMarker");
|
static auto meth =
|
||||||
|
cls->getStaticMethod<void(std::string, std::string)>("logMarker");
|
||||||
meth(cls, marker, tag);
|
meth(cls, marker, tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JReactMarker::logPerfMarker(const ReactMarker::ReactMarkerId markerId, const char* tag) {
|
void JReactMarker::logPerfMarker(
|
||||||
|
const ReactMarker::ReactMarkerId markerId,
|
||||||
|
const char *tag) {
|
||||||
switch (markerId) {
|
switch (markerId) {
|
||||||
case ReactMarker::RUN_JS_BUNDLE_START:
|
case ReactMarker::RUN_JS_BUNDLE_START:
|
||||||
JReactMarker::logMarker("RUN_JS_BUNDLE_START", tag);
|
JReactMarker::logMarker("RUN_JS_BUNDLE_START", tag);
|
||||||
|
@ -68,5 +73,5 @@ void JReactMarker::logPerfMarker(const ReactMarker::ReactMarkerId markerId, cons
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace react
|
||||||
}
|
} // namespace facebook
|
||||||
|
|
|
@ -7,8 +7,8 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <fb/fbjni.h>
|
#include <fb/fbjni.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include <cxxreact/ReactMarker.h>
|
#include <cxxreact/ReactMarker.h>
|
||||||
|
|
||||||
|
@ -16,15 +16,18 @@ namespace facebook {
|
||||||
namespace react {
|
namespace react {
|
||||||
|
|
||||||
class JReactMarker : public facebook::jni::JavaClass<JReactMarker> {
|
class JReactMarker : public facebook::jni::JavaClass<JReactMarker> {
|
||||||
public:
|
public:
|
||||||
static constexpr auto kJavaDescriptor = "Lcom/facebook/react/bridge/ReactMarker;";
|
static constexpr auto kJavaDescriptor =
|
||||||
|
"Lcom/facebook/react/bridge/ReactMarker;";
|
||||||
static void setLogPerfMarkerIfNeeded();
|
static void setLogPerfMarkerIfNeeded();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void logMarker(const std::string& marker);
|
static void logMarker(const std::string &marker);
|
||||||
static void logMarker(const std::string& marker, const std::string& tag);
|
static void logMarker(const std::string &marker, const std::string &tag);
|
||||||
static void logPerfMarker(const ReactMarker::ReactMarkerId markerId, const char* tag);
|
static void logPerfMarker(
|
||||||
|
const ReactMarker::ReactMarkerId markerId,
|
||||||
|
const char *tag);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace react
|
||||||
}
|
} // namespace facebook
|
||||||
|
|
|
@ -28,30 +28,33 @@ using namespace facebook::jni;
|
||||||
namespace facebook {
|
namespace facebook {
|
||||||
namespace react {
|
namespace react {
|
||||||
|
|
||||||
__attribute__((visibility("default")))
|
__attribute__((visibility("default"))) AAssetManager *extractAssetManager(
|
||||||
AAssetManager *extractAssetManager(alias_ref<JAssetManager::javaobject> assetManager) {
|
alias_ref<JAssetManager::javaobject> assetManager) {
|
||||||
auto env = Environment::current();
|
auto env = Environment::current();
|
||||||
return AAssetManager_fromJava(env, assetManager.get());
|
return AAssetManager_fromJava(env, assetManager.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((visibility("default")))
|
__attribute__((visibility("default"))) std::unique_ptr<const JSBigString>
|
||||||
std::unique_ptr<const JSBigString> loadScriptFromAssets(
|
loadScriptFromAssets(AAssetManager *manager, const std::string &assetName) {
|
||||||
AAssetManager *manager,
|
#ifdef WITH_FBSYSTRACE
|
||||||
const std::string& assetName) {
|
FbSystraceSection s(
|
||||||
#ifdef WITH_FBSYSTRACE
|
TRACE_TAG_REACT_CXX_BRIDGE,
|
||||||
FbSystraceSection s(TRACE_TAG_REACT_CXX_BRIDGE, "reactbridge_jni_loadScriptFromAssets",
|
"reactbridge_jni_loadScriptFromAssets",
|
||||||
"assetName", assetName);
|
"assetName",
|
||||||
#endif
|
assetName);
|
||||||
|
#endif
|
||||||
if (manager) {
|
if (manager) {
|
||||||
auto asset = AAssetManager_open(
|
auto asset = AAssetManager_open(
|
||||||
manager,
|
manager,
|
||||||
assetName.c_str(),
|
assetName.c_str(),
|
||||||
AASSET_MODE_STREAMING); // Optimized for sequential read: see AssetManager.java for docs
|
AASSET_MODE_STREAMING); // Optimized for sequential read: see
|
||||||
|
// AssetManager.java for docs
|
||||||
if (asset) {
|
if (asset) {
|
||||||
auto buf = std::make_unique<JSBigBufferString>(AAsset_getLength(asset));
|
auto buf = std::make_unique<JSBigBufferString>(AAsset_getLength(asset));
|
||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
int readbytes;
|
int readbytes;
|
||||||
while ((readbytes = AAsset_read(asset, buf->data() + offset, buf->size() - offset)) > 0) {
|
while ((readbytes = AAsset_read(
|
||||||
|
asset, buf->data() + offset, buf->size() - offset)) > 0) {
|
||||||
offset += readbytes;
|
offset += readbytes;
|
||||||
}
|
}
|
||||||
AAsset_close(asset);
|
AAsset_close(asset);
|
||||||
|
@ -61,9 +64,12 @@ std::unique_ptr<const JSBigString> loadScriptFromAssets(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
throw std::runtime_error(folly::to<std::string>("Unable to load script. Make sure you're "
|
throw std::runtime_error(folly::to<std::string>(
|
||||||
"either running a Metro server (run 'react-native start') or that your bundle '", assetName,
|
"Unable to load script. Make sure you're "
|
||||||
"' is packaged correctly for release."));
|
"either running a Metro server (run 'react-native start') or that your bundle '",
|
||||||
|
assetName,
|
||||||
|
"' is packaged correctly for release."));
|
||||||
}
|
}
|
||||||
|
|
||||||
}}
|
} // namespace react
|
||||||
|
} // namespace facebook
|
||||||
|
|
|
@ -23,8 +23,12 @@ struct JAssetManager : jni::JavaClass<JAssetManager> {
|
||||||
/**
|
/**
|
||||||
* Helper method for loading JS script from android asset
|
* Helper method for loading JS script from android asset
|
||||||
*/
|
*/
|
||||||
AAssetManager *extractAssetManager(jni::alias_ref<JAssetManager::javaobject> assetManager);
|
AAssetManager *extractAssetManager(
|
||||||
|
jni::alias_ref<JAssetManager::javaobject> assetManager);
|
||||||
|
|
||||||
std::unique_ptr<const JSBigString> loadScriptFromAssets(AAssetManager *assetManager, const std::string& assetName);
|
std::unique_ptr<const JSBigString> loadScriptFromAssets(
|
||||||
|
AAssetManager *assetManager,
|
||||||
|
const std::string &assetName);
|
||||||
|
|
||||||
} }
|
} // namespace react
|
||||||
|
} // namespace facebook
|
||||||
|
|
|
@ -9,13 +9,13 @@
|
||||||
|
|
||||||
#include <glog/logging.h>
|
#include <glog/logging.h>
|
||||||
|
|
||||||
#include <fb/fbjni.h>
|
|
||||||
#include <folly/json.h>
|
|
||||||
#include <cxxreact/CxxModule.h>
|
#include <cxxreact/CxxModule.h>
|
||||||
#include <cxxreact/CxxNativeModule.h>
|
#include <cxxreact/CxxNativeModule.h>
|
||||||
#include <cxxreact/Instance.h>
|
#include <cxxreact/Instance.h>
|
||||||
#include <cxxreact/JsArgumentHelpers.h>
|
#include <cxxreact/JsArgumentHelpers.h>
|
||||||
#include <cxxreact/NativeModule.h>
|
#include <cxxreact/NativeModule.h>
|
||||||
|
#include <fb/fbjni.h>
|
||||||
|
#include <folly/json.h>
|
||||||
|
|
||||||
#ifdef WITH_FBSYSTRACE
|
#ifdef WITH_FBSYSTRACE
|
||||||
#include <fbsystrace.h>
|
#include <fbsystrace.h>
|
||||||
|
@ -45,7 +45,8 @@ std::string JMethodDescriptor::getType() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string JavaNativeModule::getName() {
|
std::string JavaNativeModule::getName() {
|
||||||
static auto getNameMethod = wrapper_->getClass()->getMethod<jstring()>("getName");
|
static auto getNameMethod =
|
||||||
|
wrapper_->getClass()->getMethod<jstring()>("getName");
|
||||||
return getNameMethod(wrapper_)->toStdString();
|
return getNameMethod(wrapper_)->toStdString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,35 +54,34 @@ std::vector<MethodDescriptor> JavaNativeModule::getMethods() {
|
||||||
std::vector<MethodDescriptor> ret;
|
std::vector<MethodDescriptor> ret;
|
||||||
syncMethods_.clear();
|
syncMethods_.clear();
|
||||||
auto descs = wrapper_->getMethodDescriptors();
|
auto descs = wrapper_->getMethodDescriptors();
|
||||||
for (const auto& desc : *descs) {
|
for (const auto &desc : *descs) {
|
||||||
auto methodName = desc->getName();
|
auto methodName = desc->getName();
|
||||||
auto methodType = desc->getType();
|
auto methodType = desc->getType();
|
||||||
|
|
||||||
if (methodType == "sync") {
|
if (methodType == "sync") {
|
||||||
// allow for the sync methods vector to have empty values, resize on demand
|
// allow for the sync methods vector to have empty values, resize on
|
||||||
|
// demand
|
||||||
size_t methodIndex = ret.size();
|
size_t methodIndex = ret.size();
|
||||||
if (methodIndex >= syncMethods_.size()) {
|
if (methodIndex >= syncMethods_.size()) {
|
||||||
syncMethods_.resize(methodIndex + 1);
|
syncMethods_.resize(methodIndex + 1);
|
||||||
}
|
}
|
||||||
syncMethods_.insert(syncMethods_.begin() + methodIndex, MethodInvoker(
|
syncMethods_.insert(
|
||||||
desc->getMethod(),
|
syncMethods_.begin() + methodIndex,
|
||||||
desc->getSignature(),
|
MethodInvoker(
|
||||||
getName() + "." + methodName,
|
desc->getMethod(),
|
||||||
true
|
desc->getSignature(),
|
||||||
));
|
getName() + "." + methodName,
|
||||||
|
true));
|
||||||
}
|
}
|
||||||
|
|
||||||
ret.emplace_back(
|
ret.emplace_back(std::move(methodName), std::move(methodType));
|
||||||
std::move(methodName),
|
|
||||||
std::move(methodType)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
folly::dynamic JavaNativeModule::getConstants() {
|
folly::dynamic JavaNativeModule::getConstants() {
|
||||||
static auto constantsMethod =
|
static auto constantsMethod =
|
||||||
wrapper_->getClass()->getMethod<NativeMap::javaobject()>("getConstants");
|
wrapper_->getClass()->getMethod<NativeMap::javaobject()>("getConstants");
|
||||||
auto constants = constantsMethod(wrapper_);
|
auto constants = constantsMethod(wrapper_);
|
||||||
if (!constants) {
|
if (!constants) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -90,46 +90,60 @@ folly::dynamic JavaNativeModule::getConstants() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void JavaNativeModule::invoke(unsigned int reactMethodId, folly::dynamic&& params, int callId) {
|
void JavaNativeModule::invoke(
|
||||||
messageQueueThread_->runOnQueue([this, reactMethodId, params=std::move(params), callId] {
|
unsigned int reactMethodId,
|
||||||
static auto invokeMethod = wrapper_->getClass()->getMethod<void(jint, ReadableNativeArray::javaobject)>("invoke");
|
folly::dynamic &¶ms,
|
||||||
#ifdef WITH_FBSYSTRACE
|
int callId) {
|
||||||
if (callId != -1) {
|
messageQueueThread_->runOnQueue(
|
||||||
fbsystrace_end_async_flow(TRACE_TAG_REACT_APPS, "native", callId);
|
[this, reactMethodId, params = std::move(params), callId] {
|
||||||
}
|
static auto invokeMethod =
|
||||||
#endif
|
wrapper_->getClass()
|
||||||
invokeMethod(
|
->getMethod<void(jint, ReadableNativeArray::javaobject)>(
|
||||||
wrapper_,
|
"invoke");
|
||||||
static_cast<jint>(reactMethodId),
|
#ifdef WITH_FBSYSTRACE
|
||||||
ReadableNativeArray::newObjectCxxArgs(std::move(params)).get());
|
if (callId != -1) {
|
||||||
});
|
fbsystrace_end_async_flow(TRACE_TAG_REACT_APPS, "native", callId);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
invokeMethod(
|
||||||
|
wrapper_,
|
||||||
|
static_cast<jint>(reactMethodId),
|
||||||
|
ReadableNativeArray::newObjectCxxArgs(std::move(params)).get());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
MethodCallResult JavaNativeModule::callSerializableNativeHook(unsigned int reactMethodId, folly::dynamic&& params) {
|
MethodCallResult JavaNativeModule::callSerializableNativeHook(
|
||||||
|
unsigned int reactMethodId,
|
||||||
|
folly::dynamic &¶ms) {
|
||||||
// TODO: evaluate whether calling through invoke is potentially faster
|
// TODO: evaluate whether calling through invoke is potentially faster
|
||||||
if (reactMethodId >= syncMethods_.size()) {
|
if (reactMethodId >= syncMethods_.size()) {
|
||||||
throw std::invalid_argument(
|
throw std::invalid_argument(folly::to<std::string>(
|
||||||
folly::to<std::string>("methodId ", reactMethodId, " out of range [0..", syncMethods_.size(), "]"));
|
"methodId ",
|
||||||
|
reactMethodId,
|
||||||
|
" out of range [0..",
|
||||||
|
syncMethods_.size(),
|
||||||
|
"]"));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& method = syncMethods_[reactMethodId];
|
auto &method = syncMethods_[reactMethodId];
|
||||||
CHECK(method.hasValue() && method->isSyncHook()) << "Trying to invoke a asynchronous method as synchronous hook";
|
CHECK(method.hasValue() && method->isSyncHook())
|
||||||
|
<< "Trying to invoke a asynchronous method as synchronous hook";
|
||||||
return method->invoke(instance_, wrapper_->getModule(), params);
|
return method->invoke(instance_, wrapper_->getModule(), params);
|
||||||
}
|
}
|
||||||
|
|
||||||
NewJavaNativeModule::NewJavaNativeModule(
|
NewJavaNativeModule::NewJavaNativeModule(
|
||||||
std::weak_ptr<Instance> instance,
|
std::weak_ptr<Instance> instance,
|
||||||
jni::alias_ref<JavaModuleWrapper::javaobject> wrapper,
|
jni::alias_ref<JavaModuleWrapper::javaobject> wrapper,
|
||||||
std::shared_ptr<MessageQueueThread> messageQueueThread)
|
std::shared_ptr<MessageQueueThread> messageQueueThread)
|
||||||
: instance_(std::move(instance))
|
: instance_(std::move(instance)),
|
||||||
, wrapper_(make_global(wrapper))
|
wrapper_(make_global(wrapper)),
|
||||||
, module_(make_global(wrapper->getModule()))
|
module_(make_global(wrapper->getModule())),
|
||||||
, messageQueueThread_(std::move(messageQueueThread)) {
|
messageQueueThread_(std::move(messageQueueThread)) {
|
||||||
auto descs = wrapper_->getMethodDescriptors();
|
auto descs = wrapper_->getMethodDescriptors();
|
||||||
std::string moduleName = getName();
|
std::string moduleName = getName();
|
||||||
methods_.reserve(descs->size());
|
methods_.reserve(descs->size());
|
||||||
|
|
||||||
for (const auto& desc : *descs) {
|
for (const auto &desc : *descs) {
|
||||||
auto type = desc->getType();
|
auto type = desc->getType();
|
||||||
auto name = desc->getName();
|
auto name = desc->getName();
|
||||||
methods_.emplace_back(
|
methods_.emplace_back(
|
||||||
|
@ -143,7 +157,8 @@ NewJavaNativeModule::NewJavaNativeModule(
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string NewJavaNativeModule::getName() {
|
std::string NewJavaNativeModule::getName() {
|
||||||
static auto getNameMethod = wrapper_->getClass()->getMethod<jstring()>("getName");
|
static auto getNameMethod =
|
||||||
|
wrapper_->getClass()->getMethod<jstring()>("getName");
|
||||||
return getNameMethod(wrapper_)->toStdString();
|
return getNameMethod(wrapper_)->toStdString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,7 +168,7 @@ std::vector<MethodDescriptor> NewJavaNativeModule::getMethods() {
|
||||||
|
|
||||||
folly::dynamic NewJavaNativeModule::getConstants() {
|
folly::dynamic NewJavaNativeModule::getConstants() {
|
||||||
static auto constantsMethod =
|
static auto constantsMethod =
|
||||||
wrapper_->getClass()->getMethod<NativeMap::javaobject()>("getConstants");
|
wrapper_->getClass()->getMethod<NativeMap::javaobject()>("getConstants");
|
||||||
auto constants = constantsMethod(wrapper_);
|
auto constants = constantsMethod(wrapper_);
|
||||||
if (!constants) {
|
if (!constants) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -162,39 +177,59 @@ folly::dynamic NewJavaNativeModule::getConstants() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NewJavaNativeModule::invoke(unsigned int reactMethodId, folly::dynamic&& params, int callId) {
|
void NewJavaNativeModule::invoke(
|
||||||
|
unsigned int reactMethodId,
|
||||||
|
folly::dynamic &¶ms,
|
||||||
|
int callId) {
|
||||||
if (reactMethodId >= methods_.size()) {
|
if (reactMethodId >= methods_.size()) {
|
||||||
throw std::invalid_argument(
|
throw std::invalid_argument(folly::to<std::string>(
|
||||||
folly::to<std::string>("methodId ", reactMethodId, " out of range [0..", methods_.size(), "]"));
|
"methodId ",
|
||||||
|
reactMethodId,
|
||||||
|
" out of range [0..",
|
||||||
|
methods_.size(),
|
||||||
|
"]"));
|
||||||
}
|
}
|
||||||
CHECK(!methods_[reactMethodId].isSyncHook()) << "Trying to invoke a synchronous hook asynchronously";
|
CHECK(!methods_[reactMethodId].isSyncHook())
|
||||||
messageQueueThread_->runOnQueue([this, reactMethodId, params=std::move(params), callId] () mutable {
|
<< "Trying to invoke a synchronous hook asynchronously";
|
||||||
#ifdef WITH_FBSYSTRACE
|
messageQueueThread_->runOnQueue(
|
||||||
if (callId != -1) {
|
[this, reactMethodId, params = std::move(params), callId]() mutable {
|
||||||
fbsystrace_end_async_flow(TRACE_TAG_REACT_APPS, "native", callId);
|
#ifdef WITH_FBSYSTRACE
|
||||||
}
|
if (callId != -1) {
|
||||||
#endif
|
fbsystrace_end_async_flow(TRACE_TAG_REACT_APPS, "native", callId);
|
||||||
invokeInner(reactMethodId, std::move(params));
|
}
|
||||||
});
|
#endif
|
||||||
|
invokeInner(reactMethodId, std::move(params));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
MethodCallResult NewJavaNativeModule::callSerializableNativeHook(unsigned int reactMethodId, folly::dynamic&& params) {
|
MethodCallResult NewJavaNativeModule::callSerializableNativeHook(
|
||||||
|
unsigned int reactMethodId,
|
||||||
|
folly::dynamic &¶ms) {
|
||||||
if (reactMethodId >= methods_.size()) {
|
if (reactMethodId >= methods_.size()) {
|
||||||
throw std::invalid_argument(
|
throw std::invalid_argument(folly::to<std::string>(
|
||||||
folly::to<std::string>("methodId ", reactMethodId, " out of range [0..", methods_.size(), "]"));
|
"methodId ",
|
||||||
|
reactMethodId,
|
||||||
|
" out of range [0..",
|
||||||
|
methods_.size(),
|
||||||
|
"]"));
|
||||||
}
|
}
|
||||||
CHECK(methods_[reactMethodId].isSyncHook()) << "Trying to invoke a asynchronous method as synchronous hook";
|
CHECK(methods_[reactMethodId].isSyncHook())
|
||||||
|
<< "Trying to invoke a asynchronous method as synchronous hook";
|
||||||
return invokeInner(reactMethodId, std::move(params));
|
return invokeInner(reactMethodId, std::move(params));
|
||||||
}
|
}
|
||||||
|
|
||||||
MethodCallResult NewJavaNativeModule::invokeInner(unsigned int reactMethodId, folly::dynamic&& params) {
|
MethodCallResult NewJavaNativeModule::invokeInner(
|
||||||
|
unsigned int reactMethodId,
|
||||||
|
folly::dynamic &¶ms) {
|
||||||
return methods_[reactMethodId].invoke(instance_, module_.get(), params);
|
return methods_[reactMethodId].invoke(instance_, module_.get(), params);
|
||||||
}
|
}
|
||||||
|
|
||||||
jni::local_ref<JReflectMethod::javaobject> JMethodDescriptor::getMethod() const {
|
jni::local_ref<JReflectMethod::javaobject> JMethodDescriptor::getMethod()
|
||||||
static auto method = javaClassStatic()->getField<JReflectMethod::javaobject>("method");
|
const {
|
||||||
|
static auto method =
|
||||||
|
javaClassStatic()->getField<JReflectMethod::javaobject>("method");
|
||||||
return getFieldValue(method);
|
return getFieldValue(method);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace react
|
||||||
}
|
} // namespace facebook
|
||||||
|
|
|
@ -21,7 +21,7 @@ class MessageQueueThread;
|
||||||
|
|
||||||
struct JMethodDescriptor : public jni::JavaClass<JMethodDescriptor> {
|
struct JMethodDescriptor : public jni::JavaClass<JMethodDescriptor> {
|
||||||
static constexpr auto kJavaDescriptor =
|
static constexpr auto kJavaDescriptor =
|
||||||
"Lcom/facebook/react/bridge/JavaModuleWrapper$MethodDescriptor;";
|
"Lcom/facebook/react/bridge/JavaModuleWrapper$MethodDescriptor;";
|
||||||
|
|
||||||
jni::local_ref<JReflectMethod::javaobject> getMethod() const;
|
jni::local_ref<JReflectMethod::javaobject> getMethod() const;
|
||||||
std::string getSignature() const;
|
std::string getSignature() const;
|
||||||
|
@ -30,12 +30,15 @@ struct JMethodDescriptor : public jni::JavaClass<JMethodDescriptor> {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct JavaModuleWrapper : jni::JavaClass<JavaModuleWrapper> {
|
struct JavaModuleWrapper : jni::JavaClass<JavaModuleWrapper> {
|
||||||
static constexpr auto kJavaDescriptor = "Lcom/facebook/react/bridge/JavaModuleWrapper;";
|
static constexpr auto kJavaDescriptor =
|
||||||
|
"Lcom/facebook/react/bridge/JavaModuleWrapper;";
|
||||||
|
|
||||||
jni::local_ref<JBaseJavaModule::javaobject> getModule() {
|
jni::local_ref<JBaseJavaModule::javaobject> getModule() {
|
||||||
// This is the call which causes a lazy Java module to actually be
|
// This is the call which causes a lazy Java module to actually be
|
||||||
// created.
|
// created.
|
||||||
static auto getModule = javaClassStatic()->getMethod<JBaseJavaModule::javaobject()>("getModule");
|
static auto getModule =
|
||||||
|
javaClassStatic()->getMethod<JBaseJavaModule::javaobject()>(
|
||||||
|
"getModule");
|
||||||
return getModule(self());
|
return getModule(self());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,9 +47,13 @@ struct JavaModuleWrapper : jni::JavaClass<JavaModuleWrapper> {
|
||||||
return getName(self())->toStdString();
|
return getName(self())->toStdString();
|
||||||
}
|
}
|
||||||
|
|
||||||
jni::local_ref<jni::JList<JMethodDescriptor::javaobject>::javaobject> getMethodDescriptors() {
|
jni::local_ref<jni::JList<JMethodDescriptor::javaobject>::javaobject>
|
||||||
static auto getMethods = getClass()
|
getMethodDescriptors() {
|
||||||
->getMethod<jni::JList<JMethodDescriptor::javaobject>::javaobject()>("getMethodDescriptors");
|
static auto getMethods =
|
||||||
|
getClass()
|
||||||
|
->getMethod<
|
||||||
|
jni::JList<JMethodDescriptor::javaobject>::javaobject()>(
|
||||||
|
"getMethodDescriptors");
|
||||||
return getMethods(self());
|
return getMethods(self());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -54,18 +61,21 @@ struct JavaModuleWrapper : jni::JavaClass<JavaModuleWrapper> {
|
||||||
class JavaNativeModule : public NativeModule {
|
class JavaNativeModule : public NativeModule {
|
||||||
public:
|
public:
|
||||||
JavaNativeModule(
|
JavaNativeModule(
|
||||||
std::weak_ptr<Instance> instance,
|
std::weak_ptr<Instance> instance,
|
||||||
jni::alias_ref<JavaModuleWrapper::javaobject> wrapper,
|
jni::alias_ref<JavaModuleWrapper::javaobject> wrapper,
|
||||||
std::shared_ptr<MessageQueueThread> messageQueueThread)
|
std::shared_ptr<MessageQueueThread> messageQueueThread)
|
||||||
: instance_(std::move(instance))
|
: instance_(std::move(instance)),
|
||||||
, wrapper_(make_global(wrapper))
|
wrapper_(make_global(wrapper)),
|
||||||
, messageQueueThread_(std::move(messageQueueThread)) {}
|
messageQueueThread_(std::move(messageQueueThread)) {}
|
||||||
|
|
||||||
std::string getName() override;
|
std::string getName() override;
|
||||||
folly::dynamic getConstants() override;
|
folly::dynamic getConstants() override;
|
||||||
std::vector<MethodDescriptor> getMethods() override;
|
std::vector<MethodDescriptor> getMethods() override;
|
||||||
void invoke(unsigned int reactMethodId, folly::dynamic&& params, int callId) override;
|
void invoke(unsigned int reactMethodId, folly::dynamic &¶ms, int callId)
|
||||||
MethodCallResult callSerializableNativeHook(unsigned int reactMethodId, folly::dynamic&& params) override;
|
override;
|
||||||
|
MethodCallResult callSerializableNativeHook(
|
||||||
|
unsigned int reactMethodId,
|
||||||
|
folly::dynamic &¶ms) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::weak_ptr<Instance> instance_;
|
std::weak_ptr<Instance> instance_;
|
||||||
|
@ -78,15 +88,18 @@ class JavaNativeModule : public NativeModule {
|
||||||
class NewJavaNativeModule : public NativeModule {
|
class NewJavaNativeModule : public NativeModule {
|
||||||
public:
|
public:
|
||||||
NewJavaNativeModule(
|
NewJavaNativeModule(
|
||||||
std::weak_ptr<Instance> instance,
|
std::weak_ptr<Instance> instance,
|
||||||
jni::alias_ref<JavaModuleWrapper::javaobject> wrapper,
|
jni::alias_ref<JavaModuleWrapper::javaobject> wrapper,
|
||||||
std::shared_ptr<MessageQueueThread> messageQueueThread);
|
std::shared_ptr<MessageQueueThread> messageQueueThread);
|
||||||
|
|
||||||
std::string getName() override;
|
std::string getName() override;
|
||||||
std::vector<MethodDescriptor> getMethods() override;
|
std::vector<MethodDescriptor> getMethods() override;
|
||||||
folly::dynamic getConstants() override;
|
folly::dynamic getConstants() override;
|
||||||
void invoke(unsigned int reactMethodId, folly::dynamic&& params, int callId) override;
|
void invoke(unsigned int reactMethodId, folly::dynamic &¶ms, int callId)
|
||||||
MethodCallResult callSerializableNativeHook(unsigned int reactMethodId, folly::dynamic&& params) override;
|
override;
|
||||||
|
MethodCallResult callSerializableNativeHook(
|
||||||
|
unsigned int reactMethodId,
|
||||||
|
folly::dynamic &¶ms) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::weak_ptr<Instance> instance_;
|
std::weak_ptr<Instance> instance_;
|
||||||
|
@ -96,7 +109,10 @@ class NewJavaNativeModule : public NativeModule {
|
||||||
std::vector<MethodInvoker> methods_;
|
std::vector<MethodInvoker> methods_;
|
||||||
std::vector<MethodDescriptor> methodDescriptors_;
|
std::vector<MethodDescriptor> methodDescriptors_;
|
||||||
|
|
||||||
MethodCallResult invokeInner(unsigned int reactMethodId, folly::dynamic&& params);
|
MethodCallResult invokeInner(
|
||||||
|
unsigned int reactMethodId,
|
||||||
|
folly::dynamic &¶ms);
|
||||||
};
|
};
|
||||||
|
|
||||||
}}
|
} // namespace react
|
||||||
|
} // namespace facebook
|
||||||
|
|
|
@ -13,10 +13,11 @@
|
||||||
namespace facebook {
|
namespace facebook {
|
||||||
namespace react {
|
namespace react {
|
||||||
|
|
||||||
class JavaScriptExecutorHolder : public jni::HybridClass<JavaScriptExecutorHolder> {
|
class JavaScriptExecutorHolder
|
||||||
|
: public jni::HybridClass<JavaScriptExecutorHolder> {
|
||||||
public:
|
public:
|
||||||
static constexpr auto kJavaDescriptor =
|
static constexpr auto kJavaDescriptor =
|
||||||
"Lcom/facebook/react/bridge/JavaScriptExecutor;";
|
"Lcom/facebook/react/bridge/JavaScriptExecutor;";
|
||||||
|
|
||||||
std::shared_ptr<JSExecutorFactory> getExecutorFactory() {
|
std::shared_ptr<JSExecutorFactory> getExecutorFactory() {
|
||||||
return mExecutorFactory;
|
return mExecutorFactory;
|
||||||
|
@ -30,4 +31,5 @@ class JavaScriptExecutorHolder : public jni::HybridClass<JavaScriptExecutorHolde
|
||||||
std::shared_ptr<JSExecutorFactory> mExecutorFactory;
|
std::shared_ptr<JSExecutorFactory> mExecutorFactory;
|
||||||
};
|
};
|
||||||
|
|
||||||
}}
|
} // namespace react
|
||||||
|
} // namespace facebook
|
||||||
|
|
|
@ -32,9 +32,12 @@ namespace {
|
||||||
using dynamic_iterator = folly::dynamic::const_iterator;
|
using dynamic_iterator = folly::dynamic::const_iterator;
|
||||||
|
|
||||||
struct JPromiseImpl : public JavaClass<JPromiseImpl> {
|
struct JPromiseImpl : public JavaClass<JPromiseImpl> {
|
||||||
constexpr static auto kJavaDescriptor = "Lcom/facebook/react/bridge/PromiseImpl;";
|
constexpr static auto kJavaDescriptor =
|
||||||
|
"Lcom/facebook/react/bridge/PromiseImpl;";
|
||||||
|
|
||||||
static local_ref<javaobject> create(local_ref<JCallback::javaobject> resolve, local_ref<JCallback::javaobject> reject) {
|
static local_ref<javaobject> create(
|
||||||
|
local_ref<JCallback::javaobject> resolve,
|
||||||
|
local_ref<JCallback::javaobject> reject) {
|
||||||
return newInstance(resolve, reject);
|
return newInstance(resolve, reject);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -42,10 +45,10 @@ struct JPromiseImpl : public JavaClass<JPromiseImpl> {
|
||||||
// HACK: Exposes constructor
|
// HACK: Exposes constructor
|
||||||
struct ExposedReadableNativeArray : public ReadableNativeArray {
|
struct ExposedReadableNativeArray : public ReadableNativeArray {
|
||||||
explicit ExposedReadableNativeArray(folly::dynamic array)
|
explicit ExposedReadableNativeArray(folly::dynamic array)
|
||||||
: ReadableNativeArray(std::move(array)) {}
|
: ReadableNativeArray(std::move(array)) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
jdouble extractDouble(const folly::dynamic& value) {
|
jdouble extractDouble(const folly::dynamic &value) {
|
||||||
if (value.isInt()) {
|
if (value.isInt()) {
|
||||||
return static_cast<jdouble>(value.getInt());
|
return static_cast<jdouble>(value.getInt());
|
||||||
} else {
|
} else {
|
||||||
|
@ -53,7 +56,7 @@ jdouble extractDouble(const folly::dynamic& value) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
jint extractInteger(const folly::dynamic& value) {
|
jint extractInteger(const folly::dynamic &value) {
|
||||||
// The logic here is taken from convertDynamicIfIntegral, but the
|
// The logic here is taken from convertDynamicIfIntegral, but the
|
||||||
// return type and exception are different.
|
// return type and exception are different.
|
||||||
if (value.isInt()) {
|
if (value.isInt()) {
|
||||||
|
@ -62,14 +65,16 @@ jint extractInteger(const folly::dynamic& value) {
|
||||||
double dbl = value.getDouble();
|
double dbl = value.getDouble();
|
||||||
jint result = static_cast<jint>(dbl);
|
jint result = static_cast<jint>(dbl);
|
||||||
if (dbl != result) {
|
if (dbl != result) {
|
||||||
throw std::invalid_argument(
|
throw std::invalid_argument(folly::to<std::string>(
|
||||||
folly::to<std::string>(
|
"Tried to convert jint argument, but got a non-integral double: ",
|
||||||
"Tried to convert jint argument, but got a non-integral double: ", dbl));
|
dbl));
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
local_ref<JCxxCallbackImpl::jhybridobject> extractCallback(std::weak_ptr<Instance>& instance, const folly::dynamic& value) {
|
local_ref<JCxxCallbackImpl::jhybridobject> extractCallback(
|
||||||
|
std::weak_ptr<Instance> &instance,
|
||||||
|
const folly::dynamic &value) {
|
||||||
if (value.isNull()) {
|
if (value.isNull()) {
|
||||||
return local_ref<JCxxCallbackImpl::jhybridobject>(nullptr);
|
return local_ref<JCxxCallbackImpl::jhybridobject>(nullptr);
|
||||||
} else {
|
} else {
|
||||||
|
@ -77,7 +82,10 @@ local_ref<JCxxCallbackImpl::jhybridobject> extractCallback(std::weak_ptr<Instanc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
local_ref<JPromiseImpl::javaobject> extractPromise(std::weak_ptr<Instance>& instance, dynamic_iterator& it, dynamic_iterator& end) {
|
local_ref<JPromiseImpl::javaobject> extractPromise(
|
||||||
|
std::weak_ptr<Instance> &instance,
|
||||||
|
dynamic_iterator &it,
|
||||||
|
dynamic_iterator &end) {
|
||||||
auto resolve = extractCallback(instance, *it++);
|
auto resolve = extractCallback(instance, *it++);
|
||||||
CHECK(it != end);
|
CHECK(it != end);
|
||||||
auto reject = extractCallback(instance, *it++);
|
auto reject = extractCallback(instance, *it++);
|
||||||
|
@ -95,11 +103,16 @@ bool isNullable(char type) {
|
||||||
case 'X':
|
case 'X':
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
return false;;
|
return false;
|
||||||
|
;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
jvalue extract(std::weak_ptr<Instance>& instance, char type, dynamic_iterator& it, dynamic_iterator& end) {
|
jvalue extract(
|
||||||
|
std::weak_ptr<Instance> &instance,
|
||||||
|
char type,
|
||||||
|
dynamic_iterator &it,
|
||||||
|
dynamic_iterator &end) {
|
||||||
CHECK(it != end);
|
CHECK(it != end);
|
||||||
jvalue value;
|
jvalue value;
|
||||||
if (type == 'P') {
|
if (type == 'P') {
|
||||||
|
@ -107,7 +120,7 @@ jvalue extract(std::weak_ptr<Instance>& instance, char type, dynamic_iterator& i
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto& arg = *it++;
|
const auto &arg = *it++;
|
||||||
if (isNullable(type) && arg.isNull()) {
|
if (isNullable(type) && arg.isNull()) {
|
||||||
value.l = nullptr;
|
value.l = nullptr;
|
||||||
return value;
|
return value;
|
||||||
|
@ -118,7 +131,8 @@ jvalue extract(std::weak_ptr<Instance>& instance, char type, dynamic_iterator& i
|
||||||
value.z = static_cast<jboolean>(arg.getBool());
|
value.z = static_cast<jboolean>(arg.getBool());
|
||||||
break;
|
break;
|
||||||
case 'Z':
|
case 'Z':
|
||||||
value.l = JBoolean::valueOf(static_cast<jboolean>(arg.getBool())).release();
|
value.l =
|
||||||
|
JBoolean::valueOf(static_cast<jboolean>(arg.getBool())).release();
|
||||||
break;
|
break;
|
||||||
case 'i':
|
case 'i':
|
||||||
value.i = extractInteger(arg);
|
value.i = extractInteger(arg);
|
||||||
|
@ -130,7 +144,8 @@ jvalue extract(std::weak_ptr<Instance>& instance, char type, dynamic_iterator& i
|
||||||
value.f = static_cast<jfloat>(extractDouble(arg));
|
value.f = static_cast<jfloat>(extractDouble(arg));
|
||||||
break;
|
break;
|
||||||
case 'F':
|
case 'F':
|
||||||
value.l = JFloat::valueOf(static_cast<jfloat>(extractDouble(arg))).release();
|
value.l =
|
||||||
|
JFloat::valueOf(static_cast<jfloat>(extractDouble(arg))).release();
|
||||||
break;
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
value.d = extractDouble(arg);
|
value.d = extractDouble(arg);
|
||||||
|
@ -156,7 +171,7 @@ jvalue extract(std::weak_ptr<Instance>& instance, char type, dynamic_iterator& i
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t countJsArgs(const std::string& signature) {
|
std::size_t countJsArgs(const std::string &signature) {
|
||||||
std::size_t count = 0;
|
std::size_t count = 0;
|
||||||
for (char c : signature) {
|
for (char c : signature) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
|
@ -171,29 +186,38 @@ std::size_t countJsArgs(const std::string& signature) {
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
MethodInvoker::MethodInvoker(
|
||||||
|
alias_ref<JReflectMethod::javaobject> method,
|
||||||
|
std::string signature,
|
||||||
|
std::string traceName,
|
||||||
|
bool isSync)
|
||||||
|
: method_(method->getMethodID()),
|
||||||
|
signature_(signature),
|
||||||
|
jsArgCount_(countJsArgs(signature) - 2),
|
||||||
|
traceName_(std::move(traceName)),
|
||||||
|
isSync_(isSync) {
|
||||||
|
CHECK(signature_.at(1) == '.') << "Improper module method signature";
|
||||||
|
CHECK(isSync_ || signature_.at(0) == 'v')
|
||||||
|
<< "Non-sync hooks cannot have a non-void return type";
|
||||||
}
|
}
|
||||||
|
|
||||||
MethodInvoker::MethodInvoker(alias_ref<JReflectMethod::javaobject> method, std::string signature, std::string traceName, bool isSync)
|
MethodCallResult MethodInvoker::invoke(
|
||||||
: method_(method->getMethodID()),
|
std::weak_ptr<Instance> &instance,
|
||||||
signature_(signature),
|
alias_ref<JBaseJavaModule::javaobject> module,
|
||||||
jsArgCount_(countJsArgs(signature) -2),
|
const folly::dynamic ¶ms) {
|
||||||
traceName_(std::move(traceName)),
|
#ifdef WITH_FBSYSTRACE
|
||||||
isSync_(isSync) {
|
|
||||||
CHECK(signature_.at(1) == '.') << "Improper module method signature";
|
|
||||||
CHECK(isSync_ || signature_.at(0) == 'v') << "Non-sync hooks cannot have a non-void return type";
|
|
||||||
}
|
|
||||||
|
|
||||||
MethodCallResult MethodInvoker::invoke(std::weak_ptr<Instance>& instance, alias_ref<JBaseJavaModule::javaobject> module, const folly::dynamic& params) {
|
|
||||||
#ifdef WITH_FBSYSTRACE
|
|
||||||
fbsystrace::FbSystraceSection s(
|
fbsystrace::FbSystraceSection s(
|
||||||
TRACE_TAG_REACT_CXX_BRIDGE,
|
TRACE_TAG_REACT_CXX_BRIDGE,
|
||||||
isSync_ ? "callJavaSyncHook" : "callJavaModuleMethod",
|
isSync_ ? "callJavaSyncHook" : "callJavaModuleMethod",
|
||||||
"method",
|
"method",
|
||||||
traceName_);
|
traceName_);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (params.size() != jsArgCount_) {
|
if (params.size() != jsArgCount_) {
|
||||||
throw std::invalid_argument(folly::to<std::string>("expected ", jsArgCount_, " arguments, got ", params.size()));
|
throw std::invalid_argument(folly::to<std::string>(
|
||||||
|
"expected ", jsArgCount_, " arguments, got ", params.size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto env = Environment::current();
|
auto env = Environment::current();
|
||||||
|
@ -201,44 +225,48 @@ MethodCallResult MethodInvoker::invoke(std::weak_ptr<Instance>& instance, alias_
|
||||||
JniLocalScope scope(env, argCount);
|
JniLocalScope scope(env, argCount);
|
||||||
jvalue args[argCount];
|
jvalue args[argCount];
|
||||||
std::transform(
|
std::transform(
|
||||||
signature_.begin() + 2,
|
signature_.begin() + 2,
|
||||||
signature_.end(),
|
signature_.end(),
|
||||||
args,
|
args,
|
||||||
[&instance, it = params.begin(), end = params.end()] (char type) mutable {
|
[&instance, it = params.begin(), end = params.end()](char type) mutable {
|
||||||
return extract(instance, type, it, end);
|
return extract(instance, type, it, end);
|
||||||
});
|
});
|
||||||
|
|
||||||
#define PRIMITIVE_CASE(METHOD) { \
|
#define PRIMITIVE_CASE(METHOD) \
|
||||||
auto result = env->Call ## METHOD ## MethodA(module.get(), method_, args); \
|
{ \
|
||||||
throwPendingJniExceptionAsCppException(); \
|
auto result = env->Call##METHOD##MethodA(module.get(), method_, args); \
|
||||||
return folly::dynamic(result); \
|
throwPendingJniExceptionAsCppException(); \
|
||||||
}
|
return folly::dynamic(result); \
|
||||||
|
}
|
||||||
|
|
||||||
#define PRIMITIVE_CASE_CASTING(METHOD, RESULT_TYPE) { \
|
#define PRIMITIVE_CASE_CASTING(METHOD, RESULT_TYPE) \
|
||||||
auto result = env->Call ## METHOD ## MethodA(module.get(), method_, args); \
|
{ \
|
||||||
throwPendingJniExceptionAsCppException(); \
|
auto result = env->Call##METHOD##MethodA(module.get(), method_, args); \
|
||||||
return folly::dynamic(static_cast<RESULT_TYPE>(result)); \
|
throwPendingJniExceptionAsCppException(); \
|
||||||
}
|
return folly::dynamic(static_cast<RESULT_TYPE>(result)); \
|
||||||
|
}
|
||||||
|
|
||||||
#define OBJECT_CASE(JNI_CLASS, ACTIONS) { \
|
#define OBJECT_CASE(JNI_CLASS, ACTIONS) \
|
||||||
auto jobject = env->CallObjectMethodA(module.get(), method_, args); \
|
{ \
|
||||||
throwPendingJniExceptionAsCppException(); \
|
auto jobject = env->CallObjectMethodA(module.get(), method_, args); \
|
||||||
if (!jobject) { \
|
throwPendingJniExceptionAsCppException(); \
|
||||||
return folly::dynamic(nullptr); \
|
if (!jobject) { \
|
||||||
} \
|
return folly::dynamic(nullptr); \
|
||||||
auto result = adopt_local(static_cast<JNI_CLASS::javaobject>(jobject)); \
|
} \
|
||||||
return folly::dynamic(result->ACTIONS()); \
|
auto result = adopt_local(static_cast<JNI_CLASS::javaobject>(jobject)); \
|
||||||
}
|
return folly::dynamic(result->ACTIONS()); \
|
||||||
|
}
|
||||||
|
|
||||||
#define OBJECT_CASE_CASTING(JNI_CLASS, ACTIONS, RESULT_TYPE) { \
|
#define OBJECT_CASE_CASTING(JNI_CLASS, ACTIONS, RESULT_TYPE) \
|
||||||
auto jobject = env->CallObjectMethodA(module.get(), method_, args); \
|
{ \
|
||||||
throwPendingJniExceptionAsCppException(); \
|
auto jobject = env->CallObjectMethodA(module.get(), method_, args); \
|
||||||
if (!jobject) { \
|
throwPendingJniExceptionAsCppException(); \
|
||||||
return folly::dynamic(nullptr); \
|
if (!jobject) { \
|
||||||
} \
|
return folly::dynamic(nullptr); \
|
||||||
auto result = adopt_local(static_cast<JNI_CLASS::javaobject>(jobject)); \
|
} \
|
||||||
return folly::dynamic(static_cast<RESULT_TYPE>(result->ACTIONS())); \
|
auto result = adopt_local(static_cast<JNI_CLASS::javaobject>(jobject)); \
|
||||||
}
|
return folly::dynamic(static_cast<RESULT_TYPE>(result->ACTIONS())); \
|
||||||
|
}
|
||||||
|
|
||||||
char returnType = signature_.at(0);
|
char returnType = signature_.at(0);
|
||||||
switch (returnType) {
|
switch (returnType) {
|
||||||
|
@ -277,5 +305,5 @@ MethodCallResult MethodInvoker::invoke(std::weak_ptr<Instance>& instance, alias_
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace react
|
||||||
}
|
} // namespace facebook
|
||||||
|
|
|
@ -29,19 +29,28 @@ struct JReflectMethod : public jni::JavaClass<JReflectMethod> {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct JBaseJavaModule : public jni::JavaClass<JBaseJavaModule> {
|
struct JBaseJavaModule : public jni::JavaClass<JBaseJavaModule> {
|
||||||
static constexpr auto kJavaDescriptor = "Lcom/facebook/react/bridge/BaseJavaModule;";
|
static constexpr auto kJavaDescriptor =
|
||||||
|
"Lcom/facebook/react/bridge/BaseJavaModule;";
|
||||||
};
|
};
|
||||||
|
|
||||||
class MethodInvoker {
|
class MethodInvoker {
|
||||||
public:
|
public:
|
||||||
MethodInvoker(jni::alias_ref<JReflectMethod::javaobject> method, std::string signature, std::string traceName, bool isSync);
|
MethodInvoker(
|
||||||
|
jni::alias_ref<JReflectMethod::javaobject> method,
|
||||||
|
std::string signature,
|
||||||
|
std::string traceName,
|
||||||
|
bool isSync);
|
||||||
|
|
||||||
MethodCallResult invoke(std::weak_ptr<Instance>& instance, jni::alias_ref<JBaseJavaModule::javaobject> module, const folly::dynamic& params);
|
MethodCallResult invoke(
|
||||||
|
std::weak_ptr<Instance> &instance,
|
||||||
|
jni::alias_ref<JBaseJavaModule::javaobject> module,
|
||||||
|
const folly::dynamic ¶ms);
|
||||||
|
|
||||||
bool isSyncHook() const {
|
bool isSyncHook() const {
|
||||||
return isSync_;
|
return isSync_;
|
||||||
}
|
}
|
||||||
private:
|
|
||||||
|
private:
|
||||||
jmethodID method_;
|
jmethodID method_;
|
||||||
std::string signature_;
|
std::string signature_;
|
||||||
std::size_t jsArgCount_;
|
std::size_t jsArgCount_;
|
||||||
|
@ -49,5 +58,5 @@ private:
|
||||||
bool isSync_;
|
bool isSync_;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace react
|
||||||
}
|
} // namespace facebook
|
||||||
|
|
|
@ -22,16 +22,19 @@ class MessageQueueThread;
|
||||||
class ModuleHolder : public jni::JavaClass<ModuleHolder> {
|
class ModuleHolder : public jni::JavaClass<ModuleHolder> {
|
||||||
public:
|
public:
|
||||||
static auto constexpr kJavaDescriptor =
|
static auto constexpr kJavaDescriptor =
|
||||||
"Lcom/facebook/react/bridge/ModuleHolder;";
|
"Lcom/facebook/react/bridge/ModuleHolder;";
|
||||||
|
|
||||||
std::string getName() const;
|
std::string getName() const;
|
||||||
xplat::module::CxxModule::Provider getProvider(const std::string& moduleName) const;
|
xplat::module::CxxModule::Provider getProvider(
|
||||||
|
const std::string &moduleName) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<std::unique_ptr<NativeModule>> buildNativeModuleList(
|
std::vector<std::unique_ptr<NativeModule>> buildNativeModuleList(
|
||||||
std::weak_ptr<Instance> winstance,
|
std::weak_ptr<Instance> winstance,
|
||||||
jni::alias_ref<jni::JCollection<JavaModuleWrapper::javaobject>::javaobject> javaModules,
|
jni::alias_ref<jni::JCollection<JavaModuleWrapper::javaobject>::javaobject>
|
||||||
jni::alias_ref<jni::JCollection<ModuleHolder::javaobject>::javaobject> cxxModules,
|
javaModules,
|
||||||
std::shared_ptr<MessageQueueThread> moduleMessageQueue);
|
jni::alias_ref<jni::JCollection<ModuleHolder::javaobject>::javaobject>
|
||||||
}
|
cxxModules,
|
||||||
}
|
std::shared_ptr<MessageQueueThread> moduleMessageQueue);
|
||||||
|
} // namespace react
|
||||||
|
} // namespace facebook
|
||||||
|
|
|
@ -18,8 +18,10 @@ namespace react {
|
||||||
NativeArray::NativeArray(folly::dynamic array)
|
NativeArray::NativeArray(folly::dynamic array)
|
||||||
: isConsumed(false), array_(std::move(array)) {
|
: isConsumed(false), array_(std::move(array)) {
|
||||||
if (!array_.isArray()) {
|
if (!array_.isArray()) {
|
||||||
throwNewJavaException(exceptions::gUnexpectedNativeTypeExceptionClass,
|
throwNewJavaException(
|
||||||
"expected Array, got a %s", array_.typeName());
|
exceptions::gUnexpectedNativeTypeExceptionClass,
|
||||||
|
"expected Array, got a %s",
|
||||||
|
array_.typeName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,7 +32,7 @@ local_ref<jstring> NativeArray::toString() {
|
||||||
|
|
||||||
void NativeArray::registerNatives() {
|
void NativeArray::registerNatives() {
|
||||||
registerHybrid({
|
registerHybrid({
|
||||||
makeNativeMethod("toString", NativeArray::toString),
|
makeNativeMethod("toString", NativeArray::toString),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,5 +46,5 @@ void NativeArray::throwIfConsumed() {
|
||||||
exceptions::throwIfObjectAlreadyConsumed(this, "Array already consumed");
|
exceptions::throwIfObjectAlreadyConsumed(this, "Array already consumed");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace react
|
||||||
}
|
} // namespace facebook
|
||||||
|
|
|
@ -17,7 +17,8 @@ namespace react {
|
||||||
|
|
||||||
class NativeArray : public jni::HybridClass<NativeArray> {
|
class NativeArray : public jni::HybridClass<NativeArray> {
|
||||||
public:
|
public:
|
||||||
static constexpr const char* kJavaDescriptor = "Lcom/facebook/react/bridge/NativeArray;";
|
static constexpr const char *kJavaDescriptor =
|
||||||
|
"Lcom/facebook/react/bridge/NativeArray;";
|
||||||
|
|
||||||
jni::local_ref<jstring> toString();
|
jni::local_ref<jstring> toString();
|
||||||
|
|
||||||
|
@ -37,4 +38,5 @@ class NativeArray : public jni::HybridClass<NativeArray> {
|
||||||
explicit NativeArray(folly::dynamic array);
|
explicit NativeArray(folly::dynamic array);
|
||||||
};
|
};
|
||||||
|
|
||||||
}}
|
} // namespace react
|
||||||
|
} // namespace facebook
|
||||||
|
|
|
@ -18,7 +18,8 @@ namespace facebook {
|
||||||
namespace react {
|
namespace react {
|
||||||
|
|
||||||
struct ReadableType : public jni::JavaClass<ReadableType> {
|
struct ReadableType : public jni::JavaClass<ReadableType> {
|
||||||
static auto constexpr kJavaDescriptor = "Lcom/facebook/react/bridge/ReadableType;";
|
static auto constexpr kJavaDescriptor =
|
||||||
|
"Lcom/facebook/react/bridge/ReadableType;";
|
||||||
|
|
||||||
static jni::local_ref<ReadableType> getType(folly::dynamic::Type type);
|
static jni::local_ref<ReadableType> getType(folly::dynamic::Type type);
|
||||||
};
|
};
|
||||||
|
@ -28,9 +29,10 @@ namespace exceptions {
|
||||||
extern const char *gUnexpectedNativeTypeExceptionClass;
|
extern const char *gUnexpectedNativeTypeExceptionClass;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void throwIfObjectAlreadyConsumed(const T& t, const char* msg) {
|
void throwIfObjectAlreadyConsumed(const T &t, const char *msg) {
|
||||||
if (t->isConsumed) {
|
if (t->isConsumed) {
|
||||||
jni::throwNewJavaException("com/facebook/react/bridge/ObjectAlreadyConsumedException", msg);
|
jni::throwNewJavaException(
|
||||||
|
"com/facebook/react/bridge/ObjectAlreadyConsumedException", msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,8 @@ namespace react {
|
||||||
|
|
||||||
class NativeMap : public jni::HybridClass<NativeMap> {
|
class NativeMap : public jni::HybridClass<NativeMap> {
|
||||||
public:
|
public:
|
||||||
static auto constexpr kJavaDescriptor = "Lcom/facebook/react/bridge/NativeMap;";
|
static auto constexpr kJavaDescriptor =
|
||||||
|
"Lcom/facebook/react/bridge/NativeMap;";
|
||||||
|
|
||||||
std::string toString();
|
std::string toString();
|
||||||
|
|
||||||
|
@ -38,5 +39,5 @@ class NativeMap : public jni::HybridClass<NativeMap> {
|
||||||
explicit NativeMap(folly::dynamic s) : isConsumed(false), map_(s) {}
|
explicit NativeMap(folly::dynamic s) : isConsumed(false), map_(s) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace react
|
} // namespace react
|
||||||
} // namespace facebook
|
} // namespace facebook
|
||||||
|
|
|
@ -10,8 +10,8 @@
|
||||||
#include <cxxreact/JSBigString.h>
|
#include <cxxreact/JSBigString.h>
|
||||||
#include <cxxreact/ModuleRegistry.h>
|
#include <cxxreact/ModuleRegistry.h>
|
||||||
#include <cxxreact/SystraceSection.h>
|
#include <cxxreact/SystraceSection.h>
|
||||||
#include <fb/assert.h>
|
|
||||||
#include <fb/Environment.h>
|
#include <fb/Environment.h>
|
||||||
|
#include <fb/assert.h>
|
||||||
#include <folly/json.h>
|
#include <folly/json.h>
|
||||||
#include <jni/LocalReference.h>
|
#include <jni/LocalReference.h>
|
||||||
#include <jni/LocalString.h>
|
#include <jni/LocalString.h>
|
||||||
|
@ -25,28 +25,29 @@ const auto EXECUTOR_BASECLASS = "com/facebook/react/bridge/JavaJSExecutor";
|
||||||
|
|
||||||
static std::string executeJSCallWithProxy(
|
static std::string executeJSCallWithProxy(
|
||||||
jobject executor,
|
jobject executor,
|
||||||
const std::string& methodName,
|
const std::string &methodName,
|
||||||
const folly::dynamic& arguments) {
|
const folly::dynamic &arguments) {
|
||||||
static auto executeJSCall =
|
static auto executeJSCall =
|
||||||
jni::findClassStatic(EXECUTOR_BASECLASS)->getMethod<jstring(jstring, jstring)>("executeJSCall");
|
jni::findClassStatic(EXECUTOR_BASECLASS)
|
||||||
|
->getMethod<jstring(jstring, jstring)>("executeJSCall");
|
||||||
|
|
||||||
auto result = executeJSCall(
|
auto result = executeJSCall(
|
||||||
executor,
|
executor,
|
||||||
jni::make_jstring(methodName).get(),
|
jni::make_jstring(methodName).get(),
|
||||||
jni::make_jstring(folly::toJson(arguments).c_str()).get());
|
jni::make_jstring(folly::toJson(arguments).c_str()).get());
|
||||||
return result->toString();
|
return result->toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<JSExecutor> ProxyExecutorOneTimeFactory::createJSExecutor(
|
std::unique_ptr<JSExecutor> ProxyExecutorOneTimeFactory::createJSExecutor(
|
||||||
std::shared_ptr<ExecutorDelegate> delegate, std::shared_ptr<MessageQueueThread>) {
|
std::shared_ptr<ExecutorDelegate> delegate,
|
||||||
|
std::shared_ptr<MessageQueueThread>) {
|
||||||
return std::make_unique<ProxyExecutor>(std::move(m_executor), delegate);
|
return std::make_unique<ProxyExecutor>(std::move(m_executor), delegate);
|
||||||
}
|
}
|
||||||
|
|
||||||
ProxyExecutor::ProxyExecutor(jni::global_ref<jobject>&& executorInstance,
|
ProxyExecutor::ProxyExecutor(
|
||||||
std::shared_ptr<ExecutorDelegate> delegate)
|
jni::global_ref<jobject> &&executorInstance,
|
||||||
: m_executor(std::move(executorInstance))
|
std::shared_ptr<ExecutorDelegate> delegate)
|
||||||
, m_delegate(delegate)
|
: m_executor(std::move(executorInstance)), m_delegate(delegate) {}
|
||||||
{}
|
|
||||||
|
|
||||||
ProxyExecutor::~ProxyExecutor() {
|
ProxyExecutor::~ProxyExecutor() {
|
||||||
m_executor.reset();
|
m_executor.reset();
|
||||||
|
@ -55,79 +56,88 @@ ProxyExecutor::~ProxyExecutor() {
|
||||||
void ProxyExecutor::loadApplicationScript(
|
void ProxyExecutor::loadApplicationScript(
|
||||||
std::unique_ptr<const JSBigString>,
|
std::unique_ptr<const JSBigString>,
|
||||||
std::string sourceURL) {
|
std::string sourceURL) {
|
||||||
|
|
||||||
folly::dynamic nativeModuleConfig = folly::dynamic::array;
|
folly::dynamic nativeModuleConfig = folly::dynamic::array;
|
||||||
|
|
||||||
{
|
{
|
||||||
SystraceSection s("collectNativeModuleDescriptions");
|
SystraceSection s("collectNativeModuleDescriptions");
|
||||||
auto moduleRegistry = m_delegate->getModuleRegistry();
|
auto moduleRegistry = m_delegate->getModuleRegistry();
|
||||||
for (const auto& name : moduleRegistry->moduleNames()) {
|
for (const auto &name : moduleRegistry->moduleNames()) {
|
||||||
auto config = moduleRegistry->getConfig(name);
|
auto config = moduleRegistry->getConfig(name);
|
||||||
nativeModuleConfig.push_back(config ? config->config : nullptr);
|
nativeModuleConfig.push_back(config ? config->config : nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
folly::dynamic config =
|
folly::dynamic config = folly::dynamic::object(
|
||||||
folly::dynamic::object
|
"remoteModuleConfig", std::move(nativeModuleConfig));
|
||||||
("remoteModuleConfig", std::move(nativeModuleConfig));
|
|
||||||
|
|
||||||
{
|
{
|
||||||
SystraceSection t("setGlobalVariable");
|
SystraceSection t("setGlobalVariable");
|
||||||
setGlobalVariable(
|
setGlobalVariable(
|
||||||
"__fbBatchedBridgeConfig",
|
"__fbBatchedBridgeConfig",
|
||||||
std::make_unique<JSBigStdString>(folly::toJson(config)));
|
std::make_unique<JSBigStdString>(folly::toJson(config)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static auto loadApplicationScript =
|
static auto loadApplicationScript =
|
||||||
jni::findClassStatic(EXECUTOR_BASECLASS)->getMethod<void(jstring)>("loadApplicationScript");
|
jni::findClassStatic(EXECUTOR_BASECLASS)
|
||||||
|
->getMethod<void(jstring)>("loadApplicationScript");
|
||||||
|
|
||||||
// The proxy ignores the script data passed in.
|
// The proxy ignores the script data passed in.
|
||||||
|
|
||||||
loadApplicationScript(
|
loadApplicationScript(m_executor.get(), jni::make_jstring(sourceURL).get());
|
||||||
m_executor.get(),
|
|
||||||
jni::make_jstring(sourceURL).get());
|
|
||||||
// We can get pending calls here to native but the queue will be drained when
|
// We can get pending calls here to native but the queue will be drained when
|
||||||
// we launch the application.
|
// we launch the application.
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProxyExecutor::setBundleRegistry(std::unique_ptr<RAMBundleRegistry>) {
|
void ProxyExecutor::setBundleRegistry(std::unique_ptr<RAMBundleRegistry>) {
|
||||||
jni::throwNewJavaException(
|
jni::throwNewJavaException(
|
||||||
"java/lang/UnsupportedOperationException",
|
"java/lang/UnsupportedOperationException",
|
||||||
"Loading application RAM bundles is not supported for proxy executors");
|
"Loading application RAM bundles is not supported for proxy executors");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProxyExecutor::registerBundle(uint32_t bundleId, const std::string& bundlePath) {
|
void ProxyExecutor::registerBundle(
|
||||||
|
uint32_t bundleId,
|
||||||
|
const std::string &bundlePath) {
|
||||||
jni::throwNewJavaException(
|
jni::throwNewJavaException(
|
||||||
"java/lang/UnsupportedOperationException",
|
"java/lang/UnsupportedOperationException",
|
||||||
"Loading application RAM bundles is not supported for proxy executors");
|
"Loading application RAM bundles is not supported for proxy executors");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProxyExecutor::callFunction(const std::string& moduleId, const std::string& methodId, const folly::dynamic& arguments) {
|
void ProxyExecutor::callFunction(
|
||||||
|
const std::string &moduleId,
|
||||||
|
const std::string &methodId,
|
||||||
|
const folly::dynamic &arguments) {
|
||||||
auto call = folly::dynamic::array(moduleId, methodId, std::move(arguments));
|
auto call = folly::dynamic::array(moduleId, methodId, std::move(arguments));
|
||||||
|
|
||||||
std::string result = executeJSCallWithProxy(m_executor.get(), "callFunctionReturnFlushedQueue", std::move(call));
|
std::string result = executeJSCallWithProxy(
|
||||||
|
m_executor.get(), "callFunctionReturnFlushedQueue", std::move(call));
|
||||||
m_delegate->callNativeModules(*this, folly::parseJson(result), true);
|
m_delegate->callNativeModules(*this, folly::parseJson(result), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProxyExecutor::invokeCallback(const double callbackId, const folly::dynamic& arguments) {
|
void ProxyExecutor::invokeCallback(
|
||||||
|
const double callbackId,
|
||||||
|
const folly::dynamic &arguments) {
|
||||||
auto call = folly::dynamic::array(callbackId, std::move(arguments));
|
auto call = folly::dynamic::array(callbackId, std::move(arguments));
|
||||||
std::string result = executeJSCallWithProxy(m_executor.get(), "invokeCallbackAndReturnFlushedQueue", std::move(call));
|
std::string result = executeJSCallWithProxy(
|
||||||
|
m_executor.get(), "invokeCallbackAndReturnFlushedQueue", std::move(call));
|
||||||
m_delegate->callNativeModules(*this, folly::parseJson(result), true);
|
m_delegate->callNativeModules(*this, folly::parseJson(result), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProxyExecutor::setGlobalVariable(std::string propName,
|
void ProxyExecutor::setGlobalVariable(
|
||||||
std::unique_ptr<const JSBigString> jsonValue) {
|
std::string propName,
|
||||||
|
std::unique_ptr<const JSBigString> jsonValue) {
|
||||||
static auto setGlobalVariable =
|
static auto setGlobalVariable =
|
||||||
jni::findClassStatic(EXECUTOR_BASECLASS)->getMethod<void(jstring, jstring)>("setGlobalVariable");
|
jni::findClassStatic(EXECUTOR_BASECLASS)
|
||||||
|
->getMethod<void(jstring, jstring)>("setGlobalVariable");
|
||||||
|
|
||||||
setGlobalVariable(
|
setGlobalVariable(
|
||||||
m_executor.get(),
|
m_executor.get(),
|
||||||
jni::make_jstring(propName).get(),
|
jni::make_jstring(propName).get(),
|
||||||
jni::make_jstring(jsonValue->c_str()).get());
|
jni::make_jstring(jsonValue->c_str()).get());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ProxyExecutor::getDescription() {
|
std::string ProxyExecutor::getDescription() {
|
||||||
return "Chrome";
|
return "Chrome";
|
||||||
}
|
}
|
||||||
|
|
||||||
} }
|
} // namespace react
|
||||||
|
} // namespace facebook
|
||||||
|
|
|
@ -17,48 +17,50 @@ namespace facebook {
|
||||||
namespace react {
|
namespace react {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This executor factory can only create a single executor instance because it moves
|
* This executor factory can only create a single executor instance because it
|
||||||
* executorInstance global reference to the executor instance it creates.
|
* moves executorInstance global reference to the executor instance it creates.
|
||||||
*/
|
*/
|
||||||
class ProxyExecutorOneTimeFactory : public JSExecutorFactory {
|
class ProxyExecutorOneTimeFactory : public JSExecutorFactory {
|
||||||
public:
|
public:
|
||||||
ProxyExecutorOneTimeFactory(jni::global_ref<jobject>&& executorInstance) :
|
ProxyExecutorOneTimeFactory(jni::global_ref<jobject> &&executorInstance)
|
||||||
m_executor(std::move(executorInstance)) {}
|
: m_executor(std::move(executorInstance)) {}
|
||||||
virtual std::unique_ptr<JSExecutor> createJSExecutor(
|
virtual std::unique_ptr<JSExecutor> createJSExecutor(
|
||||||
std::shared_ptr<ExecutorDelegate> delegate,
|
std::shared_ptr<ExecutorDelegate> delegate,
|
||||||
std::shared_ptr<MessageQueueThread> queue) override;
|
std::shared_ptr<MessageQueueThread> queue) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
jni::global_ref<jobject> m_executor;
|
jni::global_ref<jobject> m_executor;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ProxyExecutor : public JSExecutor {
|
class ProxyExecutor : public JSExecutor {
|
||||||
public:
|
public:
|
||||||
ProxyExecutor(jni::global_ref<jobject>&& executorInstance,
|
ProxyExecutor(
|
||||||
std::shared_ptr<ExecutorDelegate> delegate);
|
jni::global_ref<jobject> &&executorInstance,
|
||||||
|
std::shared_ptr<ExecutorDelegate> delegate);
|
||||||
virtual ~ProxyExecutor() override;
|
virtual ~ProxyExecutor() override;
|
||||||
virtual void loadApplicationScript(
|
virtual void loadApplicationScript(
|
||||||
std::unique_ptr<const JSBigString> script,
|
std::unique_ptr<const JSBigString> script,
|
||||||
std::string sourceURL) override;
|
std::string sourceURL) override;
|
||||||
virtual void setBundleRegistry(
|
virtual void setBundleRegistry(
|
||||||
std::unique_ptr<RAMBundleRegistry> bundle) override;
|
std::unique_ptr<RAMBundleRegistry> bundle) override;
|
||||||
virtual void registerBundle(
|
virtual void registerBundle(uint32_t bundleId, const std::string &bundlePath)
|
||||||
uint32_t bundleId, const std::string& bundlePath) override;
|
override;
|
||||||
virtual void callFunction(
|
virtual void callFunction(
|
||||||
const std::string& moduleId,
|
const std::string &moduleId,
|
||||||
const std::string& methodId,
|
const std::string &methodId,
|
||||||
const folly::dynamic& arguments) override;
|
const folly::dynamic &arguments) override;
|
||||||
virtual void invokeCallback(
|
virtual void invokeCallback(
|
||||||
const double callbackId,
|
const double callbackId,
|
||||||
const folly::dynamic& arguments) override;
|
const folly::dynamic &arguments) override;
|
||||||
virtual void setGlobalVariable(
|
virtual void setGlobalVariable(
|
||||||
std::string propName,
|
std::string propName,
|
||||||
std::unique_ptr<const JSBigString> jsonValue) override;
|
std::unique_ptr<const JSBigString> jsonValue) override;
|
||||||
virtual std::string getDescription() override;
|
virtual std::string getDescription() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
jni::global_ref<jobject> m_executor;
|
jni::global_ref<jobject> m_executor;
|
||||||
std::shared_ptr<ExecutorDelegate> m_delegate;
|
std::shared_ptr<ExecutorDelegate> m_delegate;
|
||||||
};
|
};
|
||||||
|
|
||||||
} }
|
} // namespace react
|
||||||
|
} // namespace facebook
|
||||||
|
|
|
@ -19,12 +19,14 @@ namespace react {
|
||||||
struct WritableNativeMap;
|
struct WritableNativeMap;
|
||||||
|
|
||||||
struct WritableArray : jni::JavaClass<WritableArray> {
|
struct WritableArray : jni::JavaClass<WritableArray> {
|
||||||
static auto constexpr kJavaDescriptor = "Lcom/facebook/react/bridge/WritableArray;";
|
static auto constexpr kJavaDescriptor =
|
||||||
|
"Lcom/facebook/react/bridge/WritableArray;";
|
||||||
};
|
};
|
||||||
|
|
||||||
struct WritableNativeArray
|
struct WritableNativeArray
|
||||||
: public jni::HybridClass<WritableNativeArray, ReadableNativeArray> {
|
: public jni::HybridClass<WritableNativeArray, ReadableNativeArray> {
|
||||||
static constexpr const char* kJavaDescriptor = "Lcom/facebook/react/bridge/WritableNativeArray;";
|
static constexpr const char *kJavaDescriptor =
|
||||||
|
"Lcom/facebook/react/bridge/WritableNativeArray;";
|
||||||
|
|
||||||
WritableNativeArray();
|
WritableNativeArray();
|
||||||
static jni::local_ref<jhybriddata> initHybrid(jni::alias_ref<jclass>);
|
static jni::local_ref<jhybriddata> initHybrid(jni::alias_ref<jclass>);
|
||||||
|
@ -34,11 +36,11 @@ struct WritableNativeArray
|
||||||
void pushDouble(jdouble value);
|
void pushDouble(jdouble value);
|
||||||
void pushInt(jint value);
|
void pushInt(jint value);
|
||||||
void pushString(jstring value);
|
void pushString(jstring value);
|
||||||
void pushNativeArray(WritableNativeArray* otherArray);
|
void pushNativeArray(WritableNativeArray *otherArray);
|
||||||
void pushNativeMap(WritableNativeMap* map);
|
void pushNativeMap(WritableNativeMap *map);
|
||||||
|
|
||||||
static void registerNatives();
|
static void registerNatives();
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace react
|
||||||
}
|
} // namespace facebook
|
||||||
|
|
|
@ -18,14 +18,17 @@ namespace facebook {
|
||||||
namespace react {
|
namespace react {
|
||||||
|
|
||||||
struct WritableMap : jni::JavaClass<WritableMap> {
|
struct WritableMap : jni::JavaClass<WritableMap> {
|
||||||
static auto constexpr kJavaDescriptor = "Lcom/facebook/react/bridge/WritableMap;";
|
static auto constexpr kJavaDescriptor =
|
||||||
|
"Lcom/facebook/react/bridge/WritableMap;";
|
||||||
};
|
};
|
||||||
|
|
||||||
struct WritableNativeMap : jni::HybridClass<WritableNativeMap, ReadableNativeMap> {
|
struct WritableNativeMap
|
||||||
static auto constexpr kJavaDescriptor = "Lcom/facebook/react/bridge/WritableNativeMap;";
|
: jni::HybridClass<WritableNativeMap, ReadableNativeMap> {
|
||||||
|
static auto constexpr kJavaDescriptor =
|
||||||
|
"Lcom/facebook/react/bridge/WritableNativeMap;";
|
||||||
|
|
||||||
WritableNativeMap();
|
WritableNativeMap();
|
||||||
WritableNativeMap(folly::dynamic&& val);
|
WritableNativeMap(folly::dynamic &&val);
|
||||||
|
|
||||||
static jni::local_ref<jhybriddata> initHybrid(jni::alias_ref<jclass>);
|
static jni::local_ref<jhybriddata> initHybrid(jni::alias_ref<jclass>);
|
||||||
|
|
||||||
|
@ -34,9 +37,9 @@ struct WritableNativeMap : jni::HybridClass<WritableNativeMap, ReadableNativeMap
|
||||||
void putDouble(std::string key, double val);
|
void putDouble(std::string key, double val);
|
||||||
void putInt(std::string key, int val);
|
void putInt(std::string key, int val);
|
||||||
void putString(std::string key, jni::alias_ref<jstring> val);
|
void putString(std::string key, jni::alias_ref<jstring> val);
|
||||||
void putNativeArray(std::string key, WritableNativeArray* val);
|
void putNativeArray(std::string key, WritableNativeArray *val);
|
||||||
void putNativeMap(std::string key, WritableNativeMap* val);
|
void putNativeMap(std::string key, WritableNativeMap *val);
|
||||||
void mergeNativeMap(ReadableNativeMap* other);
|
void mergeNativeMap(ReadableNativeMap *other);
|
||||||
|
|
||||||
static void registerNatives();
|
static void registerNatives();
|
||||||
|
|
||||||
|
|
|
@ -5,13 +5,13 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <fb/log.h>
|
|
||||||
#include <fb/fbjni.h>
|
|
||||||
#include <cxxreact/CxxModule.h>
|
#include <cxxreact/CxxModule.h>
|
||||||
#include <cxxreact/JsArgumentHelpers.h>
|
#include <cxxreact/JsArgumentHelpers.h>
|
||||||
|
#include <fb/fbjni.h>
|
||||||
|
#include <fb/log.h>
|
||||||
|
|
||||||
#include <mutex>
|
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
namespace facebook {
|
namespace facebook {
|
||||||
namespace react {
|
namespace react {
|
||||||
|
@ -27,9 +27,9 @@ namespace {
|
||||||
// really desperate, you can fix this by using ToReflectedMethod on the
|
// really desperate, you can fix this by using ToReflectedMethod on the
|
||||||
// underlying jmethodid and invoking that.
|
// underlying jmethodid and invoking that.
|
||||||
class JavaJSModule : public jni::JavaClass<JavaJSModule> {
|
class JavaJSModule : public jni::JavaClass<JavaJSModule> {
|
||||||
public:
|
public:
|
||||||
static constexpr auto kJavaDescriptor =
|
static constexpr auto kJavaDescriptor =
|
||||||
"Lcom/facebook/react/CatalystBridgeBenchmarks$BridgeBenchmarkModule;";
|
"Lcom/facebook/react/CatalystBridgeBenchmarks$BridgeBenchmarkModule;";
|
||||||
|
|
||||||
static void bounceCxx(alias_ref<javaobject> obj, int iters) {
|
static void bounceCxx(alias_ref<javaobject> obj, int iters) {
|
||||||
static auto method = javaClassLocal()->getMethod<void(jint)>("bounceCxx");
|
static auto method = javaClassLocal()->getMethod<void(jint)>("bounceCxx");
|
||||||
|
@ -39,20 +39,35 @@ public:
|
||||||
static void bounceArgsCxx(
|
static void bounceArgsCxx(
|
||||||
alias_ref<javaobject> obj,
|
alias_ref<javaobject> obj,
|
||||||
int iters,
|
int iters,
|
||||||
int a, int b,
|
int a,
|
||||||
double x, double y,
|
int b,
|
||||||
const std::string& s, const std::string& t) {
|
double x,
|
||||||
|
double y,
|
||||||
|
const std::string &s,
|
||||||
|
const std::string &t) {
|
||||||
static auto method =
|
static auto method =
|
||||||
javaClassLocal()->getMethod<void(jint, jint, jint, jdouble, jdouble, jstring, jstring)>("bounceArgsCxx");
|
javaClassLocal()
|
||||||
method(obj, iters, a, b, x, y, jni::make_jstring(s).get(), jni::make_jstring(t).get());
|
->getMethod<void(
|
||||||
|
jint, jint, jint, jdouble, jdouble, jstring, jstring)>(
|
||||||
|
"bounceArgsCxx");
|
||||||
|
method(
|
||||||
|
obj,
|
||||||
|
iters,
|
||||||
|
a,
|
||||||
|
b,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
jni::make_jstring(s).get(),
|
||||||
|
jni::make_jstring(t).get());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// This is just the test instance itself. Used only to countdown the latch.
|
// This is just the test instance itself. Used only to countdown the latch.
|
||||||
class CatalystBridgeBenchmarks : public jni::JavaClass<CatalystBridgeBenchmarks> {
|
class CatalystBridgeBenchmarks
|
||||||
public:
|
: public jni::JavaClass<CatalystBridgeBenchmarks> {
|
||||||
|
public:
|
||||||
static constexpr auto kJavaDescriptor =
|
static constexpr auto kJavaDescriptor =
|
||||||
"Lcom/facebook/react/CatalystBridgeBenchmarks;";
|
"Lcom/facebook/react/CatalystBridgeBenchmarks;";
|
||||||
|
|
||||||
static void countDown(alias_ref<javaobject> obj) {
|
static void countDown(alias_ref<javaobject> obj) {
|
||||||
static auto method = javaClassLocal()->getMethod<void()>("countDown");
|
static auto method = javaClassLocal()->getMethod<void()>("countDown");
|
||||||
|
@ -72,7 +87,7 @@ Data data;
|
||||||
void runBounce(jni::alias_ref<jclass>, bool isLeft, int iters) {
|
void runBounce(jni::alias_ref<jclass>, bool isLeft, int iters) {
|
||||||
for (int i = 0; i < iters; i++) {
|
for (int i = 0; i < iters; i++) {
|
||||||
std::unique_lock<std::mutex> lk(data.m);
|
std::unique_lock<std::mutex> lk(data.m);
|
||||||
data.cv.wait(lk, [&]{ return data.leftActive == isLeft; });
|
data.cv.wait(lk, [&] { return data.leftActive == isLeft; });
|
||||||
data.leftActive = !isLeft;
|
data.leftActive = !isLeft;
|
||||||
data.cv.notify_one();
|
data.cv.notify_one();
|
||||||
}
|
}
|
||||||
|
@ -82,30 +97,35 @@ static jni::global_ref<JavaJSModule::javaobject> jsModule;
|
||||||
static jni::global_ref<CatalystBridgeBenchmarks::javaobject> javaTestInstance;
|
static jni::global_ref<CatalystBridgeBenchmarks::javaobject> javaTestInstance;
|
||||||
|
|
||||||
class CxxBenchmarkModule : public xplat::module::CxxModule {
|
class CxxBenchmarkModule : public xplat::module::CxxModule {
|
||||||
public:
|
public:
|
||||||
virtual std::string getName() override {
|
virtual std::string getName() override {
|
||||||
return "CxxBenchmarkModule";
|
return "CxxBenchmarkModule";
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual auto getConstants() -> std::map<std::string, folly::dynamic> override {
|
virtual auto getConstants()
|
||||||
|
-> std::map<std::string, folly::dynamic> override {
|
||||||
return std::map<std::string, folly::dynamic>();
|
return std::map<std::string, folly::dynamic>();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual auto getMethods() -> std::vector<Method> override {
|
virtual auto getMethods() -> std::vector<Method> override {
|
||||||
return std::vector<Method>{
|
return std::vector<Method>{
|
||||||
Method("bounce", [this] (folly::dynamic args) {
|
Method(
|
||||||
this->bounce(xplat::jsArgAsInt(args, 0));
|
"bounce",
|
||||||
}),
|
[this](folly::dynamic args) {
|
||||||
Method("bounceArgs", [this] (folly::dynamic args) {
|
this->bounce(xplat::jsArgAsInt(args, 0));
|
||||||
this->bounceArgs(
|
}),
|
||||||
xplat::jsArgAsInt(args, 0),
|
Method(
|
||||||
xplat::jsArgAsInt(args, 1),
|
"bounceArgs",
|
||||||
xplat::jsArgAsInt(args, 2),
|
[this](folly::dynamic args) {
|
||||||
xplat::jsArgAsDouble(args, 3),
|
this->bounceArgs(
|
||||||
xplat::jsArgAsDouble(args, 4),
|
xplat::jsArgAsInt(args, 0),
|
||||||
xplat::jsArgAsString(args, 5),
|
xplat::jsArgAsInt(args, 1),
|
||||||
xplat::jsArgAsString(args, 6));
|
xplat::jsArgAsInt(args, 2),
|
||||||
}),
|
xplat::jsArgAsDouble(args, 3),
|
||||||
|
xplat::jsArgAsDouble(args, 4),
|
||||||
|
xplat::jsArgAsString(args, 5),
|
||||||
|
xplat::jsArgAsString(args, 6));
|
||||||
|
}),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,9 +139,12 @@ public:
|
||||||
|
|
||||||
void bounceArgs(
|
void bounceArgs(
|
||||||
int iters,
|
int iters,
|
||||||
int a, int b,
|
int a,
|
||||||
double x, double y,
|
int b,
|
||||||
const std::string& s, const std::string& t) {
|
double x,
|
||||||
|
double y,
|
||||||
|
const std::string &s,
|
||||||
|
const std::string &t) {
|
||||||
if (iters == 0) {
|
if (iters == 0) {
|
||||||
CatalystBridgeBenchmarks::countDown(javaTestInstance);
|
CatalystBridgeBenchmarks::countDown(javaTestInstance);
|
||||||
} else {
|
} else {
|
||||||
|
@ -130,7 +153,6 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
void setUp(
|
void setUp(
|
||||||
alias_ref<CatalystBridgeBenchmarks::javaobject> obj,
|
alias_ref<CatalystBridgeBenchmarks::javaobject> obj,
|
||||||
alias_ref<JavaJSModule::javaobject> mod) {
|
alias_ref<JavaJSModule::javaobject> mod) {
|
||||||
|
@ -138,8 +160,7 @@ void setUp(
|
||||||
jsModule = jni::make_global(mod);
|
jsModule = jni::make_global(mod);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tearDown(
|
void tearDown(alias_ref<CatalystBridgeBenchmarks::javaobject>) {
|
||||||
alias_ref<CatalystBridgeBenchmarks::javaobject>) {
|
|
||||||
javaTestInstance.reset();
|
javaTestInstance.reset();
|
||||||
jsModule.reset();
|
jsModule.reset();
|
||||||
}
|
}
|
||||||
|
@ -163,17 +184,21 @@ static void stubLogHandler(int pri, const char *tag, const char *msg) {
|
||||||
gHasSeenMessage |= priorityMatches && substringFound;
|
gHasSeenMessage |= priorityMatches && substringFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
static jboolean hasSeenExpectedLogMessage(JNIEnv*, jclass) {
|
static jboolean hasSeenExpectedLogMessage(JNIEnv *, jclass) {
|
||||||
return gHasSeenMessage ? JNI_TRUE : JNI_FALSE;
|
return gHasSeenMessage ? JNI_TRUE : JNI_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void stopWatchingLogMessages(JNIEnv*, jclass) {
|
static void stopWatchingLogMessages(JNIEnv *, jclass) {
|
||||||
gMessageToLookFor = "";
|
gMessageToLookFor = "";
|
||||||
gHasSeenMessage = false;
|
gHasSeenMessage = false;
|
||||||
setLogHandler(NULL);
|
setLogHandler(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void startWatchingForLogMessage(JNIEnv* env, jclass loggerClass, jstring jmsg, jint priority) {
|
static void startWatchingForLogMessage(
|
||||||
|
JNIEnv *env,
|
||||||
|
jclass loggerClass,
|
||||||
|
jstring jmsg,
|
||||||
|
jint priority) {
|
||||||
stopWatchingLogMessages(env, loggerClass);
|
stopWatchingLogMessages(env, loggerClass);
|
||||||
gMessageToLookFor = jni::wrap_alias(jmsg)->toStdString();
|
gMessageToLookFor = jni::wrap_alias(jmsg)->toStdString();
|
||||||
gMessagePriorityToLookFor = priority;
|
gMessagePriorityToLookFor = priority;
|
||||||
|
@ -187,24 +212,34 @@ static void startWatchingForLogMessage(JNIEnv* env, jclass loggerClass, jstring
|
||||||
|
|
||||||
using namespace facebook::react;
|
using namespace facebook::react;
|
||||||
|
|
||||||
extern "C" facebook::xplat::module::CxxModule* CxxBenchmarkModule() {
|
extern "C" facebook::xplat::module::CxxModule *CxxBenchmarkModule() {
|
||||||
return new facebook::react::CxxBenchmarkModule();
|
return new facebook::react::CxxBenchmarkModule();
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" jint JNI_OnLoad(JavaVM* vm, void*) {
|
extern "C" jint JNI_OnLoad(JavaVM *vm, void *) {
|
||||||
return facebook::jni::initialize(vm, [] {
|
return facebook::jni::initialize(vm, [] {
|
||||||
facebook::jni::registerNatives(
|
facebook::jni::registerNatives(
|
||||||
"com/facebook/catalyst/testing/LogWatcher", {
|
"com/facebook/catalyst/testing/LogWatcher",
|
||||||
makeNativeMethod("startWatchingForLogMessage", "(Ljava/lang/String;I)V", logwatcher::startWatchingForLogMessage),
|
{
|
||||||
makeNativeMethod("stopWatchingLogMessages", "()V", logwatcher::stopWatchingLogMessages),
|
makeNativeMethod(
|
||||||
makeNativeMethod("hasSeenExpectedLogMessage", "()Z", logwatcher::hasSeenExpectedLogMessage),
|
"startWatchingForLogMessage",
|
||||||
});
|
"(Ljava/lang/String;I)V",
|
||||||
facebook::jni::registerNatives(
|
logwatcher::startWatchingForLogMessage),
|
||||||
"com/facebook/react/CatalystBridgeBenchmarks", {
|
makeNativeMethod(
|
||||||
makeNativeMethod("runNativeBounce", runBounce),
|
"stopWatchingLogMessages",
|
||||||
makeNativeMethod("nativeSetUp", setUp),
|
"()V",
|
||||||
makeNativeMethod("nativeTearDown", tearDown),
|
logwatcher::stopWatchingLogMessages),
|
||||||
|
makeNativeMethod(
|
||||||
|
"hasSeenExpectedLogMessage",
|
||||||
|
"()Z",
|
||||||
|
logwatcher::hasSeenExpectedLogMessage),
|
||||||
});
|
});
|
||||||
});
|
facebook::jni::registerNatives(
|
||||||
|
"com/facebook/react/CatalystBridgeBenchmarks",
|
||||||
|
{
|
||||||
|
makeNativeMethod("runNativeBounce", runBounce),
|
||||||
|
makeNativeMethod("nativeSetUp", setUp),
|
||||||
|
makeNativeMethod("nativeTearDown", tearDown),
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче