From 45032becc1c6a084a3c073143277adfa2547e12e Mon Sep 17 00:00:00 2001 From: Marc Rousavy Date: Tue, 17 Sep 2024 14:56:17 +0200 Subject: [PATCH] docs: Add info about custom `Dispatcher`s --- docs/docs/worklets.md | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/docs/docs/worklets.md b/docs/docs/worklets.md index aa925bf69..0b8ff0b6f 100644 --- a/docs/docs/worklets.md +++ b/docs/docs/worklets.md @@ -6,10 +6,10 @@ import TabItem from '@theme/TabItem'; # Worklets/Threading -Nitro itself is fully runtime-agnostic, which means every [Hybrid Object](hybrid-object) can be used from any JS Runtime or Worklet Context. +Nitro itself is fully runtime-agnostic, which means every [Hybrid Object](hybrid-objects) can be used from any JS Runtime or Worklet Context. This allows the caller to call into native Nitro Modules from libraries like [react-native-worklets-core](https://github.com/margelo/react-native-worklets-core), or [react-native-reanimated](https://github.com/software-mansion/react-native-reanimated). -You can use a Nitro [Hybrid Object](hybrid-object) on the default React JS context, on the UI context, or on any other background worklet context. +You can use a Nitro [Hybrid Object](hybrid-objects) on the default React JS context, on the UI context, or on any other background worklet context. @@ -51,3 +51,33 @@ A _boxed_ Hybrid Object is a native `jsi::HostObject`, which is supported by wor 4. The result of `.unbox()` is the original `HybridObject` - you can now call any methods on it as usual. In future versions of [react-native-worklets-core](https://github.com/margelo/react-native-worklets-core) or [react-native-reanimated](https://github.com/software-mansion/react-native-reanimated) we expect fullly automatic `jsi::NativeState` support, which will make boxing obsolete. + +## Dispatcher + +All synchronous APIs of Nitro work ✨ automagically ✨ on any runtime, but asynchronous APIs (Promises and callbacks) require a `Dispatcher`. + +If you call an asynchronous API on a runtime that Nitro doesn't know, it likely doesn't have a `Dispatcher`, so it doesn't know how to call back to the JS Thread after the asynchronous operation has finished (Promise resolve or callback call). + +If you created that `jsi::Runtime`, you need to create a `Dispatcher` for it and implement `runSync` and `runAsync`: + +```cpp +#include +using namespace margelo::nitro; + +class MyRuntimeDispatcher: public Dispatcher { +public: + void runSync(std::function&& function) override; + void runAsync(std::function&& function) override; +}; +``` + +Then, simply install this Dispatcher into your runtime: + +```cpp +auto myDispatcher = std::make_shared(); +Dispatcher::installRuntimeGlobalDispatcher(myRuntime, myDispatcher); +``` + +This needs to be done once, ideally immediately as soon as possible after creating the `jsi::Runtime`. + +Your `runSync` and `runAsync` implementations must run the given `function` on the same Thread that the `jsi::Runtime` was created on - see [`CallInvokerDispatcher.hpp`](https://github.com/mrousavy/nitro/blob/main/packages/react-native-nitro-modules/cpp/threading/CallInvokerDispatcher.hpp) for an example.