-
Notifications
You must be signed in to change notification settings - Fork 373
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
C++ & Python API: add helpers for constructing an entity path #4595
Changes from all commits
1ca6636
1efc0f4
ef73085
bb67c24
38535a3
b14f7d2
e519509
2fd7fcb
2e02799
a5103b6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
// Log a `TextDocument` | ||
|
||
#include <rerun.hpp> | ||
|
||
int main() { | ||
const auto rec = rerun::RecordingStream("rerun_example_text_document"); | ||
rec.spawn().exit_on_failure(); | ||
|
||
rec.log( | ||
R"(world/42/escaped\ string\!)", | ||
rerun::TextDocument("This entity path was escaped manually") | ||
); | ||
rec.log( | ||
rerun::new_entity_path({"world", std::to_string(42), "unescaped string!"}), | ||
rerun::TextDocument("This entity path was provided as a list of unescaped strings") | ||
); | ||
|
||
assert(rerun::escape_entity_path_part("my string!") == R"(my\ string\!)"); | ||
assert(rerun::new_entity_path({"world", "42", "my string!"}) == R"(/world/42/my\ string\!)"); | ||
Wumpf marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import rerun as rr | ||
|
||
rr.init("rerun_example_entity_path", spawn=True) | ||
|
||
rr.log(r"world/42/escaped\ string\!", rr.TextDocument("This entity path was escaped manually")) | ||
rr.log( | ||
["world", 42, "unescaped string!"], rr.TextDocument("This entity path was provided as a list of unescaped strings") | ||
) | ||
|
||
assert rr.escape_entity_path_part("my string!") == r"my\ string\!" | ||
assert rr.new_entity_path(["world", 42, "my string!"]) == r"/world/42/my\ string\!" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
//! Example of different ways of constructing an entity path. | ||
|
||
fn main() -> Result<(), Box<dyn std::error::Error>> { | ||
let rec = rerun::RecordingStreamBuilder::new("rerun_example_text_document").spawn()?; | ||
|
||
rec.log( | ||
r"world/42/escaped\ string\!", | ||
&rerun::TextDocument::new("This entity path was escaped manually"), | ||
)?; | ||
rec.log( | ||
rerun::entity_path!["world", 42, "unescaped string!"], | ||
&rerun::TextDocument::new("This entity path was provided as a list of unescaped strings"), | ||
)?; | ||
|
||
Ok(()) | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
#include "entity_path.hpp" | ||
|
||
#include "c/rerun.h" | ||
#include "error.hpp" | ||
#include "string_utils.hpp" | ||
|
||
namespace rerun { | ||
std::string escape_entity_path_part(std::string_view unescaped) { | ||
auto escaped_c_str = _rr_escape_entity_path_part(detail::to_rr_string(unescaped)); | ||
|
||
if (escaped_c_str == nullptr) { | ||
Error(ErrorCode::InvalidStringArgument, "Failed to escape entity path part").handle(); | ||
return std::string(unescaped); | ||
} else { | ||
std::string result = escaped_c_str; | ||
_rr_free_string(escaped_c_str); | ||
return result; | ||
} | ||
} | ||
|
||
std::string new_entity_path(const std::vector<std::string_view>& path) { | ||
if (path.empty()) { | ||
return "/"; | ||
} | ||
|
||
std::string result; | ||
|
||
for (const auto& part : path) { | ||
result += "/"; | ||
result += escape_entity_path_part(part); | ||
} | ||
|
||
return result; | ||
} | ||
|
||
} // namespace rerun |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
#pragma once | ||
|
||
#include <string_view> | ||
#include <vector> | ||
|
||
namespace rerun { | ||
|
||
/// Escape an individual part of an entity path. | ||
/// | ||
/// For instance, `escape_entity_path_path("my image!")` will return `"my\ image\!"`. | ||
std::string escape_entity_path_part(std::string_view str); | ||
|
||
/// Construct an entity path by escaping each part of the path. | ||
/// | ||
/// For instance, `rerun::new_entity_path({"world", 42, "unescaped string!"})` will return | ||
/// `"world/42/escaped\ string\!"`. | ||
std::string new_entity_path(const std::vector<std::string_view>& path); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe this should take a rerun collection. That way you can also call it with a single string view without overloading Then again maybe that's a disadvantage because it muddles with the semantics of "list of path parts" 🤔 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is plenty of room for improvement. I'd love to be able to call it with a mix of strings and integers to, and have the implementation call |
||
|
||
} // namespace rerun |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion:
instead of doing the alloc/free dance a slightly safer alternative would be to use the "buffer in, count inout" pattern:
In this fairly common C pattern the desired count is returned but the buffer isn't fully written. Meaning one can either pass a null for buffer to just figure out the size one needs to allocate, or speculatively put in a buffer and check whether a second call is needed.
The advantage is that in many cases only one call is needed and that allocation stays with the caller.
The disadvantage is that when passing null buffer or too small buffer initially, this bottoms out in more work being done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
don't quite understand why
new_entity_path
is not fully implemented in the c interfaceThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I went with this implementation because it was much faster to implement. But it's also why I made it private.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand the question.
new_entity_path
returns astd::string
, so cannot be defined in C.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you could pass in several
rr_string
and write to a single char* buffer