Skip to content

Commit 2779129

Browse files
sammy-SCfacebook-github-bot
authored andcommitted
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
1 parent 71b5178 commit 2779129

9 files changed

Lines changed: 160 additions & 12 deletions

File tree

ReactCommon/react/renderer/runtimescheduler/BUCK

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,5 +49,6 @@ rn_xplat_cxx_library(
4949
visibility = ["PUBLIC"],
5050
deps = [
5151
react_native_xplat_target("runtimeexecutor:runtimeexecutor"),
52+
react_native_xplat_target("react/renderer/debug:debug"),
5253
],
5354
)

ReactCommon/react/renderer/runtimescheduler/RuntimeScheduler.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,19 @@
77

88
#include "RuntimeScheduler.h"
99

10-
namespace facebook::react {} // namespace facebook::react
10+
namespace facebook::react {
11+
12+
RuntimeScheduler::RuntimeScheduler(RuntimeExecutor const &runtimeExecutor)
13+
: runtimeExecutor_(runtimeExecutor) {}
14+
15+
void RuntimeScheduler::scheduleTask(std::shared_ptr<Task> const &task) {
16+
taskQueue_.push(task);
17+
18+
runtimeExecutor_([this](jsi::Runtime &runtime) {
19+
auto topPriority = taskQueue_.top();
20+
taskQueue_.pop();
21+
(*topPriority)(runtime);
22+
});
23+
}
24+
25+
} // namespace facebook::react

ReactCommon/react/renderer/runtimescheduler/RuntimeScheduler.h

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,26 @@
77

88
#pragma once
99

10-
namespace facebook {
11-
namespace react {
10+
#include <ReactCommon/RuntimeExecutor.h>
11+
#include <react/renderer/runtimescheduler/Task.h>
12+
#include <memory>
13+
#include <queue>
1214

13-
class RuntimeScheduler final {};
15+
namespace facebook::react {
1416

15-
} // namespace react
16-
} // namespace facebook
17+
class RuntimeScheduler final {
18+
public:
19+
RuntimeScheduler(RuntimeExecutor const &runtimeExecutor);
20+
21+
void scheduleTask(std::shared_ptr<Task> const &task);
22+
23+
private:
24+
mutable std::priority_queue<
25+
std::shared_ptr<Task>,
26+
std::vector<std::shared_ptr<Task>>,
27+
TaskPriorityComparer>
28+
taskQueue_;
29+
RuntimeExecutor const runtimeExecutor_;
30+
};
31+
32+
} // namespace facebook::react

ReactCommon/react/renderer/runtimescheduler/RuntimeSchedulerBinding.cpp

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,24 @@
88
#include "RuntimeSchedulerBinding.h"
99
#include "SchedulerPriority.h"
1010

11+
#include <react/debug/react_native_assert.h>
1112
#include <memory>
1213

