The arena that owns every object in a timeline.
Symbols in this group are spelled otio_document_…. An SDK drops that prefix, which is why the name beside each call is the short one.
Moves every object out of one document into another.
This is the call that lets a binding offer the API OpenTimelineIO's own Python and C++ users expect, where a `Clip` is built on its own and put inside a `Track` afterwards. An arena has no way to do that with handles alone: a handle means nothing outside the document it was issued for, so an object built in one document has to be *moved* into the other rather than pointed at. Upstream's reference-counted object model gets this for free and pays for it elsewhere; see `docs/adr/0001-ownership-model.md`.
`source` is consumed. On success it is released and the caller's pointer is set to null, so there is nothing left to free and no way to free it twice. On failure nothing moves and the pointer is left alone. A document cannot absorb itself: a `source` that points at `target` is `OTIO_STATUS_INVALID_ARGUMENT`.
The source's root is not adopted, because the target has its own.
# The translation
Every object arrives under a new handle, so every handle the caller still holds into `source` has to be translated. The call fills `out_from` and `out_to` with the old handle and the new one for each object moved, in the same order, and writes how many pairs there are to `out_count`.
Unlike the other calls that answer with a list, this one cannot be asked twice to size the buffer: the first call would already have consumed the source. Size the arrays with [`otio_document_node_count`] on the source before calling, which is exactly how many objects will move. A capacity smaller than that is `OTIO_STATUS_INVALID_ARGUMENT`, and nothing moves.
# Example
```c size_t moving = otio_document_node_count(clip_document); OtioNode *from = malloc(moving * sizeof(OtioNode)); OtioNode *to = malloc(moving * sizeof(OtioNode)); size_t moved = 0; otio_document_absorb(timeline_document, &clip_document, from, to, moving, &moved, std::ptr::null_mut()); /* `clip_document` is now NULL; `clip` is `to[i]` where `from[i]` is `clip`. */ ```
* otio_document_absorb(timeline_document, &clip_document, from, to, moving, &moved);| Parameter | Type | Role |
|---|---|---|
| target | document | the document, changed |
| source ? | document | the document, consumed |
| out_from ? | list<node> | a list written through, sized by the count |
| out_to ? | list<node> | a list written through, sized by the count |
| capacity | size | how many the buffer can hold |
| out_count | size | how many the call had to give |
| out_error | text | why the call failed, or null to skip it |
Copies a document, objects and all.
The copy keeps the arena's layout, so a handle into the original, passed with the copy, names the copy of the same object. The two documents are independent afterwards: an object added to or removed from one is not added to or removed from the other, and a handle issued by one after the copy means nothing in the other.
OtioStatus otio_document_clone(
const OtioDocument *source,
OtioDocument **out_document,
OtioBuffer *out_error);| Parameter | Type | Role |
|---|---|---|
| source ? | document | the document, borrowed |
| out_document | document | written through, not read |
| out_error | text | why the call failed, or null to skip it |
Returns whether a handle still names a live object.
bool otio_document_contains(const OtioDocument *source, OtioNode node);| Parameter | Type | Role |
|---|---|---|
| source ? | document | the document, borrowed |
| node | node | input |
Copies an object and everything it owns, into the same document.
The copy has no parent, whatever the original had.
OtioStatus otio_document_deep_clone(
OtioDocument *target,
OtioNode node,
OtioNode *out_node,
OtioBuffer *out_error);| Parameter | Type | Role |
|---|---|---|
| target | document | the document, changed |
| node | node | input |
| out_node | node | written through, not read |
| out_error | text | why the call failed, or null to skip it |
Releases a document and every object in it.
Passing null does nothing. Every handle into the document is stale afterwards; using one is a programming error this library cannot detect, because the arena it would be checked against is gone.
* otio_document_free(document);| Parameter | Type | Role |
|---|---|---|
| document ? | document | the document, changed |
Reads a document from OTIO JSON.
OtioStatus otio_document_from_json(
const char *json,
OtioDocument **out_document,
OtioBuffer *out_error);| Parameter | Type | Role |
|---|---|---|
| json | text | input |
| out_document | document | written through, not read |
| out_error | text | why the call failed, or null to skip it |
Creates an empty document with no root.
Returns null only if the allocation fails. Release it with [`otio_document_free`].
OtioDocument *otio_document_new(void);Returns how many live objects the document holds.
size_t otio_document_node_count(const OtioDocument *source);| Parameter | Type | Role |
|---|---|---|
| source ? | document | the document, borrowed |
Reads a document from a `.otio` file on disk.
A build without a file system, such as one for WebAssembly, reports `OTIO_STATUS_UNSUPPORTED`; use [`otio_document_from_json`] there.
OtioStatus otio_document_read_from_file(
const char *path,
OtioDocument **out_document,
OtioBuffer *out_error);| Parameter | Type | Role |
|---|---|---|
| path | text | input |
| out_document | document | written through, not read |
| out_error | text | why the call failed, or null to skip it |
Removes one object from the document.
Anything that referred to it still holds a handle, and that handle is now stale: a lookup fails rather than reaching whatever takes the slot next. To remove an object together with everything hanging off it, use [`otio_document_remove_recursive`].
OtioStatus otio_document_remove(
OtioDocument *target,
OtioNode node,
OtioBuffer *out_error);| Parameter | Type | Role |
|---|---|---|
| target | document | the document, changed |
| node | node | input |
| out_error | text | why the call failed, or null to skip it |
Removes an object and everything it owns: children, markers, effects and media references.
OtioStatus otio_document_remove_recursive(
OtioDocument *target,
OtioNode node,
OtioBuffer *out_error);| Parameter | Type | Role |
|---|---|---|
| target | document | the document, changed |
| node | node | input |
| out_error | text | why the call failed, or null to skip it |
Returns the document's root object.
Reports `OTIO_STATUS_NO_VALUE` for a document that has none, which is what a freshly created one is.
* otio_document_root(document, &timeline, NULL);| Parameter | Type | Role |
|---|---|---|
| source ? | document | the document, borrowed |
| out_node | node | written through, not read |
| out_error | text | why the call failed, or null to skip it |
Sets the document's root object.
Passing `otio_node_none` clears it.
OtioStatus otio_document_set_root(
OtioDocument *target,
OtioNode node,
OtioBuffer *out_error);| Parameter | Type | Role |
|---|---|---|
| target | document | the document, changed |
| node ? | node | input |
| out_error | text | why the call failed, or null to skip it |
Writes a document as OTIO JSON, starting from its root.
`indent` is how many spaces each level is indented by; [`otio_default_indent`] is what upstream's Python bindings use.
OtioStatus otio_document_to_json(
const OtioDocument *source,
size_t indent,
OtioBuffer *out_json,
OtioBuffer *out_error);| Parameter | Type | Role |
|---|---|---|
| source ? | document | the document, borrowed |
| indent | size | input |
| out_json | text | written through, not read |
| out_error | text | why the call failed, or null to skip it |
Writes a document to a `.otio` file on disk.
A build without a file system, such as one for WebAssembly, reports `OTIO_STATUS_UNSUPPORTED`; use [`otio_document_to_json`] there.
OtioStatus otio_document_write_to_file(
const OtioDocument *source,
const char *path,
size_t indent,
OtioBuffer *out_error);| Parameter | Type | Role |
|---|---|---|
| source ? | document | the document, borrowed |
| path | text | input |
| indent | size | input |
| out_error | text | why the call failed, or null to skip it |