Skip to content

Commit

Permalink
feat: Bridgeless with runtimeExecutor (#5734)
Browse files Browse the repository at this point in the history
PR bringing 0.74/bridgeless mode support to the library.

---------

Co-authored-by: Tomasz Żelawski <40713406+tjzel@users.noreply.github.com>
Co-authored-by: Tomasz Żelawski <tomasz.zelawski@swmansion.com>
  • Loading branch information
3 people committed Apr 5, 2024
1 parent 102db0a commit 2eb2882
Show file tree
Hide file tree
Showing 20 changed files with 1,233 additions and 260 deletions.
57 changes: 56 additions & 1 deletion Common/cpp/NativeModules/NativeReanimatedModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ bool CoreFeatures::useNativeState;

namespace reanimated {

// With `jsInvoker`.
NativeReanimatedModule::NativeReanimatedModule(
jsi::Runtime &rnRuntime,
const std::shared_ptr<CallInvoker> &jsInvoker,
Expand Down Expand Up @@ -86,7 +87,61 @@ NativeReanimatedModule::NativeReanimatedModule(
platformDepMethodsHolder.subscribeForKeyboardEvents),
unsubscribeFromKeyboardEventsFunction_(
platformDepMethodsHolder.unsubscribeFromKeyboardEvents),
isBridgeless_(jsInvoker == nullptr) {
isBridgeless_(false) {
commonInit(platformDepMethodsHolder);
}

#if REACT_NATIVE_MINOR_VERSION >= 74 && defined(RCT_NEW_ARCH_ENABLED)
// With `runtimeExecutor`.
NativeReanimatedModule::NativeReanimatedModule(
jsi::Runtime &rnRuntime,
RuntimeExecutor runtimeExecutor,
const std::shared_ptr<MessageQueueThread> &jsQueue,
const std::shared_ptr<UIScheduler> &uiScheduler,
const PlatformDepMethodsHolder &platformDepMethodsHolder,
const std::string &valueUnpackerCode)
: NativeReanimatedModuleSpec(nullptr),
jsQueue_(jsQueue),
jsScheduler_(std::make_shared<JSScheduler>(rnRuntime, runtimeExecutor)),
uiScheduler_(uiScheduler),
uiWorkletRuntime_(std::make_shared<WorkletRuntime>(
rnRuntime,
jsQueue,
jsScheduler_,
"Reanimated UI runtime",
true /* supportsLocking */,
valueUnpackerCode)),
valueUnpackerCode_(valueUnpackerCode),
eventHandlerRegistry_(std::make_unique<EventHandlerRegistry>()),
requestRender_(platformDepMethodsHolder.requestRender),
onRenderCallback_([this](const double timestampMs) {
renderRequested_ = false;
onRender(timestampMs);
}),
animatedSensorModule_(platformDepMethodsHolder),
jsLogger_(std::make_shared<JSLogger>(jsScheduler_)),
layoutAnimationsManager_(jsLogger_),
#ifdef RCT_NEW_ARCH_ENABLED
synchronouslyUpdateUIPropsFunction_(
platformDepMethodsHolder.synchronouslyUpdateUIPropsFunction),
propsRegistry_(std::make_shared<PropsRegistry>()),
#else
obtainPropFunction_(platformDepMethodsHolder.obtainPropFunction),
configurePropsPlatformFunction_(
platformDepMethodsHolder.configurePropsFunction),
updatePropsFunction_(platformDepMethodsHolder.updatePropsFunction),
#endif
subscribeForKeyboardEventsFunction_(
platformDepMethodsHolder.subscribeForKeyboardEvents),
unsubscribeFromKeyboardEventsFunction_(
platformDepMethodsHolder.unsubscribeFromKeyboardEvents),
isBridgeless_(true) {
commonInit(platformDepMethodsHolder);
}
#endif // REACT_NATIVE_MINOR_VERSION >= 74 && defined(RCT_NEW_ARCH_ENABLED)

void NativeReanimatedModule::commonInit(
const PlatformDepMethodsHolder &platformDepMethodsHolder) {
auto requestAnimationFrame =
[this](jsi::Runtime &rt, const jsi::Value &callback) {
this->requestAnimationFrame(rt, callback);
Expand Down
14 changes: 14 additions & 0 deletions Common/cpp/NativeModules/NativeReanimatedModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ namespace reanimated {

class NativeReanimatedModule : public NativeReanimatedModuleSpec {
public:
// With `jsInvoker`.
NativeReanimatedModule(
jsi::Runtime &rnRuntime,
const std::shared_ptr<CallInvoker> &jsInvoker,
Expand All @@ -39,6 +40,17 @@ class NativeReanimatedModule : public NativeReanimatedModuleSpec {
const PlatformDepMethodsHolder &platformDepMethodsHolder,
const std::string &valueUnpackerCode);

#if REACT_NATIVE_MINOR_VERSION >= 74 && defined(RCT_NEW_ARCH_ENABLED)
// With `runtimeExecutor`.
NativeReanimatedModule(
jsi::Runtime &rnRuntime,
RuntimeExecutor runtimeExecutor,
const std::shared_ptr<MessageQueueThread> &jsQueue,
const std::shared_ptr<UIScheduler> &uiScheduler,
const PlatformDepMethodsHolder &platformDepMethodsHolder,
const std::string &valueUnpackerCode);
#endif // REACT_NATIVE_MINOR_VERSION >= 74 && defined(RCT_NEW_ARCH_ENABLED

~NativeReanimatedModule();

jsi::Value makeShareableClone(
Expand Down Expand Up @@ -172,6 +184,8 @@ class NativeReanimatedModule : public NativeReanimatedModuleSpec {
}

private:
void commonInit(const PlatformDepMethodsHolder &platformDepMethodsHolder);

void requestAnimationFrame(jsi::Runtime &rt, const jsi::Value &callback);

#ifdef RCT_NEW_ARCH_ENABLED
Expand Down
2 changes: 1 addition & 1 deletion Common/cpp/ReanimatedRuntime/WorkletRuntimeDecorator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ void WorkletRuntimeDecorator::decorate(
jsi::PropNameID::forAscii(rt, "evalWithSourceUrl"),
1,
evalWithSourceUrl));
#endif
#endif // NDEBUG

jsi_utils::installJsiFunction(
rt, "_toString", [](jsi::Runtime &rt, const jsi::Value &value) {
Expand Down
28 changes: 23 additions & 5 deletions Common/cpp/Tools/JSScheduler.cpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,30 @@
#include "JSScheduler.h"

#include <utility>
using namespace facebook;
using namespace react;

namespace reanimated {
JSScheduler::JSScheduler(
jsi::Runtime &rnRuntime,
const std::shared_ptr<CallInvoker> &jsCallInvoker)
: rnRuntime_(rnRuntime),
jsCallInvoker_(jsCallInvoker),
scheduleOnJS([&](Job job) {
jsCallInvoker_->invokeAsync(
[job = std::move(job), &rt = rnRuntime_] { job(rt); });
}) {}

void JSScheduler::scheduleOnJS(std::function<void(jsi::Runtime &rt)> job) {
jsCallInvoker_->invokeAsync(
[job = std::move(job), &rt = rnRuntime_] { job(rt); });
}
#if REACT_NATIVE_MINOR_VERSION >= 74 && defined(RCT_NEW_ARCH_ENABLED)
// With `runtimeExecutor`.
JSScheduler::JSScheduler(
jsi::Runtime &rnRuntime,
RuntimeExecutor runtimeExecutor)
: rnRuntime_(rnRuntime),
runtimeExecutor_(runtimeExecutor),
scheduleOnJS([&](Job job) {
runtimeExecutor_(
[job = std::move(job)](jsi::Runtime &runtime) { job(runtime); });
}) {}
#endif // REACT_NATIVE_MINOR_VERSION >= 74 && defined(RCT_NEW_ARCH_ENABLED

} // namespace reanimated
25 changes: 21 additions & 4 deletions Common/cpp/Tools/JSScheduler.h
Original file line number Diff line number Diff line change
@@ -1,25 +1,42 @@
#pragma once

#include <ReactCommon/CallInvoker.h>
#include <ReactCommon/RuntimeExecutor.h>
#include <jsi/jsi.h>

#include <memory>
#include <utility>

using namespace facebook;
using namespace react;

using Job = std::function<void(jsi::Runtime &rt)>;

namespace reanimated {

class JSScheduler {
public:
// With `jsCallInvoker`.
explicit JSScheduler(
jsi::Runtime &rnRuntime,
const std::shared_ptr<CallInvoker> &jsCallInvoker);

#if REACT_NATIVE_MINOR_VERSION >= 74 && defined(RCT_NEW_ARCH_ENABLED)
// With `runtimeExecutor`.
explicit JSScheduler(
jsi::Runtime &rnRuntime,
const std::shared_ptr<facebook::react::CallInvoker> &jsCallInvoker)
: rnRuntime_(rnRuntime), jsCallInvoker_(jsCallInvoker) {}
void scheduleOnJS(std::function<void(jsi::Runtime &rt)> job);
RuntimeExecutor runtimeExecutor);
#endif // REACT_NATIVE_MINOR_VERSION >= 74 && defined(RCT_NEW_ARCH_ENABLED

protected:
jsi::Runtime &rnRuntime_;
const std::shared_ptr<facebook::react::CallInvoker> jsCallInvoker_;
const std::shared_ptr<CallInvoker> jsCallInvoker_ = nullptr;
#if REACT_NATIVE_MINOR_VERSION >= 74 && defined(RCT_NEW_ARCH_ENABLED)
RuntimeExecutor runtimeExecutor_ = nullptr;
#endif // REACT_NATIVE_MINOR_VERSION >= 74 && defined(RCT_NEW_ARCH_ENABLED

public:
const std::function<void(Job)> scheduleOnJS = nullptr;
};

} // namespace reanimated
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class MainApplication : Application(), ReactApplication {
SoLoader.init(this, false)
if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
// If you opted-in for the New Architecture, we load the native entry point for this app.
load(bridgelessEnabled = false)
load(bridgelessEnabled = true)
}
}
}
2 changes: 1 addition & 1 deletion FabricExample/ios/FabricExample/AppDelegate.mm
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ - (NSURL *)bundleURL

- (BOOL)bridgelessEnabled
{
return NO;
return YES;
}

@end
10 changes: 10 additions & 0 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,16 @@ android {
srcDirs += "src/reactNativeVersionPatch/ReactFeatureFlagsWrapper/latest"
}
}

// RuntimeExecutor
if (IS_NEW_ARCHITECTURE_ENABLED) {
if (REACT_NATIVE_MINOR_VERSION <= 73) {
srcDirs += "src/reactNativeVersionPatch/RuntimeExecutor/73"
} else {
srcDirs += "src/reactNativeVersionPatch/RuntimeExecutor/latest"
}
}

}
}
}
Expand Down
80 changes: 72 additions & 8 deletions android/src/main/cpp/NativeProxy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,40 @@ NativeProxy::NativeProxy(
valueUnpackerCode)),
layoutAnimations_(std::move(layoutAnimations)) {
#ifdef RCT_NEW_ARCH_ENABLED
commonInit(fabricUIManager);
#endif // RCT_NEW_ARCH_ENABLED
}

#if REACT_NATIVE_MINOR_VERSION >= 74 && defined(RCT_NEW_ARCH_ENABLED)
NativeProxy::NativeProxy(
jni::alias_ref<NativeProxy::javaobject> jThis,
jsi::Runtime *rnRuntime,
RuntimeExecutor runtimeExecutor,
const std::shared_ptr<UIScheduler> &uiScheduler,
jni::global_ref<LayoutAnimations::javaobject> layoutAnimations,
jni::alias_ref<JavaMessageQueueThread::javaobject> messageQueueThread,
jni::alias_ref<facebook::react::JFabricUIManager::javaobject>
fabricUIManager,

const std::string &valueUnpackerCode)
: javaPart_(jni::make_global(jThis)),
rnRuntime_(rnRuntime),
nativeReanimatedModule_(std::make_shared<NativeReanimatedModule>(
*rnRuntime,
runtimeExecutor,
std::make_shared<JMessageQueueThread>(messageQueueThread),
uiScheduler,
getPlatformDependentMethods(),
valueUnpackerCode)),
layoutAnimations_(std::move(layoutAnimations)) {
commonInit(fabricUIManager);
}
#endif // REACT_NATIVE_MINOR_VERSION >= 74 && defined(RCT_NEW_ARCH_ENABLED

#ifdef RCT_NEW_ARCH_ENABLED
void NativeProxy::commonInit(
jni::alias_ref<facebook::react::JFabricUIManager::javaobject>
&fabricUIManager) {
const auto &uiManager =
fabricUIManager->getBinding()->getScheduler()->getUIManager();
nativeReanimatedModule_->initializeFabric(uiManager);
Expand All @@ -63,8 +97,8 @@ NativeProxy::NativeProxy(
// });
// reactScheduler_ = binding->getScheduler();
// reactScheduler_->addEventListener(eventListener_);
#endif
}
#endif // RCT_NEW_ARCH_ENABLED

NativeProxy::~NativeProxy() {
// removed temporary, new event listener mechanism need fix on the RN side
Expand Down Expand Up @@ -104,6 +138,31 @@ jni::local_ref<NativeProxy::jhybriddata> NativeProxy::initHybrid(
valueUnpackerCode);
}

#if REACT_NATIVE_MINOR_VERSION >= 74 && defined(RCT_NEW_ARCH_ENABLED)
jni::local_ref<NativeProxy::jhybriddata> NativeProxy::initHybridBridgeless(
jni::alias_ref<jhybridobject> jThis,
jlong jsContext,
jni::alias_ref<react::JRuntimeExecutor::javaobject> runtimeExecutorHolder,
jni::alias_ref<AndroidUIScheduler::javaobject> androidUiScheduler,
jni::alias_ref<LayoutAnimations::javaobject> layoutAnimations,
jni::alias_ref<JavaMessageQueueThread::javaobject> messageQueueThread,
jni::alias_ref<facebook::react::JFabricUIManager::javaobject>
fabricUIManager,
const std::string &valueUnpackerCode) {
auto uiScheduler = androidUiScheduler->cthis()->getUIScheduler();
auto runtimeExecutor = runtimeExecutorHolder->cthis()->get();
return makeCxxInstance(
jThis,
(jsi::Runtime *)jsContext,
runtimeExecutor,
uiScheduler,
make_global(layoutAnimations),
messageQueueThread,
fabricUIManager,
valueUnpackerCode);
}
#endif // REACT_NATIVE_MINOR_VERSION >= 74 && defined(RCT_NEW_ARCH_ENABLED

#ifndef NDEBUG
void NativeProxy::checkJavaVersion(jsi::Runtime &rnRuntime) {
std::string javaVersion;
Expand Down Expand Up @@ -177,13 +236,18 @@ bool NativeProxy::getIsReducedMotion() {
}

void NativeProxy::registerNatives() {
registerHybrid(
{makeNativeMethod("initHybrid", NativeProxy::initHybrid),
makeNativeMethod("installJSIBindings", NativeProxy::installJSIBindings),
makeNativeMethod(
"isAnyHandlerWaitingForEvent",
NativeProxy::isAnyHandlerWaitingForEvent),
makeNativeMethod("performOperations", NativeProxy::performOperations)});
registerHybrid({
makeNativeMethod("initHybrid", NativeProxy::initHybrid),
#if REACT_NATIVE_MINOR_VERSION >= 74 && defined(RCT_NEW_ARCH_ENABLED)
makeNativeMethod(
"initHybridBridgeless", NativeProxy::initHybridBridgeless),
#endif // REACT_NATIVE_MINOR_VERSION >= 74 && defined(RCT_NEW_ARCH_ENABLED)
makeNativeMethod("installJSIBindings", NativeProxy::installJSIBindings),
makeNativeMethod(
"isAnyHandlerWaitingForEvent",
NativeProxy::isAnyHandlerWaitingForEvent),
makeNativeMethod("performOperations", NativeProxy::performOperations)
});
}

void NativeProxy::requestRender(
Expand Down
34 changes: 34 additions & 0 deletions android/src/main/cpp/NativeProxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
#ifdef RCT_NEW_ARCH_ENABLED
#include <react/fabric/JFabricUIManager.h>
#include <react/renderer/scheduler/Scheduler.h>
#if REACT_NATIVE_MINOR_VERSION >= 74
#include <react/jni/JRuntimeExecutor.h>
#endif // REACT_NATIVE_MINOR_VERSION >= 74
#endif

#include <ReactCommon/CallInvokerHolder.h>
Expand Down Expand Up @@ -158,6 +161,19 @@ class NativeProxy : public jni::HybridClass<NativeProxy> {
fabricUIManager,
#endif
const std::string &valueUnpackerCode);

#if REACT_NATIVE_MINOR_VERSION >= 74 && defined(RCT_NEW_ARCH_ENABLED)
static jni::local_ref<jhybriddata> initHybridBridgeless(
jni::alias_ref<jhybridobject> jThis,
jlong jsContext,
jni::alias_ref<react::JRuntimeExecutor::javaobject> runtimeExecutorHolder,
jni::alias_ref<AndroidUIScheduler::javaobject> androidUiScheduler,
jni::alias_ref<LayoutAnimations::javaobject> layoutAnimations,
jni::alias_ref<JavaMessageQueueThread::javaobject> messageQueueThread,
jni::alias_ref<facebook::react::JFabricUIManager::javaobject>
fabricUIManager,
const std::string &valueUnpackerCode);
#endif // REACT_NATIVE_MINOR_VERSION >= 74 && defined(RCT_NEW_ARCH_ENABLED
static void registerNatives();

~NativeProxy();
Expand Down Expand Up @@ -269,6 +285,24 @@ class NativeProxy : public jni::HybridClass<NativeProxy> {
fabricUIManager,
#endif
const std::string &valueUnpackerCode);

#if REACT_NATIVE_MINOR_VERSION >= 74 && defined(RCT_NEW_ARCH_ENABLED)
explicit NativeProxy(
jni::alias_ref<NativeProxy::jhybridobject> jThis,
jsi::Runtime *rnRuntime,
RuntimeExecutor runtimeExecutor,
const std::shared_ptr<UIScheduler> &uiScheduler,
jni::global_ref<LayoutAnimations::javaobject> layoutAnimations,
jni::alias_ref<JavaMessageQueueThread::javaobject> messageQueueThread,
jni::alias_ref<facebook::react::JFabricUIManager::javaobject>
fabricUIManager,
const std::string &valueUnpackerCode);
#endif // REACT_NATIVE_MINOR_VERSION >= 74 && defined(RCT_NEW_ARCH_ENABLED

#ifdef RCT_NEW_ARCH_ENABLED
void commonInit(jni::alias_ref<facebook::react::JFabricUIManager::javaobject>
&fabricUIManager);
#endif // RCT_NEW_ARCH_ENABLED
};

} // namespace reanimated
Loading

0 comments on commit 2eb2882

Please sign in to comment.