Skip to content

Commit a7222bd

Browse files
committed
Improve docs for writer, add const enum values
1 parent 6ebbb7e commit a7222bd

File tree

3 files changed

+108
-16
lines changed

3 files changed

+108
-16
lines changed

src/api.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,21 @@ impl IResource for MCAPWriteOptions {
3939
}
4040
}
4141

42+
#[godot_api]
43+
impl MCAPWriteOptions {
44+
#[constant]
45+
/// No compression.
46+
const MCAP_COMPRESSION_NONE: i32 = MCAPCompression::None as i32;
47+
#[cfg(feature = "zstd")]
48+
#[constant]
49+
/// Zstandard compression.
50+
const MCAP_COMPRESSION_ZSTD: i32 = MCAPCompression::Zstd as i32;
51+
#[cfg(feature = "lz4")]
52+
#[constant]
53+
/// LZ4 frame compression.
54+
const MCAP_COMPRESSION_LZ4: i32 = MCAPCompression::Lz4 as i32;
55+
}
56+
4257
#[godot_api]
4358
impl MCAPSchema {
4459
/// Create a schema resource (id will be assigned when written).

src/types.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use godot::prelude::*;
22

33
/// Compression methods supported when writing MCAP files
44
#[derive(GodotConvert, Var, Export)]
5-
#[godot(via = GString)]
5+
#[godot(via = i64)]
66
pub enum MCAPCompression {
77
/// Do not compress chunks.
88
None,

src/writer.rs

Lines changed: 92 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,95 @@
11
use crate::{types::*, util::*};
22
use enumset::EnumSet;
3+
use godot::classes::RefCounted;
34
use godot::classes::file_access::ModeFlags;
4-
use godot::classes::{RefCounted};
55
use godot::prelude::*;
66
use godot::tools::GFile;
77
use mcap::records::Metadata;
88
use mcap::write::PrivateRecordOptions;
99
use mcap::{Attachment, Message, Writer, records::MessageHeader};
1010

11-
12-
1311
#[derive(GodotClass)]
14-
/// This class allows writing MCAP files.
12+
/// MCAP file writer for Godot.
13+
///
14+
/// Overview
15+
/// - Opens a file and writes MCAP records (channels, schemas, messages, attachments, metadata).
16+
/// - Accepts either full `MCAPMessage` resources via `write()` or pairs of header+payload via `write_to_known_channel()`.
17+
/// - Exposes a configurable `options` Resource to control chunking, compression, and emitted indexes before opening.
18+
///
19+
/// Error handling
20+
/// - Methods returning `bool` yield `false` on failure and set an internal last-error string.
21+
/// - Use `get_last_error()` to retrieve the message; success clears the last error.
22+
/// - If the writer is dropped without `close()`, it will attempt to finalize the file in `Drop`.
23+
///
24+
/// Minimal example
25+
/// ```gdscript
26+
/// var writer := MCAPWriter.new()
27+
/// if writer.open("user://test.mcap"):
28+
/// var ch := MCAPChannel.create("messages")
29+
/// # Optional: set encoding if needed
30+
/// # ch.message_encoding = "raw" # e.g. "json"
31+
///
32+
/// var msg := MCAPMessage.create(ch, var_to_bytes_with_objects("Hello World"))
33+
///
34+
/// writer.write(msg)
35+
/// writer.close()
36+
/// else:
37+
/// push_error(writer.get_last_error())
38+
/// ```
39+
///
40+
/// Full example with options, schemas, and channels
41+
/// ```gdscript
42+
/// var w := MCAPWriter.new()
43+
/// # Optional: tune options before opening
44+
/// w.options = MCAPWriteOptions.new()
45+
/// w.options.compression = MCAPCompression.None
46+
/// w.options.emit_summary_offsets = true
47+
/// w.options.emit_message_indexes = true
48+
/// w.options.emit_chunk_indexes = true
49+
///
50+
/// if not w.open("user://out.mcap"):
51+
/// push_error("open failed: %s" % w.get_last_error())
52+
/// return
53+
///
54+
/// # Define a schema (optional)
55+
/// var schema_id := w.add_schema("MyType", "jsonschema", PackedByteArray())
56+
/// if schema_id < 0:
57+
/// push_error("add_schema failed: %s" % w.get_last_error())
1558
///
16-
/// Error handling:
17-
/// - Methods that return `bool` will return `false` on failure and set an internal last-error message.
18-
/// - Call [`get_last_error()`] to retrieve the most recent error as a `GString`.
19-
/// - On successful operations, the last error is cleared.
59+
/// # Add a channel
60+
/// var ch_id := w.add_channel(schema_id, "/ch", "json", {})
61+
/// if ch_id < 0:
62+
/// push_error("add_channel failed: %s" % w.get_last_error())
63+
///
64+
/// # Write messages to the known channel
65+
/// var hdr := MCAPMessageHeader.create(ch_id)
66+
/// hdr.sequence = 1
67+
/// hdr.log_time = 1_000_000 # usec
68+
/// hdr.publish_time = 1_000_000
69+
/// var payload := PackedByteArray("{\"hello\":\"world\"}".to_utf8_buffer())
70+
/// if not w.write_to_known_channel(hdr, payload):
71+
/// push_error("write_to_known_channel failed: %s" % w.get_last_error())
72+
///
73+
/// # Optionally write an attachment or metadata
74+
/// # var att := MCAPAttachment.create("snapshot.bin", "application/octet-stream", PackedByteArray())
75+
/// # w.attach(att)
76+
/// # var meta := MCAPMetadata.create("run_info", {"key": "value"})
77+
/// # w.write_metadata(meta)
78+
///
79+
/// # Ensure chunks end cleanly for streaming readers
80+
/// w.flush()
81+
///
82+
/// # Finalize the file
83+
/// if not w.close():
84+
/// push_error("close failed: %s" % w.get_last_error())
85+
/// ```
86+
///
87+
/// Notes
88+
/// - Set or replace `options` before calling `open()`; they’re read once to construct the writer.
89+
/// - `write()` converts a full MCAPMessage Resource to mcap::Message (includes the channel fields).
90+
/// - `write_to_known_channel()` avoids schema/channel lookups when you already have their IDs.
91+
/// - `flush()` finishes the current chunk and flushes I/O to keep the file streamable mid-session.
92+
/// - Timestamps are microseconds (usec).
2093
#[class(init)]
2194
struct MCAPWriter {
2295
base: Base<RefCounted>,
@@ -92,8 +165,8 @@ impl MCAPWriter {
92165
}
93166

94167
self.path = path;
95-
// reset last error for a fresh session
96-
self.clear_error();
168+
// reset last error for a fresh session
169+
self.clear_error();
97170

98171
// 1) open file
99172
let file = match GFile::open(&self.path, ModeFlags::WRITE) {
@@ -230,9 +303,10 @@ impl MCAPWriter {
230303

231304
self.with_writer(
232305
"write_to_known_channel",
233-
|w| w
234-
.write_to_known_channel(&mcap_header, data.as_slice())
235-
.map(|_| true),
306+
|w| {
307+
w.write_to_known_channel(&mcap_header, data.as_slice())
308+
.map(|_| true)
309+
},
236310
false,
237311
)
238312
}
@@ -260,7 +334,10 @@ impl MCAPWriter {
260334

261335
self.with_writer(
262336
"write_private_record",
263-
|w| w.write_private_record(opcode, data.as_slice(), opts).map(|_| true),
337+
|w| {
338+
w.write_private_record(opcode, data.as_slice(), opts)
339+
.map(|_| true)
340+
},
264341
false,
265342
)
266343
}
@@ -312,7 +389,7 @@ impl MCAPWriter {
312389
/// of random data will compress terribly at any chunk size.)
313390
#[func]
314391
pub fn flush(&mut self) -> bool {
315-
self.with_writer("flush", |w| w.flush().map(|_| true), false)
392+
self.with_writer("flush", |w| w.flush().map(|_| true), false)
316393
}
317394

318395
/// Finalizes and closes the MCAP file. Returns true on success.

0 commit comments

Comments
 (0)