Rerun C++ SDK
Loading...
Searching...
No Matches
recording_stream.hpp
1#pragma once
2
3#include <chrono>
4#include <cstdint> // uint32_t etc.
5#include <filesystem>
6#include <limits>
7#include <optional>
8#include <string_view>
9#include <type_traits>
10#include <vector>
11
12#include "as_components.hpp"
13#include "component_column.hpp"
14#include "error.hpp"
15#include "log_sink.hpp"
16#include "spawn_options.hpp"
17#include "time_column.hpp"
18
19namespace rerun {
20 struct ComponentBatch;
21
22 enum class StoreKind {
23 Recording,
24 Blueprint,
25 };
26
27 /// What happens when a client connects to a gRPC server?
28 enum class PlaybackBehavior {
29 /// Start playing back all the old data first,
30 /// and only after start sending anything that happened since.
32
33 /// Prioritize the newest arriving messages,
34 /// replaying the history later, starting with the newest.
36 };
37
38 /// A `RecordingStream` handles everything related to logging data into Rerun.
39 ///
40 /// ## Multithreading and ordering
41 ///
42 /// A `RecordingStream` is thread-safe.
43 ///
44 /// Internally, all operations are linearized into a pipeline:
45 /// - All operations sent by a given thread will take effect in the same exact order as that
46 /// thread originally sent them in, from its point of view.
47 /// - There isn't any well defined global order across multiple threads.
48 ///
49 /// This means that e.g. flushing the pipeline (`flush_blocking`) guarantees that all
50 /// previous data sent by the calling thread has been recorded; no more, no less.
51 /// (e.g. it does not mean that all file caches are flushed)
52 ///
53 /// ## Shutdown
54 ///
55 /// The `RecordingStream` can only be shutdown by dropping all instances of it, at which point
56 /// it will automatically take care of flushing any pending data that might remain in the
57 /// pipeline.
58 ///
59 /// TODO(andreas): The only way of having two instances of a `RecordingStream` is currently to
60 /// set it as a the global.
61 ///
62 /// Shutting down cannot ever block.
63 ///
64 /// ## Logging
65 ///
66 /// Internally, the stream will automatically micro-batch multiple log calls to optimize
67 /// transport.
68 /// See [SDK Micro Batching](https://www.rerun.io/docs/reference/sdk/micro-batching) for
69 /// more information.
70 ///
71 /// The data will be timestamped automatically based on the `RecordingStream`'s
72 /// internal clock.
74 private:
75 // TODO(grtlr): Ideally we'd expose more of the `EntityPath` struct to the C++ world so
76 // that we don't have to hardcode this here.
77 static constexpr const char PROPERTIES_ENTITY_PATH[] = "__properties/";
78
79 public:
80 /// Creates a new recording stream to log to.
81 ///
82 /// \param app_id The user-chosen name of the application doing the logging.
83 /// \param recording_id The user-chosen name of the recording being logged to.
84 /// \param store_kind Whether to log to the recording store or the blueprint store.
86 std::string_view app_id, std::string_view recording_id = std::string_view(),
87 StoreKind store_kind = StoreKind::Recording
88 );
90
91 /// \private
93
94 // TODO(andreas): We could easily make the recording stream trivial to copy by bumping Rusts
95 // ref counter by adding a copy of the recording stream to the list of C recording streams.
96 // Doing it this way would likely yield the most consistent behavior when interacting with
97 // global streams (and especially when interacting with different languages in the same
98 // application).
99 /// \private
100 RecordingStream(const RecordingStream&) = delete;
101 /// \private
102 RecordingStream() = delete;
103
104 // -----------------------------------------------------------------------------------------
105 /// \name Properties
106 /// @{
107
108 /// Returns the store kind as passed during construction
109 StoreKind kind() const {
110 return _store_kind;
111 }
112
113 /// Returns whether the recording stream is enabled.
114 ///
115 /// All log functions early out if a recording stream is disabled.
116 /// Naturally, logging functions that take unserialized data will skip the serialization step as well.
117 bool is_enabled() const {
118 return _enabled;
119 }
120
121 /// @}
122
123 // -----------------------------------------------------------------------------------------
124 /// \name Controlling globally available instances of RecordingStream.
125 /// @{
126
127 /// Replaces the currently active recording for this stream's store kind in the global scope
128 /// with this one.
129 ///
130 /// Afterwards, destroying this recording stream will *not* change the global recording
131 /// stream, as it increases an internal ref-count.
132 void set_global() const;
133
134 /// Replaces the currently active recording for this stream's store kind in the thread-local
135 /// scope with this one
136 ///
137 /// Afterwards, destroying this recording stream will *not* change the thread local
138 /// recording stream, as it increases an internal ref-count.
139 void set_thread_local() const;
140
141 /// Retrieves the most appropriate globally available recording stream for the given kind.
142 ///
143 /// I.e. thread-local first, then global.
144 /// If neither was set, any operations on the returned stream will be no-ops.
145 static RecordingStream& current(StoreKind store_kind = StoreKind::Recording);
146
147 /// @}
148
149 // -----------------------------------------------------------------------------------------
150 /// \name Directing the recording stream.
151 /// \details Either of these needs to be called, otherwise the stream will buffer up indefinitely.
152 /// @{
153
154 /// Stream data to multiple sinks.
155 ///
156 /// See specific sink types for more information:
157 /// * `FileSink`
158 /// * `GrpcSink`
159 template <typename... Ts>
160 Error set_sinks(const Ts&... sinks) const {
161 LogSink out_sinks[] = {sinks...};
162 uint32_t num_sinks = sizeof...(Ts);
163 return try_set_sinks(out_sinks, num_sinks);
164 }
165
166 /// Connect to a remote Rerun Viewer on the given URL.
167 ///
168 /// Requires that you first start a Rerun Viewer by typing 'rerun' in a terminal.
169 ///
170 /// \param url The scheme must be one of `rerun://`, `rerun+http://`, or `rerun+https://`,
171 /// and the pathname must be `/proxy`. The default is `rerun+http://127.0.0.1:9876/proxy`.
172 ///
173 /// This function returns immediately.
174 Error connect_grpc(std::string_view url = "rerun+http://127.0.0.1:9876/proxy") const;
175
176 /// Swaps the underlying sink for a gRPC server sink pre-configured to listen on `rerun+http://{bind_ip}:{port}/proxy`.
177 ///
178 /// The gRPC server will buffer all log data in memory so that late connecting viewers will get all the data.
179 /// You can control the amount of data buffered by the gRPC server with the `server_memory_limit` argument.
180 /// Once reached, the earliest logged data will be dropped. Static data is never dropped.
181 ///
182 /// Returns the URI of the gRPC server so you can connect to it from a viewer.
183 ///
184 /// This function returns immediately.
186 std::string_view bind_ip = "0.0.0.0", uint16_t port = 9876,
187 std::string_view server_memory_limit = "1GiB",
189 std::vector<std::string> cors_allow_origins = {}
190 ) const;
191
192 /// Spawns a new Rerun Viewer process from an executable available in PATH, then connects to it
193 /// over gRPC.
194 ///
195 /// If a Rerun Viewer is already listening on this port, the stream will be redirected to
196 /// that viewer instead of starting a new one.
197 ///
198 /// \param options See `rerun::SpawnOptions` for more information.
199 Error spawn(const SpawnOptions& options = {}) const;
200
201 /// @see RecordingStream::spawn
202 template <typename TRep, typename TPeriod>
204 const SpawnOptions& options = {},
205 std::chrono::duration<TRep, TPeriod> flush_timeout = std::chrono::seconds(2)
206 ) const {
207 using seconds_float = std::chrono::duration<float>; // Default ratio is 1:1 == seconds.
208 return spawn(options, std::chrono::duration_cast<seconds_float>(flush_timeout).count());
209 }
210
211 /// Stream all log-data to a given `.rrd` file.
212 ///
213 /// The Rerun Viewer is able to read continuously from the resulting rrd file while it is being written.
214 /// However, depending on your OS and configuration, changes may not be immediately visible due to file caching.
215 /// This is a common issue on Windows and (to a lesser extent) on MacOS.
216 ///
217 /// This function returns immediately.
218 Error save(std::string_view path) const;
219
220 /// Stream all log-data to standard output.
221 ///
222 /// Pipe the result into the Rerun Viewer to visualize it.
223 ///
224 /// If there isn't any listener at the other end of the pipe, the `RecordingStream` will
225 /// default back to `buffered` mode, in order not to break the user's terminal.
226 ///
227 /// This function returns immediately.
228 //
229 // NOTE: This should be called `stdout` like in other SDK, but turns out that `stdout` is a
230 // macro when compiling with msvc [1].
231 // [1]: https://learn.microsoft.com/en-us/cpp/c-runtime-library/stdin-stdout-stderr?view=msvc-170
233
234 /// Initiates a flush the batching pipeline and waits for it to propagate.
235 ///
236 /// \param timeout_sec The minimum time the SDK will wait during a flush before potentially
237 /// dropping data if progress is not being made. If you pass in FLT_MAX or infinity,
238 /// the function will block until it either succeeds or fails.
239 ///
240 /// Returns an error if we fail to flush all previously sent log messages.
241 ///
242 /// See `RecordingStream` docs for ordering semantics and multithreading guarantees.
243 Error flush_blocking(float timeout_sec = std::numeric_limits<float>::infinity()) const;
244
245 /// @}
246
247 // -----------------------------------------------------------------------------------------
248 /// \name Controlling log time (index).
249 /// \details
250 /// @{
251
252 /// Set the index value of the given timeline as a sequence number, for the current calling thread.
253 ///
254 /// Used for all subsequent logging performed from this same thread, until the next call
255 /// to one of the time setting methods.
256 ///
257 /// For example: `rec.set_time_sequence("frame_nr", frame_nr)`.
258 ///
259 /// You can remove a timeline from subsequent log calls again using `rec.disable_timeline`.
260 /// @see set_time_sequence, set_time_duration, set_time_duration_secs, set_time_duration_nanos, set_time_timestamp, set_time_timestamp_secs_since_epoch, set_time_timestamp_nanos_since_epoch
261 void set_time_sequence(std::string_view timeline_name, int64_t sequence_nr) const;
262
263 /// Set the index value of the given timeline as a duration, for the current calling thread.
264 ///
265 /// Used for all subsequent logging performed from this same thread, until the next call
266 /// to one of the time setting methods.
267 ///
268 /// For example: `rec.set_time_duration("runtime", time_since_start)`.
269 ///
270 /// You can remove a timeline from subsequent log calls again using `rec.disable_timeline`.
271 /// @see set_time_sequence, set_time_duration, set_time_duration_secs, set_time_duration_nanos, set_time_timestamp, set_time_timestamp_secs_since_epoch, set_time_timestamp_nanos_since_epoch
272 template <typename TRep, typename TPeriod>
274 std::string_view timeline_name, std::chrono::duration<TRep, TPeriod> duration
275 ) const {
276 auto nanos = std::chrono::duration_cast<std::chrono::nanoseconds>(duration).count();
277 set_time_duration_nanos(timeline_name, nanos);
278 }
279
280 /// Set the index value of the given timeline as a duration in seconds, for the current calling thread.
281 ///
282 /// Used for all subsequent logging performed from this same thread, until the next call
283 /// to one of the time setting methods.
284 ///
285 /// For example: `rec.set_time_duration_secs("runtime", seconds_since_start)`.
286 ///
287 /// You can remove a timeline from subsequent log calls again using `rec.disable_timeline`.
288 /// @see set_time_sequence, set_time_duration, set_time_duration_secs, set_time_duration_nanos, set_time_timestamp, set_time_timestamp_secs_since_epoch, set_time_timestamp_nanos_since_epoch
289 void set_time_duration_secs(std::string_view timeline_name, double secs) const {
290 set_time_duration_nanos(timeline_name, static_cast<int64_t>(1e9 * secs + 0.5));
291 }
292
293 /// Set the index value of the given timeline as a duration in nanoseconds, for the current calling thread.
294 ///
295 /// Used for all subsequent logging performed from this same thread, until the next call
296 /// to one of the time setting methods.
297 ///
298 /// For example: `rec.set_time_duration_nanos("runtime", nanos_since_start)`.
299 ///
300 /// You can remove a timeline from subsequent log calls again using `rec.disable_timeline`.
301 /// @see set_time_sequence, set_time_duration, set_time_duration_secs, set_time_duration_nanos, set_time_timestamp, set_time_timestamp_secs_since_epoch, set_time_timestamp_nanos_since_epoch
302 void set_time_duration_nanos(std::string_view timeline_name, int64_t nanos) const;
303
304 /// Set the index value of the given timeline as a timestamp, for the current calling thread.
305 ///
306 /// Used for all subsequent logging performed from this same thread, until the next call
307 /// to one of the time setting methods.
308 ///
309 /// For example: `rec.set_time_timestamp("capture_time", now())`.
310 ///
311 /// You can remove a timeline from subsequent log calls again using `rec.disable_timeline`.
312 /// @see set_time_sequence, set_time_duration, set_time_duration_secs, set_time_duration_nanos, set_time_timestamp, set_time_timestamp_secs_since_epoch, set_time_timestamp_nanos_since_epoch
313 template <typename TClock>
315 std::string_view timeline_name, std::chrono::time_point<TClock> timestamp
316 ) const {
318 timeline_name,
319 std::chrono::duration_cast<std::chrono::nanoseconds>(timestamp.time_since_epoch())
320 .count()
321 );
322 }
323
324 /// Set the index value of the given timeline as seconds since Unix Epoch (1970), for the current calling thread.
325 ///
326 /// Used for all subsequent logging performed from this same thread, until the next call
327 /// to one of the time setting methods.
328 ///
329 /// For example: `rec.set_time_timestamp_secs_since_epoch("capture_time", secs_since_epoch())`.
330 ///
331 /// You can remove a timeline from subsequent log calls again using `rec.disable_timeline`.
332 /// @see set_time_sequence, set_time_duration, set_time_duration_secs, set_time_duration_nanos, set_time_timestamp, set_time_timestamp_secs_since_epoch, set_time_timestamp_nanos_since_epoch
333 void set_time_timestamp_secs_since_epoch(std::string_view timeline_name, double seconds)
334 const {
336 timeline_name,
337 static_cast<int64_t>(1e9 * seconds)
338 );
339 }
340
341 /// Set the index value of the given timeline as nanoseconds since Unix Epoch (1970), for the current calling thread.
342 ///
343 /// Used for all subsequent logging performed from this same thread, until the next call
344 /// to one of the time setting methods.
345 ///
346 /// For example: `rec.set_time_timestamp_nanos_since_epoch("capture_time", nanos_since_epoch())`.
347 ///
348 /// You can remove a timeline from subsequent log calls again using `rec.disable_timeline`.
349 /// @see set_time_sequence, set_time_duration, set_time_duration_secs, set_time_duration_nanos, set_time_timestamp, set_time_timestamp_secs_since_epoch, set_time_timestamp_nanos_since_epoch
350 void set_time_timestamp_nanos_since_epoch(std::string_view timeline_name, int64_t nanos)
351 const;
352
353 /// Set the current time of the recording, for the current calling thread.
354 ///
355 /// Used for all subsequent logging performed from this same thread, until the next call
356 /// to one of the time setting methods.
357 ///
358 /// For example: `rec.set_time("sim_time", sim_time_secs)`.
359 ///
360 /// You can remove a timeline from subsequent log calls again using `rec.disable_timeline`.
361 /// @see set_time_sequence, set_time_seconds, set_time_nanos, reset_time, disable_timeline
362 template <typename TClock>
363 [[deprecated("Renamed to `set_time_timestamp`")]] void set_time(
364 std::string_view timeline_name, std::chrono::time_point<TClock> time
365 ) const {
366 set_time(timeline_name, time.time_since_epoch());
367 }
368
369 /// Set the current time of the recording, for the current calling thread.
370 ///
371 /// Used for all subsequent logging performed from this same thread, until the next call
372 /// to one of the time setting methods.
373 ///
374 /// For example: `rec.set_time("sim_time", sim_time_secs)`.
375 ///
376 /// You can remove a timeline from subsequent log calls again using `rec.disable_timeline`.
377 /// @see set_time_sequence, set_time_seconds, set_time_nanos, reset_time, disable_timeline
378 template <typename TRep, typename TPeriod>
379 [[deprecated("Renamed `set_time_duration`")]] void set_time(
380 std::string_view timeline_name, std::chrono::duration<TRep, TPeriod> time
381 ) const {
382 set_time_duration(timeline_name, time);
383 }
384
385 /// Set the current time of the recording, for the current calling thread.
386 ///
387 /// Used for all subsequent logging performed from this same thread, until the next call
388 /// to one of the time setting methods.
389 ///
390 /// For example: `rec.set_time_seconds("sim_time", sim_time_secs)`.
391 ///
392 /// You can remove a timeline from subsequent log calls again using `rec.disable_timeline`.
393 /// @see set_time_sequence, set_time_nanos, reset_time, set_time, disable_timeline
394 [[deprecated("Use either `set_time_duration_secs` or `set_time_timestamp_secs_since_epoch`"
395 )]] void
396 set_time_seconds(std::string_view timeline_name, double seconds) const {
397 set_time_duration_secs(timeline_name, seconds);
398 }
399
400 /// Set the current time of the recording, for the current calling thread.
401 ///
402 /// Used for all subsequent logging performed from this same thread, until the next call
403 /// to one of the time setting methods.
404 ///
405 /// For example: `rec.set_time_nanos("sim_time", sim_time_nanos)`.
406 ///
407 /// You can remove a timeline from subsequent log calls again using `rec.disable_timeline`.
408 /// @see set_time_sequence, set_time_seconds, reset_time, set_time, disable_timeline
409 [[deprecated(
410 "Use either `set_time_duration_nanos` or `set_time_timestamp_nanos_since_epoch`"
411 )]] void
412 set_time_nanos(std::string_view timeline_name, int64_t nanos) const {
413 set_time_duration_nanos(timeline_name, nanos);
414 }
415
416 /// Stops logging to the specified timeline for subsequent log calls.
417 ///
418 /// The timeline is still there, but will not be updated with any new data.
419 ///
420 /// No-op if the timeline doesn't exist.
421 ///
422 /// @see set_time_sequence, set_time_seconds, set_time, reset_time
423 void disable_timeline(std::string_view timeline_name) const;
424
425 /// Clears out the current time of the recording, for the current calling thread.
426 ///
427 /// Used for all subsequent logging performed from this same thread, until the next call
428 /// to one of the time setting methods.
429 ///
430 /// For example: `rec.reset_time()`.
431 /// @see set_time_sequence, set_time_seconds, set_time_nanos, disable_timeline
432 void reset_time() const;
433
434 /// Enable or disable automatic injection of the `log_tick` timeline into logged data.
435 ///
436 /// `log_tick` is a per-recording counter that increments on every logging call.
437 /// It is **disabled** by default (it can also be controlled via the `RERUN_LOG_TICK`
438 /// environment variable).
439 ///
440 /// @see set_log_time_enabled
441 void set_log_tick_enabled(bool enabled) const;
442
443 /// Enable or disable automatic injection of the `log_time` timeline into logged data.
444 ///
445 /// `log_time` is the wall-clock time at which data was logged.
446 /// It is **enabled** by default (it can also be controlled via the `RERUN_LOG_TIME`
447 /// environment variable).
448 ///
449 /// @see set_log_tick_enabled
450 void set_log_time_enabled(bool enabled) const;
451
452 /// @}
453
454 // -----------------------------------------------------------------------------------------
455 /// \name Sending & logging data.
456 /// @{
457
458 /// Logs one or more archetype and/or component batches.
459 ///
460 /// This is the main entry point for logging data to rerun. It can be used to log anything
461 /// that implements the `AsComponents<T>` trait.
462 ///
463 /// When logging data, you must always provide an [entity_path](https://www.rerun.io/docs/concepts/logging-and-ingestion/entity-path)
464 /// for identifying the data. Note that paths prefixed with "__" are considered reserved for use by the Rerun SDK
465 /// itself and should not be used for logging user data. This is where Rerun will log additional information
466 /// such as properties and warnings.
467 ///
468 /// The most common way to log is with one of the rerun archetypes, all of which implement the `AsComponents` trait.
469 ///
470 /// For example, to log two 3D points:
471 /// ```
472 /// rec.log("my/point", rerun::Points3D({{0.0f, 0.0f, 0.0f}, {1.0f, 1.0f, 1.0f}}));
473 /// ```
474 ///
475 /// The `log` function can flexibly accept an arbitrary number of additional objects which will
476 /// be merged into the first entity, for instance:
477 /// ```
478 /// // Log three points with arrows sticking out of them:
479 /// rec.log(
480 /// "my/points",
481 /// rerun::Points3D({{0.2f, 0.5f, 0.3f}, {0.9f, 1.2f, 0.1f}, {1.0f, 4.2f, 0.3f}})
482 /// .with_radii({0.1, 0.2, 0.3}),
483 /// rerun::Arrows3D::from_vectors({{0.3f, 2.1f, 0.2f}, {0.9f, -1.1, 2.3f}, {-0.4f, 0.5f, 2.9f}})
484 /// );
485 /// ```
486 ///
487 /// Any failures that may are handled with `Error::handle`.
488 ///
489 /// \param entity_path Path to the entity in the space hierarchy.
490 /// \param as_components Any type for which the `AsComponents<T>` trait is implemented.
491 /// This is the case for any archetype as well as individual or collection of `ComponentBatch`.
492 /// You can implement `AsComponents` for your own types as well
493 ///
494 /// @see try_log, log_static, try_log_with_static
495 template <typename... Ts>
496 void log(std::string_view entity_path, const Ts&... as_components) const {
497 if (!is_enabled()) {
498 return;
499 }
500 try_log_with_static(entity_path, false, as_components...).handle();
501 }
502
503 /// Logs one or more archetype and/or component batches as static data.
504 ///
505 /// Like `log` but logs the data as static:
506 /// Static data has no time associated with it, exists on all timelines, and unconditionally shadows
507 /// any temporal data of the same type.
508 ///
509 /// Failures are handled with `Error::handle`.
510 ///
511 /// \param entity_path Path to the entity in the space hierarchy.
512 /// \param as_components Any type for which the `AsComponents<T>` trait is implemented.
513 /// This is the case for any archetype as well as individual or collection of `ComponentBatch`.
514 /// You can implement `AsComponents` for your own types as well
515 ///
516 /// @see log, try_log_static, try_log_with_static
517 template <typename... Ts>
518 void log_static(std::string_view entity_path, const Ts&... as_components) const {
519 if (!is_enabled()) {
520 return;
521 }
522 try_log_with_static(entity_path, true, as_components...).handle();
523 }
524
525 /// Logs one or more archetype and/or component batches.
526 ///
527 /// See `log` for more information.
528 /// Unlike `log` this method returns an error if an error occurs.
529 ///
530 /// \param entity_path Path to the entity in the space hierarchy.
531 /// \param as_components Any type for which the `AsComponents<T>` trait is implemented.
532 /// This is the case for any archetype as well as individual or collection of `ComponentBatch`.
533 /// You can implement `AsComponents` for your own types as well
534 ///
535 /// @see log, try_log_static, try_log_with_static
536 template <typename... Ts>
537 Error try_log(std::string_view entity_path, const Ts&... as_components) const {
538 if (!is_enabled()) {
539 return Error::ok();
540 }
541 return try_log_with_static(entity_path, false, as_components...);
542 }
543
544 /// Logs one or more archetype and/or component batches as static data, returning an error.
545 ///
546 /// See `log`/`log_static` for more information.
547 /// Unlike `log_static` this method returns if an error occurs.
548 ///
549 /// \param entity_path Path to the entity in the space hierarchy.
550 /// \param as_components Any type for which the `AsComponents<T>` trait is implemented.
551 /// This is the case for any archetype as well as individual or collection of `ComponentBatch`.
552 /// You can implement `AsComponents` for your own types as well
553 /// \returns An error if an error occurs during evaluation of `AsComponents` or logging.
554 ///
555 /// @see log_static, try_log, try_log_with_static
556 template <typename... Ts>
557 Error try_log_static(std::string_view entity_path, const Ts&... as_components) const {
558 if (!is_enabled()) {
559 return Error::ok();
560 }
561 return try_log_with_static(entity_path, true, as_components...);
562 }
563
564 /// Logs one or more archetype and/or component batches optionally static, returning an error.
565 ///
566 /// See `log`/`log_static` for more information.
567 /// Returns an error if an error occurs during evaluation of `AsComponents` or logging.
568 ///
569 /// \param entity_path Path to the entity in the space hierarchy.
570 /// \param static_ If true, the logged components will be static.
571 /// Static data has no time associated with it, exists on all timelines, and unconditionally shadows
572 /// any temporal data of the same type.
573 /// Otherwise, the data will be timestamped automatically with `log_time` (and `log_tick`, if enabled).
574 /// Additional timelines set by `set_time_sequence` or `set_time` will also be included.
575 /// \param as_components Any type for which the `AsComponents<T>` trait is implemented.
576 /// This is the case for any archetype as well as individual or collection of `ComponentBatch`.
577 /// You can implement `AsComponents` for your own types as well
578 ///
579 /// @see log, try_log, log_static, try_log_static
580 template <typename... Ts>
581 void log_with_static(std::string_view entity_path, bool static_, const Ts&... as_components)
582 const {
583 try_log_with_static(entity_path, static_, as_components...).handle();
584 }
585
586 /// Logs one or more archetype and/or component batches optionally static, returning an error.
587 ///
588 /// See `log`/`log_static` for more information.
589 /// Returns an error if an error occurs during evaluation of `AsComponents` or logging.
590 ///
591 /// \param entity_path Path to the entity in the space hierarchy.
592 /// \param static_ If true, the logged components will be static.
593 /// Static data has no time associated with it, exists on all timelines, and unconditionally shadows
594 /// any temporal data of the same type.
595 /// Otherwise, the data will be timestamped automatically with `log_time` (and `log_tick`, if enabled).
596 /// Additional timelines set by `set_time_sequence` or `set_time` will also be included.
597 /// \param as_components Any type for which the `AsComponents<T>` trait is implemented.
598 /// This is the case for any archetype as well as individual or collection of `ComponentBatch`.
599 /// You can implement `AsComponents` for your own types as well
600 /// \returns An error if an error occurs during evaluation of `AsComponents` or logging.
601 ///
602 /// @see log, try_log, log_static, try_log_static
603 template <typename... Ts>
605 std::string_view entity_path, bool static_, const Ts&... as_components
606 ) const {
607 if (!is_enabled()) {
608 return Error::ok();
609 }
610 std::vector<ComponentBatch> serialized_columns;
611 Error err;
612 (
613 [&] {
614 if (err.is_err()) {
615 return;
616 }
617
618 const Result<Collection<ComponentBatch>> serialization_result =
619 AsComponents<Ts>().as_batches(as_components);
620 if (serialization_result.is_err()) {
621 err = serialization_result.error;
622 return;
623 }
624
625 if (serialized_columns.empty()) {
626 // Fast path for the first batch (which is usually the only one!)
627 serialized_columns = std::move(serialization_result.value).to_vector();
628 } else {
629 serialized_columns.insert(
630 serialized_columns.end(),
631 std::make_move_iterator(serialization_result.value.begin()),
632 std::make_move_iterator(serialization_result.value.end())
633 );
634 }
635 }(),
636 ...
637 );
638 RR_RETURN_NOT_OK(err);
639
640 return try_log_serialized_batches(entity_path, static_, std::move(serialized_columns));
641 }
642
643 /// Logs several serialized batches batches, returning an error on failure.
644 ///
645 /// This is a more low-level API than `log`/`log_static\ and requires you to already serialize the data
646 /// ahead of time.
647 ///
648 /// \param entity_path Path to the entity in the space hierarchy.
649 /// \param static_ If true, the logged components will be static.
650 /// Static data has no time associated with it, exists on all timelines, and unconditionally shadows
651 /// any temporal data of the same type.
652 /// Otherwise, the data will be timestamped automatically with `log_time` (and `log_tick`, if enabled).
653 /// Additional timelines set by `set_time_sequence` or `set_time` will also be included.
654 /// \param batches The serialized batches to log.
655 ///
656 /// \see `log`, `try_log`, `log_static`, `try_log_static`, `try_log_with_static`
658 std::string_view entity_path, bool static_, std::vector<ComponentBatch> batches
659 ) const;
660
661 /// Bottom level API that logs raw data cells to the recording stream.
662 ///
663 /// In order to use this you need to pass serialized Arrow data cells.
664 ///
665 /// \param entity_path Path to the entity in the space hierarchy.
666 /// \param num_data_cells Number of data cells passed in.
667 /// \param data_cells The data cells to log.
668 /// \param inject_time
669 /// If set to `true`, the row's timestamp data will be overridden using the recording
670 /// streams internal clock.
671 ///
672 /// \see `try_log_serialized_batches`
674 std::string_view entity_path, size_t num_data_cells, const ComponentBatch* data_cells,
675 bool inject_time
676 ) const;
677
678 /// Logs the file at the given `path` using all `Importer`s available.
679 ///
680 /// A single `path` might be handled by more than one importer.
681 ///
682 /// This method blocks until either at least one `Importer` starts streaming data in
683 /// or all of them fail.
684 ///
685 /// See <https://www.rerun.io/docs/concepts/logging-and-ingestion/importers/overview> for more information.
686 ///
687 /// \param filepath Path to the file to be logged.
688 /// \param entity_path_prefix What should the logged entity paths be prefixed with?
689 /// \param static_ If true, the logged components will be static.
690 /// Static data has no time associated with it, exists on all timelines, and unconditionally shadows
691 /// any temporal data of the same type.
692 /// Otherwise, the data will be timestamped automatically with `log_time` (and `log_tick`, if enabled).
693 /// Additional timelines set by `set_time_sequence` or `set_time` will also be included.
694 ///
695 /// \see `try_log_file_from_path`
697 const std::filesystem::path& filepath,
698 std::string_view entity_path_prefix = std::string_view(), bool static_ = false
699 ) const {
700 try_log_file_from_path(filepath, entity_path_prefix, static_).handle();
701 }
702
703 /// Logs the file at the given `path` using all `Importer`s available.
704 ///
705 /// A single `path` might be handled by more than one importer.
706 ///
707 /// This method blocks until either at least one `Importer` starts streaming data in
708 /// or all of them fail.
709 ///
710 /// See <https://www.rerun.io/docs/concepts/logging-and-ingestion/importers/overview> for more information.
711 ///
712 /// \param filepath Path to the file to be logged.
713 /// \param entity_path_prefix What should the logged entity paths be prefixed with?
714 /// \param static_ If true, the logged components will be static.
715 /// Static data has no time associated with it, exists on all timelines, and unconditionally shadows
716 /// any temporal data of the same type.
717 /// Otherwise, the data will be timestamped automatically with `log_time` (and `log_tick`, if enabled).
718 /// Additional timelines set by `set_time_sequence` or `set_time` will also be included.
719 ///
720 /// \see `log_file_from_path`
722 const std::filesystem::path& filepath,
723 std::string_view entity_path_prefix = std::string_view(), bool static_ = false
724 ) const;
725
726 /// Logs the given `contents` using all `Importer`s available.
727 ///
728 /// A single `path` might be handled by more than one importer.
729 ///
730 /// This method blocks until either at least one `Importer` starts streaming data in
731 /// or all of them fail.
732 ///
733 /// See <https://www.rerun.io/docs/concepts/logging-and-ingestion/importers/overview> for more information.
734 ///
735 /// \param filepath Path to the file that the `contents` belong to.
736 /// \param contents Contents to be logged.
737 /// \param contents_size Size in bytes of the `contents`.
738 /// \param entity_path_prefix What should the logged entity paths be prefixed with?
739 /// \param static_ If true, the logged components will be static.
740 /// Static data has no time associated with it, exists on all timelines, and unconditionally shadows
741 /// any temporal data of the same type.
742 /// Otherwise, the data will be timestamped automatically with `log_time` (and `log_tick`, if enabled).
743 /// Additional timelines set by `set_time_sequence` or `set_time` will also be included.
744 ///
745 /// \see `try_log_file_from_contents`
747 const std::filesystem::path& filepath, const std::byte* contents, size_t contents_size,
748 std::string_view entity_path_prefix = std::string_view(), bool static_ = false
749 ) const {
751 filepath,
752 contents,
753 contents_size,
754 entity_path_prefix,
755 static_
756 )
757 .handle();
758 }
759
760 /// Logs the given `contents` using all `Importer`s available.
761 ///
762 /// A single `path` might be handled by more than one importer.
763 ///
764 /// This method blocks until either at least one `Importer` starts streaming data in
765 /// or all of them fail.
766 ///
767 /// See <https://www.rerun.io/docs/concepts/logging-and-ingestion/importers/overview> for more information.
768 ///
769 /// \param filepath Path to the file that the `contents` belong to.
770 /// \param contents Contents to be logged.
771 /// \param contents_size Size in bytes of the `contents`.
772 /// \param entity_path_prefix What should the logged entity paths be prefixed with?
773 /// \param static_ If true, the logged components will be static.
774 /// Static data has no time associated with it, exists on all timelines, and unconditionally shadows
775 /// any temporal data of the same type.
776 /// Otherwise, the data will be timestamped automatically with `log_time` (and `log_tick`, if enabled).
777 /// Additional timelines set by `set_time_sequence` or `set_time` will also be included.
778 ///
779 /// \see `log_file_from_contents`
781 const std::filesystem::path& filepath, const std::byte* contents, size_t contents_size,
782 std::string_view entity_path_prefix = std::string_view(), bool static_ = false
783 ) const;
784
785 /// Directly log a columns of data to Rerun.
786 ///
787 /// This variant takes in arbitrary amount of `ComponentColumn`s and `ComponentColumn` collections.
788 ///
789 /// Unlike the regular `log` API, which is row-oriented, this API lets you submit the data
790 /// in a columnar form. Each `TimeColumn` and `ComponentColumn` represents a column of data that will be sent to Rerun.
791 /// The lengths of all of these columns must match, and all
792 /// data that shares the same index across the different columns will act as a single logical row,
793 /// equivalent to a single call to `RecordingStream::log`.
794 ///
795 /// Note that this API ignores any stateful time set on the log stream via the `RecordingStream::set_time_*` APIs.
796 /// Furthermore, this will _not_ inject the default timelines `log_tick` and `log_time` timeline columns.
797 ///
798 /// Any failures that may occur during serialization are handled with `Error::handle`.
799 ///
800 /// \param entity_path Path to the entity in the space hierarchy.
801 /// \param time_columns The time columns to send.
802 /// \param component_columns The columns of components to send. Both individual `ComponentColumn`s and `Collection<ComponentColumn>`s are accepted.
803 /// \see `try_send_columns`
804 template <typename... Ts>
806 std::string_view entity_path, Collection<TimeColumn> time_columns,
807 Ts... component_columns // NOLINT
808 ) const {
809 try_send_columns(entity_path, time_columns, component_columns...).handle();
810 }
811
812 /// Directly log a columns of data to Rerun.
813 ///
814 /// This variant takes in arbitrary amount of `ComponentColumn`s and `ComponentColumn` collections.
815 ///
816 /// Unlike the regular `log` API, which is row-oriented, this API lets you submit the data
817 /// in a columnar form. Each `TimeColumn` and `ComponentColumn` represents a column of data that will be sent to Rerun.
818 /// The lengths of all of these columns must match, and all
819 /// data that shares the same index across the different columns will act as a single logical row,
820 /// equivalent to a single call to `RecordingStream::log`.
821 ///
822 /// Note that this API ignores any stateful time set on the log stream via the `RecordingStream::set_time_*` APIs.
823 /// Furthermore, this will _not_ inject the default timelines `log_tick` and `log_time` timeline columns.
824 ///
825 /// \param entity_path Path to the entity in the space hierarchy.
826 /// \param time_columns The time columns to send.
827 /// \param component_columns The columns of components to send. Both individual `ComponentColumn`s and `Collection<ComponentColumn>`s are accepted.
828 /// \see `send_columns`
829 template <typename... Ts>
831 std::string_view entity_path, Collection<TimeColumn> time_columns,
832 Ts... component_columns // NOLINT
833 ) const {
834 if constexpr (sizeof...(Ts) == 1) {
835 // Directly forward if this is only a single element,
836 // skipping collection of component column vector.
837 return try_send_columns(
838 entity_path,
839 std::move(time_columns),
840 Collection(std::forward<Ts...>(component_columns...))
841 );
842 }
843
844 std::vector<ComponentColumn> flat_column_list;
845 (
846 [&] {
847 static_assert(
848 std::is_same_v<std::remove_cv_t<Ts>, ComponentColumn> ||
849 std::is_constructible_v<Collection<ComponentColumn>, Ts>,
850 "Ts must be ComponentColumn or a collection thereof"
851 );
852
853 push_back_columns(flat_column_list, std::move(component_columns));
854 }(),
855 ...
856 );
857 return try_send_columns(
858 entity_path,
859 std::move(time_columns),
860 // Need to create collection explicitly, otherwise this becomes a recursive call.
861 Collection<ComponentColumn>(std::move(flat_column_list))
862 );
863 }
864
865 /// Directly log a columns of data to Rerun.
866 ///
867 /// Unlike the regular `log` API, which is row-oriented, this API lets you submit the data
868 /// in a columnar form. Each `TimeColumn` and `ComponentColumn` represents a column of data that will be sent to Rerun.
869 /// The lengths of all of these columns must match, and all
870 /// data that shares the same index across the different columns will act as a single logical row,
871 /// equivalent to a single call to `RecordingStream::log`.
872 ///
873 /// Note that this API ignores any stateful time set on the log stream via the `RecordingStream::set_time_*` APIs.
874 /// Furthermore, this will _not_ inject the default timelines `log_tick` and `log_time` timeline columns.
875 ///
876 /// Any failures that may occur during serialization are handled with `Error::handle`.
877 ///
878 /// \param entity_path Path to the entity in the space hierarchy.
879 /// \param time_columns The time columns to send.
880 /// \param component_columns The columns of components to send.
881 /// \see `try_send_columns`
883 std::string_view entity_path, Collection<TimeColumn> time_columns,
884 Collection<ComponentColumn> component_columns
885 ) const {
886 try_send_columns(entity_path, time_columns, component_columns).handle();
887 }
888
889 /// Directly log a columns of data to Rerun.
890 ///
891 /// Unlike the regular `log` API, which is row-oriented, this API lets you submit the data
892 /// in a columnar form. Each `TimeColumn` and `ComponentColumn` represents a column of data that will be sent to Rerun.
893 /// The lengths of all of these columns must match, and all
894 /// data that shares the same index across the different columns will act as a single logical row,
895 /// equivalent to a single call to `RecordingStream::log`.
896 ///
897 /// Note that this API ignores any stateful time set on the log stream via the `RecordingStream::set_time_*` APIs.
898 /// Furthermore, this will _not_ inject the default timelines `log_tick` and `log_time` timeline columns.
899 ///
900 /// \param entity_path Path to the entity in the space hierarchy.
901 /// \param time_columns The time columns to send.
902 /// \param component_columns The columns of components to send.
903 /// \see `send_columns`
905 std::string_view entity_path, Collection<TimeColumn> time_columns,
906 Collection<ComponentColumn> component_columns
907 ) const;
908
909 /// Set a property of a recording.
910 ///
911 /// Any failures that may occur during serialization are handled with `Error::handle`.
912 ///
913 /// \param name The name of the property.
914 /// \param values The values of the property.
915 /// \see `try_send_property`
916 template <typename... Ts>
917 void send_property(std::string_view name, const Ts&... values) const {
918 try_send_property(name, values...).handle();
919 }
920
921 /// Set a property of a recording.
922 ///
923 /// Any failures that may occur during serialization are handled with `Error::handle`.
924 ///
925 /// \param name The name of the property.
926 /// \param values The values of the property.
927 /// \see `set_property`
928 template <typename... Ts>
929 Error try_send_property(std::string_view name, const Ts&... values) const {
930 return try_log_static(
931 this->PROPERTIES_ENTITY_PATH + std::string(name),
932 values... // NOLINT
933 );
934 }
935
936 /// Set the name of a recording.
937 ///
938 /// Any failures that may occur during serialization are handled with `Error::handle`.
939 ///
940 /// \param name The name of the recording.
941 /// \see `try_send_recording_name`
942 void send_recording_name(std::string_view name) const {
944 }
945
946 /// Set the name of a recording.
947 ///
948 /// \param name The name of the recording.
949 /// \see `send_recording_name`
950 Error try_send_recording_name(std::string_view name) const;
951
952 /// Set the start time of a recording.
953 ///
954 /// Any failures that may occur during serialization are handled with `Error::handle`.
955 ///
956 /// \param nanos The timestamp of the recording in nanoseconds since Unix epoch.
957 /// \see `try_send_recording_start_time`
958 void send_recording_start_time_nanos(int64_t nanos) const {
960 }
961
962 /// Set the start time of a recording.
963 ///
964 /// \param nanos The timestamp of the recording in nanoseconds since Unix epoch.
965 /// \see `set_name`
967
968 /// @}
969
970 private:
971 Error try_set_sinks(const LogSink* sinks, uint32_t num_sinks) const;
972
973 // Utility function to implement `try_send_columns` variadic template.
974 static void push_back_columns(
975 std::vector<ComponentColumn>& component_columns, Collection<ComponentColumn> new_columns
976 ) {
977 for (const auto& new_column : new_columns) {
978 component_columns.emplace_back(std::move(new_column));
979 }
980 }
981
982 static void push_back_columns(
983 std::vector<ComponentColumn>& component_columns, ComponentColumn new_column
984 ) {
985 component_columns.emplace_back(std::move(new_column));
986 }
987
988 RecordingStream(uint32_t id, StoreKind store_kind);
989
990 uint32_t _id;
991 StoreKind _store_kind;
992 bool _enabled;
993 };
994} // namespace rerun
Generic collection of elements that are roughly contiguous in memory.
Definition collection.hpp:49
Status outcome object (success or error) returned for fallible operations.
Definition error.hpp:103
void handle() const
Handle this error based on the set log handler.
bool is_err() const
Returns true if the code is not Ok.
Definition error.hpp:139
static Error ok()
Creates a new error set to ok.
Definition error.hpp:124
A RecordingStream handles everything related to logging data into Rerun.
Definition recording_stream.hpp:73
Error try_log_with_static(std::string_view entity_path, bool static_, const Ts &... as_components) const
Logs one or more archetype and/or component batches optionally static, returning an error.
Definition recording_stream.hpp:604
Error try_send_property(std::string_view name, const Ts &... values) const
Set a property of a recording.
Definition recording_stream.hpp:929
void set_log_time_enabled(bool enabled) const
Enable or disable automatic injection of the log_time timeline into logged data.
Error try_send_columns(std::string_view entity_path, Collection< TimeColumn > time_columns, Collection< ComponentColumn > component_columns) const
Directly log a columns of data to Rerun.
void log_file_from_path(const std::filesystem::path &filepath, std::string_view entity_path_prefix=std::string_view(), bool static_=false) const
Logs the file at the given path using all Importers available.
Definition recording_stream.hpp:696
bool is_enabled() const
Returns whether the recording stream is enabled.
Definition recording_stream.hpp:117
void set_time_duration_nanos(std::string_view timeline_name, int64_t nanos) const
Set the index value of the given timeline as a duration in nanoseconds, for the current calling threa...
void send_property(std::string_view name, const Ts &... values) const
Set a property of a recording.
Definition recording_stream.hpp:917
Error try_send_recording_start_time_nanos(int64_t nanos) const
Set the start time of a recording.
Error try_log(std::string_view entity_path, const Ts &... as_components) const
Logs one or more archetype and/or component batches.
Definition recording_stream.hpp:537
void disable_timeline(std::string_view timeline_name) const
Stops logging to the specified timeline for subsequent log calls.
void reset_time() const
Clears out the current time of the recording, for the current calling thread.
Error to_stdout() const
Stream all log-data to standard output.
void send_columns(std::string_view entity_path, Collection< TimeColumn > time_columns, Collection< ComponentColumn > component_columns) const
Directly log a columns of data to Rerun.
Definition recording_stream.hpp:882
Error try_log_file_from_path(const std::filesystem::path &filepath, std::string_view entity_path_prefix=std::string_view(), bool static_=false) const
Logs the file at the given path using all Importers available.
Error save(std::string_view path) const
Stream all log-data to a given .rrd file.
Error try_log_static(std::string_view entity_path, const Ts &... as_components) const
Logs one or more archetype and/or component batches as static data, returning an error.
Definition recording_stream.hpp:557
StoreKind kind() const
Returns the store kind as passed during construction.
Definition recording_stream.hpp:109
Error flush_blocking(float timeout_sec=std::numeric_limits< float >::infinity()) const
Initiates a flush the batching pipeline and waits for it to propagate.
Error spawn(const SpawnOptions &options={}, std::chrono::duration< TRep, TPeriod > flush_timeout=std::chrono::seconds(2)) const
Definition recording_stream.hpp:203
Error try_log_data_row(std::string_view entity_path, size_t num_data_cells, const ComponentBatch *data_cells, bool inject_time) const
Bottom level API that logs raw data cells to the recording stream.
void log_file_from_contents(const std::filesystem::path &filepath, const std::byte *contents, size_t contents_size, std::string_view entity_path_prefix=std::string_view(), bool static_=false) const
Logs the given contents using all Importers available.
Definition recording_stream.hpp:746
void set_time_timestamp_secs_since_epoch(std::string_view timeline_name, double seconds) const
Set the index value of the given timeline as seconds since Unix Epoch (1970), for the current calling...
Definition recording_stream.hpp:333
void set_time_duration_secs(std::string_view timeline_name, double secs) const
Set the index value of the given timeline as a duration in seconds, for the current calling thread.
Definition recording_stream.hpp:289
void set_time_duration(std::string_view timeline_name, std::chrono::duration< TRep, TPeriod > duration) const
Set the index value of the given timeline as a duration, for the current calling thread.
Definition recording_stream.hpp:273
Error set_sinks(const Ts &... sinks) const
Stream data to multiple sinks.
Definition recording_stream.hpp:160
void set_time_nanos(std::string_view timeline_name, int64_t nanos) const
Set the current time of the recording, for the current calling thread.
Definition recording_stream.hpp:412
void set_time(std::string_view timeline_name, std::chrono::duration< TRep, TPeriod > time) const
Set the current time of the recording, for the current calling thread.
Definition recording_stream.hpp:379
Result< std::string > serve_grpc(std::string_view bind_ip="0.0.0.0", uint16_t port=9876, std::string_view server_memory_limit="1GiB", PlaybackBehavior playback_behavior=PlaybackBehavior::OldestFirst, std::vector< std::string > cors_allow_origins={}) const
Swaps the underlying sink for a gRPC server sink pre-configured to listen on rerun+http://{bind_ip}:{...
void send_recording_start_time_nanos(int64_t nanos) const
Set the start time of a recording.
Definition recording_stream.hpp:958
void log_with_static(std::string_view entity_path, bool static_, const Ts &... as_components) const
Logs one or more archetype and/or component batches optionally static, returning an error.
Definition recording_stream.hpp:581
static RecordingStream & current(StoreKind store_kind=StoreKind::Recording)
Retrieves the most appropriate globally available recording stream for the given kind.
RecordingStream(std::string_view app_id, std::string_view recording_id=std::string_view(), StoreKind store_kind=StoreKind::Recording)
Creates a new recording stream to log to.
void log(std::string_view entity_path, const Ts &... as_components) const
Logs one or more archetype and/or component batches.
Definition recording_stream.hpp:496
void set_thread_local() const
Replaces the currently active recording for this stream's store kind in the thread-local scope with t...
Error try_send_recording_name(std::string_view name) const
Set the name of a recording.
Error try_log_serialized_batches(std::string_view entity_path, bool static_, std::vector< ComponentBatch > batches) const
Logs several serialized batches batches, returning an error on failure.
Error connect_grpc(std::string_view url="rerun+http://127.0.0.1:9876/proxy") const
Connect to a remote Rerun Viewer on the given URL.
void set_time(std::string_view timeline_name, std::chrono::time_point< TClock > time) const
Set the current time of the recording, for the current calling thread.
Definition recording_stream.hpp:363
Error spawn(const SpawnOptions &options={}) const
Spawns a new Rerun Viewer process from an executable available in PATH, then connects to it over gRPC...
void set_time_seconds(std::string_view timeline_name, double seconds) const
Set the current time of the recording, for the current calling thread.
Definition recording_stream.hpp:396
void set_time_timestamp_nanos_since_epoch(std::string_view timeline_name, int64_t nanos) const
Set the index value of the given timeline as nanoseconds since Unix Epoch (1970), for the current cal...
void send_columns(std::string_view entity_path, Collection< TimeColumn > time_columns, Ts... component_columns) const
Directly log a columns of data to Rerun.
Definition recording_stream.hpp:805
Error try_log_file_from_contents(const std::filesystem::path &filepath, const std::byte *contents, size_t contents_size, std::string_view entity_path_prefix=std::string_view(), bool static_=false) const
Logs the given contents using all Importers available.
void send_recording_name(std::string_view name) const
Set the name of a recording.
Definition recording_stream.hpp:942
void set_global() const
Replaces the currently active recording for this stream's store kind in the global scope with this on...
void set_log_tick_enabled(bool enabled) const
Enable or disable automatic injection of the log_tick timeline into logged data.
void set_time_timestamp(std::string_view timeline_name, std::chrono::time_point< TClock > timestamp) const
Set the index value of the given timeline as a timestamp, for the current calling thread.
Definition recording_stream.hpp:314
void set_time_sequence(std::string_view timeline_name, int64_t sequence_nr) const
Set the index value of the given timeline as a sequence number, for the current calling thread.
Error try_send_columns(std::string_view entity_path, Collection< TimeColumn > time_columns, Ts... component_columns) const
Directly log a columns of data to Rerun.
Definition recording_stream.hpp:830
void log_static(std::string_view entity_path, const Ts &... as_components) const
Logs one or more archetype and/or component batches as static data.
Definition recording_stream.hpp:518
A class for representing either a usable value, or an error.
Definition result.hpp:14
bool is_err() const
Returns true if error is not set to rerun::ErrorCode::Ok, implying that no value is contained,...
Definition result.hpp:44
All Rerun C++ types and functions are in the rerun namespace or one of its nested namespaces.
Definition rerun.hpp:23
PlaybackBehavior
What happens when a client connects to a gRPC server?
Definition recording_stream.hpp:28
@ OldestFirst
Start playing back all the old data first, and only after start sending anything that happened since.
@ NewestFirst
Prioritize the newest arriving messages, replaying the history later, starting with the newest.
Arrow-encoded data of a single batch of components together with a component descriptor.
Definition component_batch.hpp:28
Arrow-encoded data of a column of components.
Definition component_column.hpp:20
A sink for log messages.
Definition log_sink.hpp:38
Options to control the behavior of spawn.
Definition spawn_options.hpp:17