Add minimal implementation of RuntimeScheduler::scheduleTask
Summary: Changelog: [internal] Add minimal implementation of schedule task. More features and proper scheduling will be added later. Reviewed By: mdvacca Differential Revision: D27622138 fbshipit-source-id: b2e4623d38e7217290a6a3c59ccc10a1c13e3a4f
This commit is contained in:
Родитель
71b5178230
Коммит
2779129434
|
@ -49,5 +49,6 @@ rn_xplat_cxx_library(
|
|||
visibility = ["PUBLIC"],
|
||||
deps = [
|
||||
react_native_xplat_target("runtimeexecutor:runtimeexecutor"),
|
||||
react_native_xplat_target("react/renderer/debug:debug"),
|
||||
],
|
||||
)
|
||||
|
|
|
@ -7,4 +7,19 @@
|
|||
|
||||
#include "RuntimeScheduler.h"
|
||||
|
||||
namespace facebook::react {} // namespace facebook::react
|
||||
namespace facebook::react {
|
||||
|
||||
RuntimeScheduler::RuntimeScheduler(RuntimeExecutor const &runtimeExecutor)
|
||||
: runtimeExecutor_(runtimeExecutor) {}
|
||||
|
||||
void RuntimeScheduler::scheduleTask(std::shared_ptr<Task> const &task) {
|
||||
taskQueue_.push(task);
|
||||
|
||||
runtimeExecutor_([this](jsi::Runtime &runtime) {
|
||||
auto topPriority = taskQueue_.top();
|
||||
taskQueue_.pop();
|
||||
(*topPriority)(runtime);
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace facebook::react
|
||||
|
|
|
@ -7,10 +7,26 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
#include <ReactCommon/RuntimeExecutor.h>
|
||||
#include <react/renderer/runtimescheduler/Task.h>
|
||||
#include <memory>
|
||||
#include <queue>
|
||||
|
||||
class RuntimeScheduler final {};
|
||||
namespace facebook::react {
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
class RuntimeScheduler final {
|
||||
public:
|
||||
RuntimeScheduler(RuntimeExecutor const &runtimeExecutor);
|
||||
|
||||
void scheduleTask(std::shared_ptr<Task> const &task);
|
||||
|
||||
private:
|
||||
mutable std::priority_queue<
|
||||
std::shared_ptr<Task>,
|
||||
std::vector<std::shared_ptr<Task>>,
|
||||
TaskPriorityComparer>
|
||||
taskQueue_;
|
||||
RuntimeExecutor const runtimeExecutor_;
|
||||
};
|
||||
|
||||
} // namespace facebook::react
|
||||
|
|
|
@ -8,12 +8,15 @@
|
|||
#include "RuntimeSchedulerBinding.h"
|
||||
#include "SchedulerPriority.h"
|
||||
|
||||
#include <react/debug/react_native_assert.h>
|
||||
#include <memory>
|
||||
|
||||
namespace facebook::react {
|
||||
|
||||
std::shared_ptr<RuntimeSchedulerBinding>
|
||||
RuntimeSchedulerBinding::createAndInstallIfNeeded(jsi::Runtime &runtime) {
|
||||
RuntimeSchedulerBinding::createAndInstallIfNeeded(
|
||||
jsi::Runtime &runtime,
|
||||
RuntimeExecutor runtimeExecutor) {
|
||||
auto runtimeSchedulerModuleName = "nativeRuntimeScheduler";
|
||||
|
||||
auto runtimeSchedulerValue =
|
||||
|
@ -21,7 +24,8 @@ RuntimeSchedulerBinding::createAndInstallIfNeeded(jsi::Runtime &runtime) {
|
|||
if (runtimeSchedulerValue.isUndefined()) {
|
||||
// The global namespace does not have an instance of the binding;
|
||||
// we need to create, install and return it.
|
||||
auto runtimeSchedulerBinding = std::make_shared<RuntimeSchedulerBinding>();
|
||||
auto runtimeSchedulerBinding = std::make_shared<RuntimeSchedulerBinding>(
|
||||
RuntimeScheduler(runtimeExecutor));
|
||||
auto object =
|
||||
jsi::Object::createFromHostObject(runtime, runtimeSchedulerBinding);
|
||||
runtime.global().setProperty(
|
||||
|
@ -35,11 +39,37 @@ RuntimeSchedulerBinding::createAndInstallIfNeeded(jsi::Runtime &runtime) {
|
|||
return runtimeSchedulerObject.getHostObject<RuntimeSchedulerBinding>(runtime);
|
||||
}
|
||||
|
||||
RuntimeSchedulerBinding::RuntimeSchedulerBinding(
|
||||
RuntimeScheduler runtimeScheduler)
|
||||
: runtimeScheduler_(std::move(runtimeScheduler)) {}
|
||||
|
||||
jsi::Value RuntimeSchedulerBinding::get(
|
||||
jsi::Runtime &runtime,
|
||||
jsi::PropNameID const &name) {
|
||||
auto propertyName = name.utf8(runtime);
|
||||
|
||||
if (propertyName == "unstable_scheduleCallback") {
|
||||
return jsi::Function::createFromHostFunction(
|
||||
runtime,
|
||||
name,
|
||||
3,
|
||||
[this](
|
||||
jsi::Runtime &runtime,
|
||||
jsi::Value const &,
|
||||
jsi::Value const *arguments,
|
||||
size_t) noexcept -> jsi::Value {
|
||||
SchedulerPriority priority = fromRawValue(arguments[0].getNumber());
|
||||
auto callback = arguments[1].getObject(runtime).getFunction(runtime);
|
||||
react_native_assert(arguments[2].isUndefined());
|
||||
|
||||
auto task = std::make_shared<Task>(priority, std::move(callback));
|
||||
runtimeScheduler_.scheduleTask(task);
|
||||
|
||||
// TODO: return reference to the task.
|
||||
return jsi::Value::undefined();
|
||||
});
|
||||
}
|
||||
|
||||
if (propertyName == "unstable_ImmediatePriority") {
|
||||
return jsi::Value(runtime, serialize(SchedulerPriority::ImmediatePriority));
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <jsi/jsi.h>
|
||||
#include <react/renderer/runtimescheduler/RuntimeScheduler.h>
|
||||
|
||||
namespace facebook::react {
|
||||
|
||||
|
@ -16,20 +17,25 @@ namespace facebook::react {
|
|||
*/
|
||||
class RuntimeSchedulerBinding : public jsi::HostObject {
|
||||
public:
|
||||
RuntimeSchedulerBinding(RuntimeScheduler runtimeScheduler);
|
||||
|
||||
/*
|
||||
* Installs RuntimeSchedulerBinding into JavaScript runtime if needed.
|
||||
* Creates and sets `RuntimeSchedulerBinding` into the global namespace.
|
||||
* In case if the global namespace already has a `RuntimeSchedulerBinding`
|
||||
* installed, returns that. Thread synchronization must be enforced
|
||||
* externally.
|
||||
* installed, returns that.
|
||||
*/
|
||||
static std::shared_ptr<RuntimeSchedulerBinding> createAndInstallIfNeeded(
|
||||
jsi::Runtime &runtime);
|
||||
jsi::Runtime &runtime,
|
||||
RuntimeExecutor runtimeExecutor);
|
||||
|
||||
/*
|
||||
* `jsi::HostObject` specific overloads.
|
||||
*/
|
||||
jsi::Value get(jsi::Runtime &runtime, jsi::PropNameID const &name) override;
|
||||
|
||||
private:
|
||||
RuntimeScheduler runtimeScheduler_;
|
||||
};
|
||||
|
||||
} // namespace facebook::react
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <react/debug/react_native_assert.h>
|
||||
|
||||
namespace facebook::react {
|
||||
|
||||
enum class SchedulerPriority : int {
|
||||
|
@ -23,4 +25,22 @@ static constexpr std::underlying_type<SchedulerPriority>::type serialize(
|
|||
schedulerPriority);
|
||||
}
|
||||
|
||||
static inline SchedulerPriority fromRawValue(double value) {
|
||||
switch ((int)value) {
|
||||
case 1:
|
||||
return SchedulerPriority::ImmediatePriority;
|
||||
case 2:
|
||||
return SchedulerPriority::UserBlockingPriority;
|
||||
case 3:
|
||||
return SchedulerPriority::NormalPriority;
|
||||
case 4:
|
||||
return SchedulerPriority::LowPriority;
|
||||
case 5:
|
||||
return SchedulerPriority::IdlePriority;
|
||||
default:
|
||||
react_native_assert(false && "Unsupported SchedulerPriority value");
|
||||
return SchedulerPriority::NormalPriority;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace facebook::react
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#include "RuntimeScheduler.h"
|
||||
|
||||
namespace facebook::react {
|
||||
|
||||
Task::Task(SchedulerPriority priority, jsi::Function callback)
|
||||
: priority_(priority), callback_(std::move(callback)) {}
|
||||
|
||||
SchedulerPriority Task::getPriority() const {
|
||||
return priority_;
|
||||
}
|
||||
|
||||
void Task::operator()(jsi::Runtime &runtime) const {
|
||||
callback_.call(runtime, {});
|
||||
}
|
||||
|
||||
} // namespace facebook::react
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <jsi/jsi.h>
|
||||
#include <react/renderer/runtimescheduler/SchedulerPriority.h>
|
||||
|
||||
namespace facebook::react {
|
||||
|
||||
class Task final {
|
||||
public:
|
||||
Task(SchedulerPriority priority, jsi::Function callback);
|
||||
|
||||
SchedulerPriority priority_;
|
||||
jsi::Function callback_;
|
||||
|
||||
SchedulerPriority getPriority() const;
|
||||
|
||||
void operator()(jsi::Runtime &runtime) const;
|
||||
};
|
||||
|
||||
class TaskPriorityComparer {
|
||||
public:
|
||||
inline bool operator()(
|
||||
std::shared_ptr<Task> const &lhs,
|
||||
std::shared_ptr<Task> const &rhs) {
|
||||
return lhs->getPriority() > rhs->getPriority();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace facebook::react
|
|
@ -99,7 +99,8 @@ Scheduler::Scheduler(
|
|||
auto uiManagerBinding = UIManagerBinding::createAndInstallIfNeeded(runtime);
|
||||
uiManagerBinding->attach(uiManager);
|
||||
if (enableRuntimeScheduler) {
|
||||
RuntimeSchedulerBinding::createAndInstallIfNeeded(runtime);
|
||||
RuntimeSchedulerBinding::createAndInstallIfNeeded(
|
||||
runtime, runtimeExecutor_);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче