Skip to content

Conversation

@tjzel
Copy link
Collaborator

@tjzel tjzel commented Oct 24, 2025

Summary

Inspired by #8425

I'm adding scheduling APIs for the WorkletRuntime class resembling the ones in TypeScript API. I preserved previous scheduling APIs as deprecated.

Synchronous call methods

  • runSync
    • accepting jsi::Function or std::shared_ptr<SerializableWorklet>
    • mimicking runOn...Sync TS API etc.
    • always invokes via callGuard
    • perfectly forwards function arguments
    • returns jsi::Value
// example
jsi::Value foo(
    jsi::Function function,
    std::shared_ptr<WorkletRuntime> runtime,
    double value) {
  return runtime->runSync(function, value);
}

  • runSync (2)
    • accepting a functor that takes jsi::Runtime & as an argument, i.e. std::function<TReturn(jsi::Runtime &)>`
    • mimicking runOn...Sync TS API etc.
    • doesn't use callGuard - the user have to do it themselves
    • doesn't take function arguments - the user already passes a lambda so they can put them into closure
    • returns the type of the lambda
// example
double bar(std::shared_ptr<WorkletRuntime> runtime, double value) {
  return runtime->runSync([value](jsi::Runtime &rt) -> double {
    auto math = rt.global().getPropertyAsObject(rt, "Math");
    auto pow = math.getPropertyAsFunction(rt, "pow");
    return pow.call(rt, value).asNumber();
  });
}

  • runSyncSerialized
    • syntax sugar that does the same as runSync but returns extracted Serializable from jsi::Value
    • worklet or jsi::Function passed must serialize on its own in JS with createSerializable
    • doesn't accept std::function<TReturn(jsi::Runtime &)> as TReturn might not be serializable
// example
std::shared_ptr<Serializable> baz(
    std::shared_ptr<WorkletRuntime> runtime,
    jsi::Function function,
    double value) {
  return runtime->runSyncSerialized(function, jsi::Value(value));
}

Asynchronous call methods

  • schedule
    • mimicking scheduleOn... TS API etc.
    • accepts jsi::Function, std::shared_ptr<SerializableWorklet>, std::function<void()> or std::function<void(jsi::Runtime&)>
    • requires the Worklet Runtime to have the AsyncQueue set
    • doesn't take arguments
      • For jsi::Function and std::shared_ptr<SerializableWorklet> we don't want to be responsible for how arguments are stored in the lambda passed to AsyncQueue
      • For std::function the user can store the arguments in their lambda
    • doesn't return a value
// example
void baq(
    std::shared_ptr<WorkletRuntime> runtime,
    std::shared_ptr<SerializableWorklet> worklet) {
  runtime->schedule(worklet);
}

runAsync function possibly returning promises (futures) is yet to be considered for implementation in future PRs

Deprecated methods

  • runGuarded - identical to runSync, replaced with runSync
  • runAsyncGuarded - identical to schedule, replaced with schedule
  • (1) executeSync - this function was a bit complicated. It took two runtimes, executed a worklet on the target runtime then serialized data back to the caller runtime. While it's a handy syntax sugar I think it shouldn't be a method of a runtime but rather some utility API. Replaced with runSyncSerialized and manual extraction on the caller runtime.
  • (2) executeSync - identical to runSync replaced with runSync

Test plan

⭐ BokehExample ⭐

return getCallGuard(rt).call(rt, function, args...);
#else
return function.asObject(rt).asFunction(rt).call(rt, args...);
return function..call(rt, args...);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return function..call(rt, args...);
return function.call(rt, args...);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants