Skip to content

Commit d72a4c9

Browse files
DataLoaders 8: docs, guide, etc (#4567)
Some docs for the whole thing. It heavily relies on linking to the examples for exact details and to avoid rot. It's probably extremely bad. Help welcome. --- Part of a series of PRs to make it possible to load _any_ file from the local filesystem, by any means, on web and native: - #4516 - #4517 - #4518 - #4519 - #4520 - #4521 - #4565 - #4566 - #4567 Co-authored-by: Nikolaus West <[email protected]>
1 parent 803a1cd commit d72a4c9

File tree

8 files changed

+219
-126
lines changed

8 files changed

+219
-126
lines changed

crates/re_data_source/src/data_loader/loader_external.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,14 @@ pub fn iter_external_loaders() -> impl ExactSizeIterator<Item = std::path::PathB
6262
// ---
6363

6464
/// A [`crate::DataLoader`] that forwards the path to load to all executables present in
65-
/// the user's `PATH` with a name that starts with `EXTERNAL_DATA_LOADER_PREFIX`.
65+
/// the user's `PATH` with a name that starts with [`EXTERNAL_DATA_LOADER_PREFIX`].
6666
///
6767
/// The external loaders are expected to log rrd data to their standard output.
6868
///
6969
/// Refer to our `external_data_loader` example for more information.
70+
///
71+
/// Checkout our [guide](https://www.rerun.io/docs/howto/open-any-file?speculative-link) on
72+
/// how to implement external loaders.
7073
pub struct ExternalLoader;
7174

7275
impl crate::DataLoader for ExternalLoader {

crates/re_data_source/src/data_loader/mod.rs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,21 @@ use re_log_types::{ArrowMsg, DataRow, LogMsg};
3333
///
3434
/// ## Registering custom loaders
3535
///
36-
/// TODO(cmc): web guide in upcoming PR
36+
/// Checkout our [guide](https://www.rerun.io/docs/howto/open-any-file?speculative-link).
3737
///
3838
/// ## Execution
3939
///
40-
/// **All** registered [`DataLoader`]s get called when a user tries to open a file, unconditionally.
40+
/// **All** known [`DataLoader`]s get called when a user tries to open a file, unconditionally.
4141
/// This gives [`DataLoader`]s maximum flexibility to decide what files they are interested in, as
4242
/// opposed to e.g. only being able to look at files' extensions.
4343
///
44+
/// If a [`DataLoader`] has no interest in the given file, it should fail as soon as possible
45+
/// with a [`DataLoaderError::Incompatible`] error.
46+
///
47+
/// Iff all [`DataLoader`]s (including custom and external ones) return with a [`DataLoaderError::Incompatible`]
48+
/// error, the Viewer will show an error message to the user indicating that the file type is not
49+
/// supported.
50+
///
4451
/// On native, [`DataLoader`]s are executed in parallel.
4552
///
4653
/// [Rerun files]: crate::SUPPORTED_RERUN_EXTENSIONS
@@ -78,8 +85,8 @@ pub trait DataLoader: Send + Sync {
7885
/// possible (e.g. didn't even manage to open the file).
7986
/// Otherwise, they should log errors that happen in an asynchronous context.
8087
///
81-
/// If a [`DataLoader`] has no interest in the given file, it should successfully return
82-
/// without pushing any data into `tx`.
88+
/// If a [`DataLoader`] has no interest in the given file, it should fail as soon as possible
89+
/// with a [`DataLoaderError::Incompatible`] error.
8390
#[cfg(not(target_arch = "wasm32"))]
8491
fn load_from_path(
8592
&self,
@@ -111,8 +118,8 @@ pub trait DataLoader: Send + Sync {
111118
/// possible (e.g. didn't even manage to open the file).
112119
/// Otherwise, they should log errors that happen in an asynchronous context.
113120
///
114-
/// If a [`DataLoader`] has no interest in the given file, it should successfully return
115-
/// without pushing any data into `tx`.
121+
/// If a [`DataLoader`] has no interest in the given file, it should fail as soon as possible
122+
/// with a [`DataLoaderError::Incompatible`] error.
116123
fn load_from_file_contents(
117124
&self,
118125
store_id: re_log_types::StoreId,

docs/content/getting-started/installing-viewer.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
title: Installing the Rerun Viewer
3-
order: 0
3+
order: -1
44
---
55

66
The [Rerun Viewer](../reference/viewer/overview.md) can be installed independent of the SDK language you're using.
@@ -20,6 +20,7 @@ In any case you should be able to run `rerun` afterwards to start the Viewer.
2020
You'll be welcomed by an overview page that allows you to jump into some examples.
2121
If you're facing any difficulties, don't hesitate to [open an issue](https://github.com/rerun-io/rerun/issues/new/choose) or [join the Discord server](https://discord.gg/PXtCgFBSmH).
2222

23+
The Rerun Viewer has built-in support for opening many kinds of files, and can be [extended to open any other file type](../howto/open-any-file.md) without needing to modify the Rerun codebase itself.
2324

2425
To start getting your own data logged & visualized in the viewer check one of the respective getting started guides:
2526
* [Python](python.md)

docs/content/howto/open-any-file.md

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
---
2+
title: Open any file
3+
order: -10
4+
---
5+
6+
The Rerun Viewer has built-in support for opening many kinds of files, and can be extended to open any other file type without needing to modify the Rerun codebase itself.
7+
8+
The viewer can load files in 3 different ways:
9+
- via CLI arguments (e.g. `rerun myfile.jpeg`),
10+
- using drag-and-drop,
11+
- using the open dialog in the Rerun Viewer.
12+
13+
All these file loading methods support loading a single file, many files at once (e.g. `rerun myfiles/*`), or even folders.
14+
15+
⚠ Drag-and-drop of folders does [not yet work](https://github.com/rerun-io/rerun/issues/4528) on the web version of the Rerun Viewer ⚠
16+
17+
The following file types have built-in support in the Rerun Viewer:
18+
- Native Rerun files: `rrd`
19+
- 3D models: `gltf`, `glb`, `obj`
20+
- Images: `avif`, `bmp`, `dds`, `exr`, `farbfeld`, `ff`, `gif`, `hdr`, `ico`, `jpeg`, `jpg`, `pam`, `pbm`, `pgm`, `png`, `ppm`, `tga`, `tif`, `tiff`, `webp`.
21+
- Point clouds: `ply`.
22+
- Text files: `md`, `txt`.
23+
24+
With the exception of `rrd` files that can be streamed from an HTTP URL (e.g. `rerun https://demo.rerun.io/version/latest/examples/dna/data.rrd`), we only support loading files from the local filesystem for now, with [plans to make this generic over any URI and protocol in the future](https://github.com/rerun-io/rerun/issues/4525).
25+
26+
## Adding support for arbitrary filetypes
27+
28+
Internally, the [`DataLoader`](https://docs.rs/re_data_source/latest/re_data_source/trait.DataLoader.html?speculative-link) trait takes care of loading files into the Viewer.
29+
30+
There are 3 broad kinds of `DataLoader`s: _builtin_, _external_ and _custom_.
31+
_External_ and _custom_ are the two ways of extending the file loading system that we'll describe below.
32+
33+
When a user attempts to open a file in the Viewer, **all** known `DataLoader`s are notified of the path to be opened, unconditionally.
34+
This gives `DataLoader`s maximum flexibility to decide what files they are interested in, as opposed to e.g. only being able to look at a file's extension.
35+
36+
Once notified, a `DataLoader` can return a [`DataLoaderError::Incompatible`](https://docs.rs/re_data_source/latest/re_data_source/enum.DataLoaderError.html?speculative-link#variant.Incompatible) error to indicate that it doesn't support a given file type.
37+
If, and only if, all loaders known to the Viewer return an `Incompatible` error code, then an error message is shown to the user indicating that this file type is not (_yet_) supported.
38+
39+
In these instances of unsupported files, we expose two ways of implementing and registering your `DataLoader`s, explained below.
40+
41+
### External data-loaders
42+
43+
The easiest way to create your own `DataLoader` is by implementing what we call an "external loader": a stand alone executable written in any language that the Rerun SDK ships for. Any executable on your `$PATH` with a name that starts with `rerun-loader-` will be treated as a `DataLoader`.
44+
45+
This executable takes a file path as input on `stdin` and outputs Rerun logs on `stdout`.
46+
It will be called by the Rerun Viewer when the user opens a file, and be passed the path to that file.
47+
From there, it can log data as usual, using the [`stdout` logging sink](../reference/sdk-operating-modes?speculative-link#standard-inputoutput).
48+
49+
The Rerun Viewer will then automatically load the data streamed to the external loader's standard output.
50+
51+
Like any other `DataLoader`, an external loader will be notified of all file openings, unconditionally.
52+
To indicate that it does not support a given file, the loader has to exit with a [dedicated status code](https://docs.rs/rerun/latest/rerun/constant.EXTERNAL_DATA_LOADER_INCOMPATIBLE_EXIT_CODE.html?speculative-link).
53+
54+
Check out our examples for [C++](https://github.com/rerun-io/rerun/tree/main/examples/cpp/external_data_loader), [Python](https://github.com/rerun-io/rerun/tree/main/examples/python/external_data_loader) and [Rust](https://github.com/rerun-io/rerun/tree/main/examples/rust/external_data_loader) that cover every steps in details.
55+
56+
### Custom data-loaders
57+
58+
Another Rust-specific approach is to implement the `DataLoader` trait yourself and register it in the Rerun Viewer.
59+
60+
To do so, you'll need to import `rerun` as a library, register your `DataLoader` and then start the viewer from code.
61+
62+
Check out our [example](https://github.com/rerun-io/rerun/tree/main/examples/rust/custom_data_loader) that cover all these steps in details.

0 commit comments

Comments
 (0)