Implement RuntimeScheduler::cancelTask

Summary:
Changelog: [internal]

Implement RuntimeScheduler::cancelTask and expose it through JSI.

JavaScript implementation:
https://github.com/facebook/react/blob/master/packages/scheduler/src/forks/SchedulerNoDOM.js#L384-L397

Reviewed By: mdvacca

Differential Revision: D27648071

fbshipit-source-id: 91ae92b336017596fb658831824e971c7e047cd2
This commit is contained in:
Samuel Susla
2021-04-13 01:55:04 -07:00
committed by Facebook GitHub Bot
parent 3c14c196ca
commit 08ef1df1ba
7 changed files with 49 additions and 4 deletions
@@ -50,5 +50,6 @@ rn_xplat_cxx_library(
deps = [
react_native_xplat_target("runtimeexecutor:runtimeexecutor"),
react_native_xplat_target("react/renderer/debug:debug"),
react_native_xplat_target("better:better"),
],
)
@@ -22,4 +22,8 @@ void RuntimeScheduler::scheduleTask(std::shared_ptr<Task> const &task) {
});
}
void RuntimeScheduler::cancelTask(const std::shared_ptr<Task> &task) {
task->cancel();
}
} // namespace facebook::react
@@ -20,6 +20,8 @@ class RuntimeScheduler final {
void scheduleTask(std::shared_ptr<Task> const &task);
void cancelTask(std::shared_ptr<Task> const &task);
private:
mutable std::priority_queue<
std::shared_ptr<Task>,
@@ -70,6 +70,20 @@ jsi::Value RuntimeSchedulerBinding::get(
});
}
if (propertyName == "unstable_cancelCallback") {
return jsi::Function::createFromHostFunction(
runtime,
name,
1,
[this](
jsi::Runtime &runtime,
jsi::Value const &,
jsi::Value const *arguments,
size_t) noexcept -> jsi::Value {
runtimeScheduler_.cancelTask(taskFromValue(runtime, arguments[0]));
return jsi::Value::undefined();
});
}
if (propertyName == "unstable_ImmediatePriority") {
return jsi::Value(runtime, serialize(SchedulerPriority::ImmediatePriority));
}
@@ -91,6 +105,7 @@ jsi::Value RuntimeSchedulerBinding::get(
return jsi::Value(runtime, serialize(SchedulerPriority::IdlePriority));
}
react_native_assert(false && "undefined property");
return jsi::Value::undefined();
}
@@ -16,8 +16,18 @@ SchedulerPriority Task::getPriority() const {
return priority_;
}
void Task::cancel() {
// Null out the callback to indicate the task has been canceled. (Can't
// remove from the priority_queue because you can't remove arbitrary nodes
// from an array based heap, only the first one.)
callback_.reset();
}
void Task::operator()(jsi::Runtime &runtime) const {
callback_.call(runtime, {});
if (callback_) {
// Cancelled task doesn't have a callback.
callback_.value().call(runtime, {});
}
}
} // namespace facebook::react
@@ -7,6 +7,7 @@
#pragma once
#include <better/optional.h>
#include <jsi/jsi.h>
#include <react/renderer/runtimescheduler/SchedulerPriority.h>
@@ -16,12 +17,14 @@ class Task final {
public:
Task(SchedulerPriority priority, jsi::Function callback);
SchedulerPriority priority_;
jsi::Function callback_;
SchedulerPriority getPriority() const;
void cancel();
void operator()(jsi::Runtime &runtime) const;
private:
SchedulerPriority priority_;
better::optional<jsi::Function> callback_;
};
class TaskPriorityComparer {
@@ -26,4 +26,14 @@ inline static jsi::Value valueFromTask(
runtime, std::make_shared<TaskWrapper>(task));
}
inline static std::shared_ptr<Task> taskFromValue(
jsi::Runtime &runtime,
jsi::Value const &value) {
if (value.isNull()) {
return nullptr;
}
return value.getObject(runtime).getHostObject<TaskWrapper>(runtime)->task;
}
} // namespace facebook::react