Skip to content

Commit

Permalink
Add "spawn" variants for Quick Start guides (#3912)
Browse files Browse the repository at this point in the history
### What

By default, the Quick Start guides show instructions that will send a
recording to the current viewer. This is only possible if the viewer
accepts TPC connection (which is not the case of Web-based viewers).
This PR adds a varient for the guides that will instead spawn a local
viewer whenever TCP connections aren't accepted.

* Fixes #3871

In a connection-accepting viewer:

<img width="1291" alt="image"
src="https://github.com/rerun-io/rerun/assets/49431240/f4ffbb87-c01c-412f-b0b5-ac2df5c16bb8">

In a web viewer:

<img width="1185" alt="image"
src="https://github.com/rerun-io/rerun/assets/49431240/c5106daa-babb-4bbd-9c30-3a2aee9c59c5">


### Checklist
* [x] I have read and agree to [Contributor
Guide](https://github.com/rerun-io/rerun/blob/main/CONTRIBUTING.md) and
the [Code of
Conduct](https://github.com/rerun-io/rerun/blob/main/CODE_OF_CONDUCT.md)
* [x] I've included a screenshot or gif (if applicable)
* [x] I have tested [demo.rerun.io](https://demo.rerun.io/pr/3912) (if
applicable)
* [x] The PR title and labels are set such as to maximize their
usefulness for the next release's CHANGELOG

- [PR Build Summary](https://build.rerun.io/pr/3912)
- [Docs
preview](https://rerun.io/preview/5d04ce8296947cab55c1373990037f7266a5834c/docs)
<!--DOCS-PREVIEW-->
- [Examples
preview](https://rerun.io/preview/5d04ce8296947cab55c1373990037f7266a5834c/examples)
<!--EXAMPLES-PREVIEW-->
- [Recent benchmark results](https://ref.rerun.io/dev/bench/)
- [Wasm size tracking](https://ref.rerun.io/dev/sizes/)
  • Loading branch information
abey79 authored Oct 19, 2023
1 parent 610ebda commit f3a5ae2
Show file tree
Hide file tree
Showing 16 changed files with 203 additions and 28 deletions.
8 changes: 8 additions & 0 deletions crates/re_smart_channel/src/receive_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,14 @@ impl<T: Send> ReceiveSet<T> {
!self.is_empty()
}

/// Does this viewer accept inbound TCP connections?
pub fn accepts_tcp_connections(&self) -> bool {
re_tracing::profile_function!();
self.sources()
.iter()
.any(|s| matches!(**s, SmartChannelSource::TcpServer { .. }))
}

/// No connected receivers?
///
/// This gets updated after calling one of the `recv` methods.
Expand Down
3 changes: 3 additions & 0 deletions crates/re_viewer/data/quick_start_guides/cpp_spawn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
## C++ Quick Start

TODO(ab): https://github.com/rerun-io/rerun/issues/3870
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ The Rerun SDK comes with a demo that can be used to try the viewer. You can send
to this viewer using the following command:

```sh
python -m rerun_sdk.demo --connect
python -m rerun_sdk --connect
```

This will open a new recording that looks like this:
Expand Down
36 changes: 36 additions & 0 deletions crates/re_viewer/data/quick_start_guides/python_spawn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
## Python Quick Start

${SAFARI_WARNING}

### Installing the Rerun SDK

The Rerun SDK is available on [PyPI](https://pypi.org/) under the
[`rerun-sdk`](https://pypi.org/project/rerun-sdk/) name. It can be installed like any other
Python package:

```sh
pip install rerun-sdk
```

### Try out the viewer

The Rerun SDK comes with a demo that can be used to try the viewer. You can spawn a native viewer and load a demo using the following command:

```sh
python -m rerun_sdk
```

This will open a new recording that looks like this:

![Demo recording](https://static.rerun.io/quickstart2_simple_cube/632a8f1c79f70a2355fad294fe085291fcf3a8ae/768w.png)


### Logging your own data

Instead of a pre-packaged demo, you can log your own data. Copy and paste the following snippet in a new Python file and execute it to create a recording in a new viewer:

```python
${EXAMPLE_CODE}
```

${HOW_DOES_IT_WORK}
35 changes: 35 additions & 0 deletions crates/re_viewer/data/quick_start_guides/rust_spawn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
## Rust Quick Start

${SAFARI_WARNING}

### Installing Rerun

To use the Rerun SDK in your project, you need the [rerun crate](https://crates.io/crates/rerun) which you can add with `cargo add rerun`.

Let's try it out in a brand-new Rust project:

```sh
cargo init cube && cd cube && cargo add rerun --features native_viewer
```

Note that the Rerun SDK requires a working installation of Rust 1.72+.

### Logging your own data

Add the following code to your `main.rs` file:

```rust
${EXAMPLE_CODE}
```

You can now run your application:

```shell
cargo run
```

Once everything finishes compiling, a new viewer will start displaying these points:

![Demo recording](https://static.rerun.io/intro_rust_result/cc780eb9bf014d8b1a68fac174b654931f92e14f/768w.png)

${HOW_DOES_IT_WORK}
83 changes: 56 additions & 27 deletions crates/re_viewer/src/ui/welcome_screen/welcome_page.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,30 @@ use std::collections::HashMap;

const SPACE_VIEWS_HELP: &str = "https://www.rerun.io/docs/getting-started/viewer-walkthrough";

const HOW_DOES_IT_WORK: &str = include_str!("../../../data/quick_start_guides/how_does_it_work.md");
const CPP_CONNECT_MARKDOWN: &str = include_str!("../../../data/quick_start_guides/cpp_connect.md");
const CPP_SPAWN_MARKDOWN: &str = include_str!("../../../data/quick_start_guides/cpp_spawn.md");
const PYTHON_CONNECT_MARKDOWN: &str =
include_str!("../../../data/quick_start_guides/python_connect.md");
const PYTHON_SPAWN_MARKDOWN: &str =
include_str!("../../../data/quick_start_guides/python_spawn.md");
const RUST_CONNECT_MARKDOWN: &str =
include_str!("../../../data/quick_start_guides/rust_connect.md");
const RUST_SPAWN_MARKDOWN: &str = include_str!("../../../data/quick_start_guides/rust_spawn.md");
const HOW_DOES_IT_WORK_MARKDOWN: &str =
include_str!("../../../data/quick_start_guides/how_does_it_work.md");

const CPP_CONNECT_CODE_EXAMPLE: &str =
include_str!("../../../data/quick_start_guides/quick_start_connect.cpp");
const CPP_SPAWN_CODE_EXAMPLE: &str =
include_str!("../../../data/quick_start_guides/quick_start_spawn.cpp");
const PYTHON_CONNECT_CODE_EXAMPLE: &str =
include_str!("../../../data/quick_start_guides/quick_start_connect.py");
const PYTHON_SPAWN_CODE_EXAMPLE: &str =
include_str!("../../../data/quick_start_guides/quick_start_spawn.py");
const RUST_CONNECT_CODE_EXAMPLE: &str =
include_str!("../../../data/quick_start_guides/quick_start_connect.rs");
const RUST_SPAWN_CODE_EXAMPLE: &str =
include_str!("../../../data/quick_start_guides/quick_start_spawn.rs");

/// Show the welcome page.
///
Expand All @@ -22,7 +45,9 @@ pub(super) fn welcome_page_ui(
command_sender: &re_viewer_context::CommandSender,
) -> WelcomeScreenResponse {
ui.vertical(|ui| {
let show_example = onboarding_content_ui(ui, command_sender);
let accepts_connections = rx.accepts_tcp_connections();

let show_example = onboarding_content_ui(ui, command_sender, accepts_connections);

for status_strings in status_strings(rx) {
if status_strings.long_term {
Expand Down Expand Up @@ -52,6 +77,7 @@ struct WelcomePagePanel<'a> {
fn onboarding_content_ui(
ui: &mut Ui,
command_sender: &re_viewer_context::CommandSender,
accepts_connections: bool,
) -> WelcomeScreenResponse {
// The panel data is stored in this ad hoc structure such that it can easily be iterated over
// in chunks, to make the layout grid code simpler.
Expand All @@ -63,20 +89,21 @@ fn onboarding_content_ui(
image: &re_ui::icons::WELCOME_SCREEN_LIVE_DATA,
add_buttons: Box::new(|ui: &mut egui::Ui| {
//TODO(#3870): enable with C++ guides are completed
#[allow(clippy::collapsible_if)]
#[allow(clippy::collapsible_if, clippy::if_same_then_else)]
if false {
if large_text_button(ui, "C++").clicked() {
let (markdown, code) = if accepts_connections {
(CPP_CONNECT_MARKDOWN, CPP_CONNECT_CODE_EXAMPLE)
} else {
(CPP_SPAWN_MARKDOWN, CPP_SPAWN_CODE_EXAMPLE)
};

open_quick_start(
command_sender,
include_str!("../../../data/quick_start_guides/cpp_native.md"),
markdown,
[
(
"EXAMPLE_CODE",
include_str!(
"../../../data/quick_start_guides/quick_start_connect.cpp"
),
),
("HOW_DOES_IT_WORK", HOW_DOES_IT_WORK),
("EXAMPLE_CODE", code),
("HOW_DOES_IT_WORK", HOW_DOES_IT_WORK_MARKDOWN),
("SAFARI_WARNING", safari_warning()),
]
.into(),
Expand All @@ -86,17 +113,18 @@ fn onboarding_content_ui(
}
}
if large_text_button(ui, "Python").clicked() {
let (markdown, code) = if accepts_connections {
(PYTHON_CONNECT_MARKDOWN, PYTHON_CONNECT_CODE_EXAMPLE)
} else {
(PYTHON_SPAWN_MARKDOWN, PYTHON_SPAWN_CODE_EXAMPLE)
};

open_quick_start(
command_sender,
include_str!("../../../data/quick_start_guides/python_native.md"),
markdown,
[
(
"EXAMPLE_CODE",
include_str!(
"../../../data/quick_start_guides/quick_start_connect.py"
),
),
("HOW_DOES_IT_WORK", HOW_DOES_IT_WORK),
("EXAMPLE_CODE", code),
("HOW_DOES_IT_WORK", HOW_DOES_IT_WORK_MARKDOWN),
("SAFARI_WARNING", safari_warning()),
]
.into(),
Expand All @@ -105,17 +133,18 @@ fn onboarding_content_ui(
);
}
if large_text_button(ui, "Rust").clicked() {
let (markdown, code) = if accepts_connections {
(RUST_CONNECT_MARKDOWN, RUST_CONNECT_CODE_EXAMPLE)
} else {
(RUST_SPAWN_MARKDOWN, RUST_SPAWN_CODE_EXAMPLE)
};

open_quick_start(
command_sender,
include_str!("../../../data/quick_start_guides/rust_native.md"),
markdown,
[
(
"EXAMPLE_CODE",
include_str!(
"../../../data/quick_start_guides/quick_start_connect.rs"
),
),
("HOW_DOES_IT_WORK", HOW_DOES_IT_WORK),
("EXAMPLE_CODE", code),
("HOW_DOES_IT_WORK", HOW_DOES_IT_WORK_MARKDOWN),
("SAFARI_WARNING", safari_warning()),
]
.into(),
Expand Down
4 changes: 4 additions & 0 deletions docs/code-examples/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,10 @@ path = "point3d_simple.rs"
name = "quick_start_connect"
path = "quick_start_connect.rs"

[[bin]]
name = "quick_start_spawn"
path = "quick_start_spawn.rs"

[[bin]]
name = "scalar_simple"
path = "scalar_simple.rs"
Expand Down
5 changes: 5 additions & 0 deletions docs/code-examples/quick_start_spawn.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// TODO(ab): https://github.com/rerun-io/rerun/issues/3870

int main() {
return 0;
}
24 changes: 24 additions & 0 deletions docs/code-examples/quick_start_spawn.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
"""Spawn a viewer and log some data."""

import numpy as np
import rerun as rr

# Initialize the SDK, give our recording a unique name, and spawn a viewer
rr.init("rerun_example_demo", spawn=True)

# Create some data
SIZE = 10

pos_grid = np.meshgrid(*[np.linspace(-10, 10, SIZE)] * 3)
positions = np.vstack([d.reshape(-1) for d in pos_grid]).T

col_grid = np.meshgrid(*[np.linspace(0, 255, SIZE)] * 3)
colors = np.vstack([c.reshape(-1) for c in col_grid]).astype(np.uint8).T

# Log the data
rr.log(
# name under which this entity is logged (known as "entity path")
"my_points",
# log data as a 3D point cloud archetype
rr.Points3D(positions, colors=colors, radii=0.5),
)
26 changes: 26 additions & 0 deletions docs/code-examples/quick_start_spawn.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//! Spawn a viewer and log some data.
use rerun::{demo_util::grid, external::glam};

fn main() -> Result<(), Box<dyn std::error::Error>> {
// Create a new `RecordingStream` which stores data in memory.
let (rec, storage) = rerun::RecordingStreamBuilder::new("rerun_example_minimal_rs").memory()?;

// Create some data using the `grid` utility function.
let points = grid(glam::Vec3::splat(-10.0), glam::Vec3::splat(10.0), 10);
let colors = grid(glam::Vec3::ZERO, glam::Vec3::splat(255.0), 10)
.map(|v| rerun::Color::from_rgb(v.x as u8, v.y as u8, v.z as u8));

// Log the "my_points" entity with our data, using the `Points3D` archetype.
rec.log(
"my_points",
&rerun::Points3D::new(points)
.with_colors(colors)
.with_radii([0.5]),
)?;

// Show the viewer with the recorded data.
rerun::native_viewer::show(storage.take())?;

Ok(())
}
2 changes: 2 additions & 0 deletions docs/code-examples/roundtrips.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"image_advanced": ["cpp", "rust"], # Missing examples
"log_line": ["cpp", "rust", "py"], # Not a complete example -- just a single log line
"quick_start_connect": ["cpp"], # TODO(#3870): Not yet implemented in C++
"quick_start_spawn": ["cpp"], # TODO(#3870): Not yet implemented in C++
"text_log_integration": ["cpp"], # TODO(#2919): Not yet implemented in C++

# This is this script, it's not an example.
Expand All @@ -44,6 +45,7 @@
"point2d_random": ["cpp", "py", "rust"], # TODO(#3206): examples use different RNGs
"point3d_random": ["cpp", "py", "rust"], # TODO(#3206): examples use different RNGs
"quick_start_connect": ["cpp", "py", "rust"], # These example don't have exactly the same implementation.
"quick_start_spawn": ["cpp", "py", "rust"], # These example don't have exactly the same implementation.
"scalar_multiple_plots": ["cpp"], # trigonometric functions have slightly different outcomes
"tensor_simple": ["cpp", "py", "rust"], # TODO(#3206): examples use different RNGs
"transform3d_simple": ["cpp"], # TODO(#2919): Something broken in the C++ SDK
Expand Down

0 comments on commit f3a5ae2

Please sign in to comment.