Funnel All Fabric calls to RuntimeExecutor to RuntimeScheduler

Summary:
Changelog: [internal]

This diff moves all calls to RuntimeExecutor to RuntimeScheduler. The calls are still immediately dispatched. Timing of events will not change.

The goal of this diff is to prepare infrastructure for Concurrent Mode.

Reviewed By: JoshuaGross

Differential Revision: D27937665

fbshipit-source-id: 434d78c95ccf23d8da41186d0dae91bff4eda384
This commit is contained in:
Samuel Susla 2021-05-13 08:01:51 -07:00 коммит произвёл Facebook GitHub Bot
Родитель 58a0f9b4e2
Коммит 9b3c12dc87
8 изменённых файлов: 49 добавлений и 20 удалений

Просмотреть файл

@ -30,6 +30,7 @@
#import <react/renderer/components/root/RootShadowNode.h>
#import <react/renderer/core/LayoutConstraints.h>
#import <react/renderer/core/LayoutContext.h>
#import <react/renderer/runtimescheduler/RuntimeScheduler.h>
#import <react/renderer/scheduler/AsynchronousEventBeat.h>
#import <react/renderer/scheduler/AsynchronousEventBeatV2.h>
#import <react/renderer/scheduler/SchedulerToolbox.h>
@ -91,7 +92,6 @@ static BackgroundExecutor RCTGetBackgroundExecutor()
{
if (self = [super init]) {
assert(contextContainer && "RuntimeExecutor must be not null.");
_runtimeExecutor = runtimeExecutor;
_contextContainer = contextContainer;
@ -273,7 +273,17 @@ static BackgroundExecutor RCTGetBackgroundExecutor()
auto toolbox = SchedulerToolbox{};
toolbox.contextContainer = _contextContainer;
toolbox.componentRegistryFactory = componentRegistryFactory;
if (reactNativeConfig && reactNativeConfig->getBool("react_fabric:enable_runtimescheduler_ios")) {
auto runtimeScheduler = std::make_shared<RuntimeScheduler>(_runtimeExecutor);
toolbox.runtimeScheduler = runtimeScheduler;
runtimeExecutor = [runtimeScheduler](std::function<void(jsi::Runtime & runtime)> &&callback) {
runtimeScheduler->scheduleWork(std::move(callback));
};
}
toolbox.runtimeExecutor = runtimeExecutor;
toolbox.mainRunLoopObserverFactory = [](RunLoopObserver::Activity activities,
RunLoopObserver::WeakOwner const &owner) {
return std::make_unique<MainRunLoopObserver>(activities, owner);

Просмотреть файл

@ -17,6 +17,11 @@ RuntimeScheduler::RuntimeScheduler(
std::function<RuntimeSchedulerTimePoint()> now)
: runtimeExecutor_(runtimeExecutor), now_(now) {}
void RuntimeScheduler::scheduleWork(
std::function<void(jsi::Runtime &)> callback) const {
runtimeExecutor_(std::move(callback));
}
std::shared_ptr<Task> RuntimeScheduler::scheduleTask(
SchedulerPriority priority,
jsi::Function callback) {

Просмотреть файл

@ -23,6 +23,8 @@ class RuntimeScheduler final {
RuntimeExecutor const &runtimeExecutor,
std::function<RuntimeSchedulerTimePoint()> now);
void scheduleWork(std::function<void(jsi::Runtime &)> callback) const;
std::shared_ptr<Task> scheduleTask(
SchedulerPriority priority,
jsi::Function callback);

Просмотреть файл

@ -18,7 +18,7 @@ namespace facebook::react {
std::shared_ptr<RuntimeSchedulerBinding>
RuntimeSchedulerBinding::createAndInstallIfNeeded(
jsi::Runtime &runtime,
RuntimeExecutor runtimeExecutor) {
std::shared_ptr<RuntimeScheduler> const &runtimeScheduler) {
auto runtimeSchedulerModuleName = "nativeRuntimeScheduler";
auto runtimeSchedulerValue =
@ -26,9 +26,8 @@ RuntimeSchedulerBinding::createAndInstallIfNeeded(
if (runtimeSchedulerValue.isUndefined()) {
// The global namespace does not have an instance of the binding;
// we need to create, install and return it.
auto runtimeScheduler = std::make_unique<RuntimeScheduler>(runtimeExecutor);
auto runtimeSchedulerBinding =
std::make_shared<RuntimeSchedulerBinding>(std::move(runtimeScheduler));
std::make_shared<RuntimeSchedulerBinding>(runtimeScheduler);
auto object =
jsi::Object::createFromHostObject(runtime, runtimeSchedulerBinding);
runtime.global().setProperty(
@ -43,8 +42,8 @@ RuntimeSchedulerBinding::createAndInstallIfNeeded(
}
RuntimeSchedulerBinding::RuntimeSchedulerBinding(
std::unique_ptr<RuntimeScheduler> runtimeScheduler)
: runtimeScheduler_(std::move(runtimeScheduler)) {}
std::shared_ptr<RuntimeScheduler> const &runtimeScheduler)
: runtimeScheduler_(runtimeScheduler) {}
jsi::Value RuntimeSchedulerBinding::get(
jsi::Runtime &runtime,

Просмотреть файл

@ -17,7 +17,8 @@ namespace facebook::react {
*/
class RuntimeSchedulerBinding : public jsi::HostObject {
public:
RuntimeSchedulerBinding(std::unique_ptr<RuntimeScheduler> runtimeScheduler);
RuntimeSchedulerBinding(
std::shared_ptr<RuntimeScheduler> const &runtimeScheduler);
/*
* Installs RuntimeSchedulerBinding into JavaScript runtime if needed.
@ -27,7 +28,7 @@ class RuntimeSchedulerBinding : public jsi::HostObject {
*/
static std::shared_ptr<RuntimeSchedulerBinding> createAndInstallIfNeeded(
jsi::Runtime &runtime,
RuntimeExecutor runtimeExecutor);
std::shared_ptr<RuntimeScheduler> const &runtimeScheduler);
/*
* `jsi::HostObject` specific overloads.
@ -35,7 +36,7 @@ class RuntimeSchedulerBinding : public jsi::HostObject {
jsi::Value get(jsi::Runtime &runtime, jsi::PropNameID const &name) override;
private:
std::unique_ptr<RuntimeScheduler> runtimeScheduler_;
std::shared_ptr<RuntimeScheduler> runtimeScheduler_;
};
} // namespace facebook::react

Просмотреть файл

@ -312,4 +312,19 @@ TEST_F(RuntimeSchedulerTest, getCurrentPriorityLevel) {
SchedulerPriority::NormalPriority);
}
TEST_F(RuntimeSchedulerTest, scheduleWork) {
bool wasCalled = false;
runtimeScheduler_->scheduleWork(
[&](jsi::Runtime const &) { wasCalled = true; });
EXPECT_FALSE(wasCalled);
EXPECT_EQ(stubQueue_->size(), 1);
stubQueue_->tick();
EXPECT_TRUE(wasCalled);
EXPECT_EQ(stubQueue_->size(), 0);
}
} // namespace facebook::react

Просмотреть файл

@ -87,20 +87,14 @@ Scheduler::Scheduler(
uiManager->setDelegate(this);
uiManager->setComponentDescriptorRegistry(componentDescriptorRegistry_);
#ifdef ANDROID
auto enableRuntimeScheduler = reactNativeConfig_->getBool(
"react_fabric:enable_runtimescheduler_android");
#else
auto enableRuntimeScheduler =
reactNativeConfig_->getBool("react_fabric:enable_runtimescheduler_ios");
#endif
runtimeExecutor_([=](jsi::Runtime &runtime) {
runtimeExecutor_([uiManager,
runtimeScheduler = schedulerToolbox.runtimeScheduler](
jsi::Runtime &runtime) {
auto uiManagerBinding = UIManagerBinding::createAndInstallIfNeeded(runtime);
uiManagerBinding->attach(uiManager);
if (enableRuntimeScheduler) {
if (runtimeScheduler) {
RuntimeSchedulerBinding::createAndInstallIfNeeded(
runtime, runtimeExecutor_);
runtime, runtimeScheduler);
}
});

Просмотреть файл

@ -13,6 +13,7 @@
#include <react/renderer/componentregistry/ComponentDescriptorFactory.h>
#include <react/renderer/core/EventBeat.h>
#include <react/renderer/leakchecker/LeakChecker.h>
#include <react/renderer/runtimescheduler/RuntimeScheduler.h>
#include <react/renderer/uimanager/UIManagerCommitHook.h>
#include <react/renderer/uimanager/primitives.h>
#include <react/utils/ContextContainer.h>
@ -42,6 +43,8 @@ struct SchedulerToolbox final {
*/
RuntimeExecutor runtimeExecutor;
std::shared_ptr<RuntimeScheduler> runtimeScheduler;
/*
* Represent connections with a platform-specific UI run loops.
*/