Skip to content

Commit

Permalink
docs: Add info about custom Dispatchers
Browse files Browse the repository at this point in the history
  • Loading branch information
mrousavy committed Sep 17, 2024
1 parent 1128d6a commit 45032be
Showing 1 changed file with 32 additions and 2 deletions.
34 changes: 32 additions & 2 deletions docs/docs/worklets.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

<Tabs groupId="worklet-library">
<TabItem value="rnwc" label="Worklets Core" default>
Expand Down Expand Up @@ -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 <NitroModules/Dispatcher.hpp>
using namespace margelo::nitro;

class MyRuntimeDispatcher: public Dispatcher {
public:
void runSync(std::function<void()>&& function) override;
void runAsync(std::function<void()>&& function) override;
};
```
Then, simply install this Dispatcher into your runtime:
```cpp
auto myDispatcher = std::make_shared<MyRuntimeDispatcher>();
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.

0 comments on commit 45032be

Please sign in to comment.