Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
teh-cmc committed Mar 4, 2024
1 parent 0ef2fa1 commit 76d84d8
Show file tree
Hide file tree
Showing 7 changed files with 210 additions and 59 deletions.
29 changes: 27 additions & 2 deletions crates/rerun_c/src/rerun.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,30 @@ typedef struct rr_spawn_options {
rr_string executable_path;
} rr_spawn_options;

/// Recommended settings for the [`DataLoader`].
///
/// The loader is free to ignore some or all of these.
///
/// Refer to the field-level documentation for more information about each individual options.
//
// TODO(#3841): expose timepoint settings once we implement stateless APIs
typedef struct rr_data_loader_settings {
/// The recommended `RecordingId` to log the data to.
///
/// Unspecified by default.
rr_string recording_id;

/// What should the logged entity paths be prefixed with?
///
/// Unspecified by default.
rr_string entity_path_prefix;

/// Should the logged data be timeless?
///
/// Defaults to `false` if not set.
bool timeless;
} rr_data_loader_settings;

typedef struct rr_store_info {
/// The user-chosen name of the application doing the logging.
rr_string application_id;
Expand Down Expand Up @@ -432,7 +456,7 @@ extern void rr_recording_stream_log(
///
/// See <https://www.rerun.io/docs/howto/open-any-file> for more information.
extern void rr_recording_stream_log_file_from_path(
rr_recording_stream stream, rr_string path, rr_error* error
rr_recording_stream stream, rr_data_loader_settings settings, rr_string path, rr_error* error
);

/// Logs the given `contents` using all `DataLoader`s available.
Expand All @@ -444,7 +468,8 @@ extern void rr_recording_stream_log_file_from_path(
///
/// See <https://www.rerun.io/docs/howto/open-any-file> for more information.
extern void rr_recording_stream_log_file_from_contents(
rr_recording_stream stream, rr_string path, rr_bytes contents, rr_error* error
rr_recording_stream stream, rr_data_loader_settings settings, rr_string path, rr_bytes contents,
rr_error* error
);

// ----------------------------------------------------------------------------
Expand Down
118 changes: 74 additions & 44 deletions examples/cpp/external_data_loader/main.cpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,54 @@
#include <cstdint>
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>

#include <rerun.hpp>
#include <rerun/third_party/cxxopts.hpp>
#include <string_view>

void set_time_from_args(const rerun::RecordingStream& rec, cxxopts::ParseResult& args) {
if (args.count("time")) {
const auto times = args["time"].as<std::vector<std::string>>();
for (const auto& time_str : times) {
auto pos = time_str.find('=');
if (pos != std::string::npos) {
auto timeline_name = time_str.substr(0, pos);
int64_t time = std::stoi(time_str.substr(pos + 1));
rec.set_time_seconds(timeline_name, time);
}
}
}

if (args.count("sequence")) {
const auto sequences = args["sequence"].as<std::vector<std::string>>();
for (const auto& sequence_str : sequences) {
auto pos = sequence_str.find('=');
if (pos != std::string::npos) {
auto timeline_name = sequence_str.substr(0, pos);
int64_t sequence = std::stoi(sequence_str.substr(pos + 1));
rec.set_time_sequence(timeline_name, sequence);
}
}
}
}

int main(int argc, char* argv[]) {
// The Rerun Viewer will always pass these two pieces of information:
// 1. The path to be loaded, as a positional arg.
// 2. A shared recording ID, via the `--recording-id` flag.
//
// It is up to you whether you make use of that shared recording ID or not.
// If you use it, the data will end up in the same recording as all other plugins interested in
// that file, otherwise you can just create a dedicated recording for it. Or both.
//
// Check out `re_data_source::DataLoaderSettings` documentation for an exhaustive listing of
// the available CLI parameters.

static const char* USAGE = R"(
cxxopts::Options options(
"rerun-loader-cpp-file",
R"(
This is an example executable data-loader plugin for the Rerun Viewer.
Any executable on your `$PATH` with a name that starts with `rerun-loader-` will be treated as an
external data-loader.
Expand All @@ -15,51 +58,31 @@ special exit code to indicate that it doesn't support anything else.
To try it out, compile it and place it in your $PATH as `rerun-loader-cpp-file`, then open a C++ source
file with Rerun (`rerun file.cpp`).
)"
);

USAGE:
rerun-loader-cpp-file [OPTIONS] FILEPATH
FLAGS:
-h, --help Prints help information
OPTIONS:
--recording-id RECORDING_ID ID of the shared recording
ARGS:
<FILEPATH>
)";

int main(int argc, char* argv[]) {
// The Rerun Viewer will always pass these two pieces of information:
// 1. The path to be loaded, as a positional arg.
// 2. A shared recording ID, via the `--recording-id` flag.
//
// It is up to you whether you make use of that shared recording ID or not.
// If you use it, the data will end up in the same recording as all other plugins interested in
// that file, otherwise you can just create a dedicated recording for it. Or both.
std::string filepath;
std::string recording_id;

for (int i = 1; i < argc; ++i) {
std::string arg(argv[i]);

if (arg == "--recording-id") {
if (i + 1 < argc) {
recording_id = argv[i + 1];
++i;
} else {
std::cerr << USAGE << std::endl;
return 1;
}
} else {
filepath = arg;
}
// clang-format off
options.add_options()
("h,help", "Print usage")
("filepath", "The filepath to be loaded and logged", cxxopts::value<std::string>())
("recording-id", "Optional recommended ID for the recording", cxxopts::value<std::string>())
("entity-path-prefix", "Optional prefix for all entity paths", cxxopts::value<std::string>())
("timeless", "Optionally mark data to be logged as timeless", cxxopts::value<bool>()->default_value("false"))
("time", "Optional timestamps to log at (e.g. `--time sim_time=1709203426`) (repeatable)", cxxopts::value<std::vector<std::string>>())
("sequence", "Optional sequences to log at (e.g. `--sequence sim_frame=42`) (repeatable)", cxxopts::value<std::vector<std::string>>())
;
// clang-format on

options.parse_positional({"filepath"});

auto args = options.parse(argc, argv);

if (args.count("help")) {
std::cout << options.help() << std::endl;
exit(0);
}

if (filepath.empty()) {
std::cerr << USAGE << std::endl;
return 1;
}
const auto filepath = args["filepath"].as<std::string>();

bool is_file = std::filesystem::is_regular_file(filepath);
bool is_cpp_file = std::filesystem::path(filepath).extension().string() == ".cpp";
Expand All @@ -75,12 +98,19 @@ int main(int argc, char* argv[]) {

std::string text = "## Some C++ code\n```cpp\n" + body.str() + "\n```\n";

auto recording_id = std::string_view();
if (args.count("recording-id")) {
recording_id = args["recording-id"].as<std::string>();
}
const auto rec = rerun::RecordingStream("rerun_example_external_data_loader", recording_id);
// The most important part of this: log to standard output so the Rerun Viewer can ingest it!
rec.to_stdout().exit_on_failure();

rec.log_timeless(
set_time_from_args(rec, args);

rec.log_with_timeless(
filepath,
args["timeless"].as<bool>(),
rerun::TextDocument(text).with_media_type(rerun::MediaType::markdown())
);
}
5 changes: 3 additions & 2 deletions examples/cpp/log_file/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ int main(int argc, char** argv) {
for (const auto& filepath : filepaths) {
if (!from_contents) {
// Either log the file using its path…
rec.log_file_from_path(filepath);
rec.log_file_from_path(filepath, "log_file_example");
} else {
// …or using its contents if you already have them loaded for some reason.
if (std::filesystem::is_regular_file(filepath)) {
Expand All @@ -70,7 +70,8 @@ int main(int argc, char** argv) {
rec.log_file_from_contents(
filepath,
reinterpret_cast<const std::byte*>(data.c_str()),
data.size()
data.size(),
entity_path_prefix = "log_file_example"
);
}
}
Expand Down
29 changes: 27 additions & 2 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.

20 changes: 18 additions & 2 deletions rerun_cpp/src/rerun/recording_stream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -257,14 +257,23 @@ namespace rerun {
return status;
}

Error RecordingStream::try_log_file_from_path(const std::filesystem::path& filepath) const {
Error RecordingStream::try_log_file_from_path(
const std::filesystem::path& filepath, std::string_view recording_id,
std::string_view entity_path_prefix, bool timeless
) const {
if (!is_enabled()) {
return Error::ok();
}

rr_data_loader_settings settings = {};
settings.recording_id = detail::to_rr_string(recording_id);
settings.entity_path_prefix = detail::to_rr_string(entity_path_prefix);
settings.timeless = timeless;

rr_error status = {};
rr_recording_stream_log_file_from_path(
_id,
settings,
detail::to_rr_string(filepath.string()),
&status
);
Expand All @@ -273,7 +282,8 @@ namespace rerun {
}

Error RecordingStream::try_log_file_from_contents(
const std::filesystem::path& filepath, const std::byte* contents, size_t contents_size
const std::filesystem::path& filepath, const std::byte* contents, size_t contents_size,
std::string_view recording_id, std::string_view entity_path_prefix, bool timeless
) const {
if (!is_enabled()) {
return Error::ok();
Expand All @@ -283,9 +293,15 @@ namespace rerun {
data.bytes = reinterpret_cast<const uint8_t*>(contents);
data.length = static_cast<uint32_t>(contents_size);

rr_data_loader_settings settings = {};
settings.recording_id = detail::to_rr_string(recording_id);
settings.entity_path_prefix = detail::to_rr_string(entity_path_prefix);
settings.timeless = timeless;

rr_error status = {};
rr_recording_stream_log_file_from_contents(
_id,
settings,
detail::to_rr_string(filepath.string()),
data,
&status
Expand Down

0 comments on commit 76d84d8

Please sign in to comment.