Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Standard input/output support 4: C++ SDK stdout impl/examples/docs #4514

Merged
merged 8 commits into from
Dec 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions crates/rerun_c/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ pub enum CErrorCode {
_CategoryRecordingStream = 0x0000_00100,
RecordingStreamCreationFailure,
RecordingStreamSaveFailure,
RecordingStreamStdoutFailure,
// TODO(cmc): Really this should be its own category…
RecordingStreamSpawnFailure,

Expand Down Expand Up @@ -468,6 +469,24 @@ pub extern "C" fn rr_recording_stream_save(
}
}

#[allow(clippy::result_large_err)]
fn rr_recording_stream_stdout_impl(stream: CRecordingStream) -> Result<(), CError> {
recording_stream(stream)?.stdout().map_err(|err| {
CError::new(
CErrorCode::RecordingStreamStdoutFailure,
&format!("Failed to forward recording stream to stdout: {err}"),
)
})
}

#[allow(unsafe_code)]
#[no_mangle]
pub extern "C" fn rr_recording_stream_stdout(id: CRecordingStream, error: *mut CError) {
if let Err(err) = rr_recording_stream_stdout_impl(id) {
err.write_error(error);
}
}

#[allow(clippy::result_large_err)]
fn rr_recording_stream_set_time_sequence_impl(
stream: CRecordingStream,
Expand Down
11 changes: 11 additions & 0 deletions crates/rerun_c/src/rerun.h
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ enum {
_RR_ERROR_CODE_CATEGORY_RECORDING_STREAM = 0x000000100,
RR_ERROR_CODE_RECORDING_STREAM_CREATION_FAILURE,
RR_ERROR_CODE_RECORDING_STREAM_SAVE_FAILURE,
RR_ERROR_CODE_RECORDING_STREAM_STDOUT_FAILURE,
teh-cmc marked this conversation as resolved.
Show resolved Hide resolved
RR_ERROR_CODE_RECORDING_STREAM_SPAWN_FAILURE,

// Arrow data processing errors.
Expand Down Expand Up @@ -333,6 +334,16 @@ extern void rr_recording_stream_spawn(
/// This function returns immediately.
extern void rr_recording_stream_save(rr_recording_stream stream, rr_string path, rr_error* error);

/// Stream all log-data to stdout.
///
/// Pipe the result into the Rerun Viewer to visualize it.
///
/// If there isn't any listener at the other end of the pipe, the `RecordingStream` will
/// default back to `buffered` mode, in order not to break the user's terminal.
///
/// This function returns immediately.
extern void rr_recording_stream_stdout(rr_recording_stream stream, rr_error* error);

/// Initiates a flush the batching pipeline and waits for it to propagate.
///
/// See `rr_recording_stream` docs for ordering semantics and multithreading guarantees.
Expand Down
6 changes: 6 additions & 0 deletions docs/content/reference/sdk-operating-modes.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,12 @@ Use [`RecordingStream::save`](https://docs.rs/rerun/latest/rerun/struct.Recordin

Streams all logging data to standard output, which can then be loaded by the Rerun Viewer by streaming it from standard input.

#### C++

Use [`RecordingStream::stdout`](https://ref.rerun.io/docs/cpp/stable/classrerun_1_1RecordingStream.html#SOMEHASH?speculative-link).
Copy link
Member Author

@teh-cmc teh-cmc Dec 14, 2023

Choose a reason for hiding this comment

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

I'm gonna have a hard time coming up with the exact right hash speculatively...


Check out our [dedicated example](https://github.com/rerun-io/rerun/tree/latest/examples/cpp/stdio/main.cpp?speculative-link).

#### Python

Use [`rr.stdout`](https://ref.rerun.io/docs/python/stable/common/initialization_functions/#rerun.stdout?speculative-link).
Expand Down
6 changes: 4 additions & 2 deletions examples/cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
add_subdirectory(clock)
add_subdirectory(custom_collection_adapter)
add_subdirectory(dna)
add_subdirectory(shared_recording)
add_subdirectory(minimal)
add_subdirectory(shared_recording)
add_subdirectory(spawn_viewer)
add_subdirectory(stdio)

add_custom_target(examples)

add_dependencies(examples example_clock)
add_dependencies(examples example_custom_collection_adapter)
add_dependencies(examples example_dna)
add_dependencies(examples example_shared_recording)
add_dependencies(examples example_minimal)
add_dependencies(examples example_shared_recording)
add_dependencies(examples example_spawn_viewer)
add_dependencies(examples example_stdio)
32 changes: 32 additions & 0 deletions examples/cpp/stdio/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
cmake_minimum_required(VERSION 3.16...3.27)

teh-cmc marked this conversation as resolved.
Show resolved Hide resolved
# If you use the example outside of the Rerun SDK you need to specify
# where the rerun_c build is to be found by setting the `RERUN_CPP_URL` variable.
# This can be done by passing `-DRERUN_CPP_URL=<path to rerun_sdk_cpp zip>` to cmake.
if(DEFINED RERUN_REPOSITORY)
add_executable(example_stdio main.cpp)
rerun_strict_warning_settings(example_stdio)
else()
project(example_stdio LANGUAGES CXX)

add_executable(example_stdio main.cpp)

# Set the path to the rerun_c build.
set(RERUN_CPP_URL "https://github.com/rerun-io/rerun/releases/latest/download/rerun_cpp_sdk.zip" CACHE STRING "URL to the rerun_cpp zip.")
option(RERUN_FIND_PACKAGE "Whether to use find_package to find a preinstalled rerun package (instead of using FetchContent)." OFF)

if(RERUN_FIND_PACKAGE)
find_package(rerun_sdk REQUIRED)
else()
# Download the rerun_sdk
include(FetchContent)
FetchContent_Declare(rerun_sdk URL ${RERUN_CPP_URL})
FetchContent_MakeAvailable(rerun_sdk)
endif()

# Rerun requires at least C++17, but it should be compatible with newer versions.
set_property(TARGET example_stdio PROPERTY CXX_STANDARD 17)
endif()

# Link against rerun_sdk.
target_link_libraries(example_stdio PRIVATE rerun_sdk)
24 changes: 24 additions & 0 deletions examples/cpp/stdio/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
title: Standard Input/Output example
python: https://github.com/rerun-io/rerun/tree/latest/examples/python/stdio/main.py?speculative-link
rust: https://github.com/rerun-io/rerun/tree/latest/examples/rust/stdio/src/main.rs?speculative-link
cpp: https://github.com/rerun-io/rerun/tree/latest/examples/cpp/stdio/main.cpp?speculative-link
thumbnail: https://static.rerun.io/stdio/25c5aba992d4c8b3861386d8d9539a4823dca117/480w.png
---

<picture>
<img src="https://static.rerun.io/stdio/25c5aba992d4c8b3861386d8d9539a4823dca117/full.png" alt="">
<source media="(max-width: 480px)" srcset="https://static.rerun.io/stdio/25c5aba992d4c8b3861386d8d9539a4823dca117/480w.png">
<source media="(max-width: 768px)" srcset="https://static.rerun.io/stdio/25c5aba992d4c8b3861386d8d9539a4823dca117/768w.png">
<source media="(max-width: 1024px)" srcset="https://static.rerun.io/stdio/25c5aba992d4c8b3861386d8d9539a4823dca117/1024w.png">
<source media="(max-width: 1200px)" srcset="https://static.rerun.io/stdio/25c5aba992d4c8b3861386d8d9539a4823dca117/1200w.png">
</picture>

Demonstrates how to log data to standard output with the Rerun SDK, and then visualize it from standard input with the Rerun Viewer.

To build it from a checkout of the repository (requires a Rust toolchain):
```bash
cmake .
cmake --build . --target example_stdio
echo 'hello from stdin!' | ./examples/cpp/stdio/example_stdio | rerun -
```
17 changes: 17 additions & 0 deletions examples/cpp/stdio/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#include <iostream>
#include <string>

#include <rerun.hpp>

int main() {
const auto rec = rerun::RecordingStream("rerun_example_stdio");
rec.to_stdout().exit_on_failure();

std::string input;
std::string line;
while (std::getline(std::cin, line)) {
input += line + '\n';
}

rec.log("stdin", rerun::TextDocument(input));
}
11 changes: 11 additions & 0 deletions rerun_cpp/src/rerun/c/rerun.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions rerun_cpp/src/rerun/error.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ namespace rerun {
_CategoryRecordingStream = 0x0000'0100,
RecordingStreamCreationFailure,
RecordingStreamSaveFailure,
RecordingStreamStdoutFailure,
RecordingStreamSpawnFailure,

// Arrow data processing errors.
Expand Down
6 changes: 6 additions & 0 deletions rerun_cpp/src/rerun/recording_stream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,12 @@ namespace rerun {
return status;
}

Error RecordingStream::to_stdout() const {
rr_error status = {};
rr_recording_stream_stdout(_id, &status);
return status;
}

void RecordingStream::flush_blocking() const {
rr_recording_stream_flush_blocking(_id);
}
Expand Down
14 changes: 14 additions & 0 deletions rerun_cpp/src/rerun/recording_stream.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,20 @@ namespace rerun {
/// This function returns immediately.
Error save(std::string_view path) const;

/// Stream all log-data to standard output.
///
/// Pipe the result into the Rerun Viewer to visualize it.
///
/// If there isn't any listener at the other end of the pipe, the `RecordingStream` will
/// default back to `buffered` mode, in order not to break the user's terminal.
///
/// This function returns immediately.
//
// NOTE: This should be called `stdout` like in other SDK, but turns out that `stdout` is a
// macro when compiling with msvc [1].
// [1]: https://learn.microsoft.com/en-us/cpp/c-runtime-library/stdin-stdout-stderr?view=msvc-170
Error to_stdout() const;
teh-cmc marked this conversation as resolved.
Show resolved Hide resolved

/// Initiates a flush the batching pipeline and waits for it to propagate.
///
/// See `RecordingStream` docs for ordering semantics and multithreading guarantees.
Expand Down
Loading