1314
namespace facebook::react {
1415

1516
std::shared_ptr<RuntimeSchedulerBinding>
16-
RuntimeSchedulerBinding::createAndInstallIfNeeded(jsi::Runtime &runtime) {
17+
RuntimeSchedulerBinding::createAndInstallIfNeeded(
18+
jsi::Runtime &runtime,
19+
RuntimeExecutor runtimeExecutor) {
1720
auto runtimeSchedulerModuleName = "nativeRuntimeScheduler";
1821

1922
auto runtimeSchedulerValue =
2023
runtime.global().getProperty(runtime, runtimeSchedulerModuleName);
2124
if (runtimeSchedulerValue.isUndefined()) {
2225
// The global namespace does not have an instance of the binding;
2326
// we need to create, install and return it.
24-
auto runtimeSchedulerBinding = std::make_shared<RuntimeSchedulerBinding>();
27+
auto runtimeSchedulerBinding = std::make_shared<RuntimeSchedulerBinding>(
28+
RuntimeScheduler(runtimeExecutor));
2529
auto object =
2630
jsi::Object::createFromHostObject(runtime, runtimeSchedulerBinding);
2731
runtime.global().setProperty(
@@ -35,11 +39,37 @@ RuntimeSchedulerBinding::createAndInstallIfNeeded(jsi::Runtime &runtime) {
3539
return runtimeSchedulerObject.getHostObject<RuntimeSchedulerBinding>(runtime);
3640
}
3741

42+
RuntimeSchedulerBinding::RuntimeSchedulerBinding(
43+
RuntimeScheduler runtimeScheduler)
44+
: runtimeScheduler_(std::move(runtimeScheduler)) {}
45+
3846
jsi::Value RuntimeSchedulerBinding::get(
3947
jsi::Runtime &runtime,
4048
jsi::PropNameID const &name) {
4149
auto propertyName = name.utf8(runtime);
4250

51+
if (propertyName == "unstable_scheduleCallback") {
52+
return jsi::Function::createFromHostFunction(
53+
runtime,
54+
name,
55+
3,
56+
[this](
57+
jsi::Runtime &runtime,
58+
jsi::Value const &,
59+
jsi::Value const *arguments,
60+
size_t) noexcept -> jsi::Value {
61+
SchedulerPriority priority = fromRawValue(arguments[0].getNumber());
62+
auto callback = arguments[1].getObject(runtime).getFunction(runtime);
63+
react_native_assert(arguments[2].isUndefined());
64+
65+
auto task = std::make_shared<Task>(priority, std::move(callback));
66+
runtimeScheduler_.scheduleTask(task);
67+
68+
// TODO: return reference to the task.
69+
return jsi::Value::undefined();
70+
});
71+
}
72+
4373
if (propertyName == "unstable_ImmediatePriority") {
4474
return jsi::Value(runtime, serialize(SchedulerPriority::ImmediatePriority));
4575
}

ReactCommon/react/renderer/runtimescheduler/RuntimeSchedulerBinding.h

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#pragma once
99

1010
#include <jsi/jsi.h>
11+
#include <react/renderer/runtimescheduler/RuntimeScheduler.h>
1112

1213
namespace facebook::react {
1314

@@ -16,20 +17,25 @@ namespace facebook::react {
1617
*/
1718
class RuntimeSchedulerBinding : public jsi::HostObject {
1819
public:
20+
RuntimeSchedulerBinding(RuntimeScheduler runtimeScheduler);
21+
1922
/*
2023
* Installs RuntimeSchedulerBinding into JavaScript runtime if needed.
2124
* Creates and sets `RuntimeSchedulerBinding` into the global namespace.
2225
* In case if the global namespace already has a `RuntimeSchedulerBinding`
23-
* installed, returns that. Thread synchronization must be enforced
24-
* externally.
26+
* installed, returns that.
2527
*/
2628
static std::shared_ptr<RuntimeSchedulerBinding> createAndInstallIfNeeded(
27-
jsi::Runtime &runtime);
29+
jsi::Runtime &runtime,
30+
RuntimeExecutor runtimeExecutor);
2831

2932
/*
3033
* `jsi::HostObject` specific overloads.
3134
*/
3235
jsi::Value get(jsi::Runtime &runtime, jsi::PropNameID const &name) override;
36+
37+
private:
38+
RuntimeScheduler runtimeScheduler_;
3339
};
3440

3541
} // namespace facebook::react

ReactCommon/react/renderer/runtimescheduler/SchedulerPriority.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
#pragma once
99

10+
#include <react/debug/react_native_assert.h>
11+
1012
namespace facebook::react {
1113

1214
enum class SchedulerPriority : int {
@@ -23,4 +25,22 @@ static constexpr std::underlying_type<SchedulerPriority>::type serialize(
2325
schedulerPriority);
2426
}
2527

28+
static inline SchedulerPriority fromRawValue(double value) {
29+
switch ((int)value) {
30+
case 1:
31+
return SchedulerPriority::ImmediatePriority;
32+
case 2:
33+
return SchedulerPriority::UserBlockingPriority;
34+
case 3:
35+
return SchedulerPriority::NormalPriority;
36+
case 4:
37+
return SchedulerPriority::LowPriority;
38+
case 5:
39+
return SchedulerPriority::IdlePriority;
40+
default:
41+
react_native_assert(false && "Unsupported SchedulerPriority value");
42+
return SchedulerPriority::NormalPriority;
43+
}
44+
}
45+
2646
} // namespace facebook::react
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*
2+
* Copyright (c) Facebook, Inc. and its affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
#include "RuntimeScheduler.h"
9+
10+
namespace facebook::react {
11+
12+
Task::Task(SchedulerPriority priority, jsi::Function callback)
13+
: priority_(priority), callback_(std::move(callback)) {}
14+
15+
SchedulerPriority Task::getPriority() const {
16+
return priority_;
17+
}
18+
19+
void Task::operator()(jsi::Runtime &runtime) const {
20+
callback_.call(runtime, {});
21+
}
22+
23+
} // namespace facebook::react
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Copyright (c) Facebook, Inc. and its affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
#pragma once
9+
10+
#include <jsi/jsi.h>
11+
#include <react/renderer/runtimescheduler/SchedulerPriority.h>
12+
13+
namespace facebook::react {
14+
15+
class Task final {
16+
public:
17+
Task(SchedulerPriority priority, jsi::Function callback);
18+
19+
SchedulerPriority priority_;
20+
jsi::Function callback_;
21+
22+
SchedulerPriority getPriority() const;
23+
24+
void operator()(jsi::Runtime &runtime) const;
25+
};
26+
27+
class TaskPriorityComparer {
28+
public:
29+
inline bool operator()(
30+
std::shared_ptr<Task> const &lhs,
31+
std::shared_ptr<Task> const &rhs) {
32+
return lhs->getPriority() > rhs->getPriority();
33+
}
34+
};
35+
36+
} // namespace facebook::react

ReactCommon/react/renderer/scheduler/Scheduler.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,8 @@ Scheduler::Scheduler(
9999
auto uiManagerBinding = UIManagerBinding::createAndInstallIfNeeded(runtime);
100100
uiManagerBinding->attach(uiManager);
101101
if (enableRuntimeScheduler) {
102-
RuntimeSchedulerBinding::createAndInstallIfNeeded(runtime);
102+
RuntimeSchedulerBinding::createAndInstallIfNeeded(
103+
runtime, runtimeExecutor_);
103104
}
104105
});
105106

0 commit comments

Comments
 (0)