refactor: drop internal bridge/ffi layers; exporter family lands
Single-lib cleanup: the per-crate src/bridge/ and src/ffi.rs layers are gone (oakundo/oakcommon/oaknode/oaktimeline/oakcodec/oakaudio/ oakrender/oaktask/oakplugin/oakstorage); cross-crate calls are plain Rust, CHandle marshalling shrinks to the oakengine boundary, and tests call the Rust APIs directly (pure C-ABI wrapper tests removed where the domain layer already covers the behavior). exporter.h family implemented: oakengine_export_render (CLI contract), oakengine_export_render_with_params (was a stub), last_error and progress callback; synchronous path reuses task_create_export + start_sync. Fixes on the way: oaktask video ticket self-deadlock, audio params dropped on the export path, codec encoder AAC slicing and H.264 time base. Real-mp4 tests cover both entry points, progress and the illegal-argument matrix. Also: oakstorage session maps null project handles to None (version- info path), configstore test double literal 3.14 -> 3.15 (clippy PI lint), oakaudio output callback scratch buffer + env-aware P1 test, cli media round-trip test uses a generated 16-frame clip (no more minute-long debug runs).
This commit is contained in:
@@ -15,18 +15,68 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! Render-side project copy client (the C++ ProjectCopier, inverted):
|
||||
//! all copying happens inside oaknode
|
||||
//! (`oaknode_project_deep_copy` / `sync_copy`); this module only tracks
|
||||
//! which copy belongs to which viewer and when to re-sync.
|
||||
//!
|
||||
//! The oaknode C ABI functions go through [`crate::bridge::node`]; oaknode
|
||||
//! never implemented the deep-copy symbols (single-lib plan §4.1 — dead
|
||||
//! direction), so the copy operations fail explainably and the
|
||||
//! success-path tests are `#[ignore]`d.
|
||||
//! all copying happens inside oaknode. oaknode never implemented the
|
||||
//! deep-copy direction (single-lib plan §4.1 — dead direction), so the
|
||||
//! copy operations fail explainably and the success-path tests are
|
||||
//! `#[ignore]`d.
|
||||
|
||||
use crate::bridge::node::{ChangeRecord, ProjectHandle};
|
||||
use crate::error::{Error, Result};
|
||||
|
||||
/// A project handle (oaknode-owned; the shared canonical handle type).
|
||||
pub type ProjectHandle = crate::handle::CHandle;
|
||||
|
||||
/// One change record (see oaknode `ChangeRecord`).
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub struct ChangeRecord {
|
||||
/// Discriminant (see oaknode `ChangeRecord`).
|
||||
pub kind: u32,
|
||||
/// Payload bytes (per-kind layout documented in project.h).
|
||||
pub payload: [u8; 48],
|
||||
}
|
||||
|
||||
/// Change-record discriminants (oaknode project.h).
|
||||
pub mod change_kind {
|
||||
/// Node added.
|
||||
pub const NODE_ADD: u32 = 0;
|
||||
/// Node removed.
|
||||
pub const NODE_REMOVE: u32 = 1;
|
||||
/// Edge added.
|
||||
pub const EDGE_ADD: u32 = 2;
|
||||
/// Edge removed.
|
||||
pub const EDGE_REMOVE: u32 = 3;
|
||||
/// Value change.
|
||||
pub const VALUE_CHANGE: u32 = 4;
|
||||
/// Value hint change.
|
||||
pub const VALUE_HINT_CHANGE: u32 = 5;
|
||||
/// Project setting change.
|
||||
pub const PROJECT_SETTING_CHANGE: u32 = 6;
|
||||
/// Footage proxy change.
|
||||
pub const FOOTAGE_PROXY: u32 = 7;
|
||||
}
|
||||
|
||||
/// `oaknode_project_deep_copy(project)` — would return an owned
|
||||
/// copied-project handle.
|
||||
///
|
||||
/// Never implemented: oaknode has no such Rust function (single-lib plan
|
||||
/// §4.1 — dead direction), so this always yields the empty handle, exactly
|
||||
/// as the previous runtime-symbol lookup did when the symbol was absent.
|
||||
pub fn project_deep_copy(_project: ProjectHandle) -> ProjectHandle {
|
||||
ProjectHandle::null()
|
||||
}
|
||||
|
||||
/// `oaknode_project_sync_copy` — never implemented (dead direction); the
|
||||
/// sync always fails explainably.
|
||||
pub fn project_sync_copy(
|
||||
_source: ProjectHandle,
|
||||
_copy: ProjectHandle,
|
||||
_changes: &[ChangeRecord],
|
||||
) -> Result<()> {
|
||||
Err(Error::Failed(
|
||||
"oaknode_project_sync_copy missing (not implemented in oaknode)".into(),
|
||||
))
|
||||
}
|
||||
|
||||
/// A handle to a render-side project copy.
|
||||
pub struct ProjectCopy {
|
||||
/// Identity of the source project.
|
||||
@@ -62,7 +112,7 @@ impl ProjectCopy {
|
||||
}
|
||||
// Release any previous copy.
|
||||
self.release_copy();
|
||||
let copy = crate::bridge::node::project_deep_copy(source);
|
||||
let copy = crate::copier::project_deep_copy(source);
|
||||
if copy.is_null() {
|
||||
return Err(Error::Failed(
|
||||
"oaknode_project_deep_copy failed (symbol missing or copy error)".into(),
|
||||
@@ -89,7 +139,7 @@ impl ProjectCopy {
|
||||
if copy.is_null() {
|
||||
return Err(Error::State);
|
||||
}
|
||||
crate::bridge::node::project_sync_copy(source, copy, changes)?;
|
||||
crate::copier::project_sync_copy(source, copy, changes)?;
|
||||
self.last_sync_generation += 1;
|
||||
self.has_pending_updates = false;
|
||||
Ok(())
|
||||
@@ -163,7 +213,7 @@ mod tests {
|
||||
fn sync_without_project_is_state_error() {
|
||||
let mut pc = ProjectCopy::new();
|
||||
let changes = [ChangeRecord {
|
||||
kind: crate::bridge::node::change_kind::NODE_ADD,
|
||||
kind: crate::copier::change_kind::NODE_ADD,
|
||||
payload: [0u8; 48],
|
||||
}];
|
||||
assert_eq!(pc.sync(&changes).unwrap_err().code(), Error::State.code());
|
||||
@@ -177,9 +227,10 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore = "needs oaknode C ABI (oaknode_project_deep_copy)"]
|
||||
#[ignore = "needs oaknode deep-copy (not implemented)"]
|
||||
fn deep_copy_roundtrip_with_real_node() {
|
||||
// Requires a live liboaknode; run with the app linked.
|
||||
// oaknode never implemented the deep-copy direction; the copy
|
||||
// always fails explainably, which is what the live path checks.
|
||||
let mut pc = ProjectCopy::new();
|
||||
let src = ProjectHandle {
|
||||
ctx: 1 as *mut std::ffi::c_void,
|
||||
@@ -187,10 +238,8 @@ mod tests {
|
||||
release: None,
|
||||
abi_version: crate::handle::OAKRENDER_ABI_VERSION,
|
||||
};
|
||||
if crate::bridge::node::node_abi_available() {
|
||||
pc.set_project(src).unwrap();
|
||||
assert_ne!(pc.copy, 0);
|
||||
assert!(pc.copied_project().is_some());
|
||||
}
|
||||
pc.set_project(src).unwrap();
|
||||
assert_ne!(pc.copy, 0);
|
||||
assert!(pc.copied_project().is_some());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user