Single mechanical restructure commit: - root Cargo.toml = oakapp bin + workspace; one cargo build produces oakapp, oak-cli, oak-worker, liboakengine.dylib - app/rust/src -> src/ (app at repo root, no rust/ nesting) - src/<mod>/rust -> crates/oak<mod>; src/oakcore-rs -> crates/oakcore; src/bindings/oakotio -> crates/oakotio; src/engine/rust -> crates/oakengine (keeps cdylib+staticlib+rlib) - public C headers include/<mod>/ -> crates/oakengine/include/<mod>/ - OFX SDK headers vendored into crates/oakplugin/ofx/ (HostSupport gone) - legacy deleted: old src/ C++ modules, engine/, core/, ffmpeg_bridge/, app/ (Qt), cli/worker C++, root CMakeLists, third_party/KDDockWidgets submodule, otio-install, all build-* output (~40GB) - oakstorage kept but excluded from the workspace (skeleton w/ todos); gpui excluded (own workspace) - verified: cargo build green, cargo test --workspace 1845/0 (with the documented OCIO_RS_* env override for the homebrew OCIO)
7.7 KiB
oaktask coverage map
Maps every C++ task class/method in src/task/src to its Rust home in this
crate. The C++ code remains the parity source of truth; // CPP-PARITY:
markers in the Rust files point at the exact C++ file. Review this map before
touching a task class so you rewrite the right module.
C++ class / file (src/task/src/...) |
Rust home |
|---|---|
task.h — olive::Task base |
src/task.rs |
taskmanager.h — TaskManager |
src/manager.rs |
codecbridge.h — submitter registration |
src/codecbridge.rs + src/bridge/codec.rs |
conform/conform.h — ConformTask |
src/conform.rs |
customcache/customcachetask.h |
src/customcache.rs |
export/export.h — ExportTask |
src/export.rs |
precache/precachetask.h — PreCacheTask |
src/precache.rs |
proxy/proxy.h — ProxyTask |
src/proxy.rs |
render/render.h — RenderTask base |
src/render.rs |
project/import/import.h |
src/project/import.rs |
project/load/load.h |
src/project/load.rs |
| interchange-format dispatch (task-side) | src/project/format.rs |
project/loadotio/loadotio.h |
src/project/loadotio.rs |
project/save/save.h |
src/project/save.rs |
project/saveotio/saveotio.h |
src/project/saveotio.rs |
Parity / golden tests
| Golden source | Rust test |
|---|---|
ConformTask::derive_filenames (conform.h) |
tests/parity_test.rs::conform_derive_filenames |
ProxyTask::build_arguments (proxy.h) |
tests/parity_test.rs::proxy_build_arguments |
ProxyTask::parse_progress (proxy.h) |
tests/parity_test.rs::proxy_parse_progress |
src/task/tests/task_test.cpp (manager/task) |
tests/manager_test.rs, tests/ffi_contract_test.rs |
include/task/*.h (C ABI contract) |
tests/ffi_contract_test.rs |
loadotio.cpp (OTIO -> project) |
tests/otio_test.rs::otio_load_*, fcpxml_load_* (synthetic documents built with oakotio) |
saveotio.cpp (project -> OTIO) |
tests/otio_test.rs::otio_save_*, fcpxml_save_* (exports re-parsed with oakotio) |
extension dispatch (.otio/.fcpxml) |
tests/otio_test.rs::otio_load_extension_dispatch_matrix (+ unknown-extension failures on both tasks) |
Couplings handled through other modules' C ABIs
The task module never reimplements another oak module. Every cross-module
call is a declared extern "C" import in src/bridge/, mirroring the frozen
headers verbatim:
- oakrender:
bridge/render.rs— cancelatom (OakCancelAtom), tickets (OakRenderTicket,oakrender_ticket_*), project copier (OakRenderProjectCopier), color processor (OakColorProcessor), frame cache (OakRenderCache). - oakcodec:
bridge/codec.rs— encoder/decoder (OakEncoder/OakDecoder), frames (OakFrame), task submitter (oakcodec_set_task_submit_cb,OakCodecTaskRequest), proxy params (oakcodec_proxy_params). - oaknode:
bridge/node.rs— project/footage/folder/sequence/colormanager/ node handles for the project tasks. - oakundo:
bridge/undo.rs—OakUndoCommand. - oakcommon / oakcore:
bridge/common.rs—OakVideoParams,OakColorTransform,OakAudioParams.
Deliberately out of scope
- Export/precache render details — the C++ render loop is a concurrent
ticket pool; the Rust
render.rsis a simplified synchronous loop (one ticket at a time,wait()ed). The per-frame observable contract (orderedframe_downloaded/audio_downloaded, progress, cancellation) is preserved. The export task additionally skips the temporary-file rename dance and the sidecar subtitle encoder.
export.cpp.pending / export.h.pending in src/task/src/export/ are
in-progress variants; src/export.rs is mapped to the canonical export.h.
OpenTimelineIO was previously out of scope (OTIO parsing stayed in the C++
impl); since oakotio landed it is covered: LoadOTIOTask/SaveOTIOTask
parse/serialize through oakotio (see README decision #6) and the project
graph still moves across the oaknode/oaktimeline C ABIs only. The tasks
are format-aware: src/project/format.rs dispatches .otio (OpenTimelineIO
JSON) vs .fcpxml (FCPXML) from the filename extension (case-insensitive)
at the parse/serialize call; the track/clip/footage code is shared, and
the C ABI is unchanged (the format parameter is the filename itself).
Test strategy
tests/common/mod.rsprovides#[no_mangle]stubs for every extern C symbol the crate imports (test binaries link the rlib without the real module DLLs). Each stub family exposesset_*controls so tests drive both the success and the failure path. The oakrender ticket stubs are compiled out when thereal-oakrenderfeature is on.tests/manager_test.rsdrives the codec submitter end-to-end: a real shell script stands in for ffmpeg (proxy success + 3 failure modes), and conform success/failure/cancellation are exercised through real file renames.tests/render_real_integration_test.rs(featurereal-oakrender+--testfilter; links the real oakrender crate) drivesRenderTask::renderagainst the actual ticket arena — frames arrive in timestamp order through the CPU path, no GPU.- Every exported
oaktask_*symbol has at least one success and one failure-path test (tests/ffi_contract_test.rs,tests/project_task_test.rs).
Coverage (cargo tarpaulin, 2026-08)
86.53% line coverage (1850/2138). Per-file (lines covered/total):
| File | Covered |
|---|---|
| src/bridge/node.rs | 4/4 |
| src/bridge/render.rs | 29/36 |
| src/codecbridge.rs | 49/49 |
| src/conform.rs | 72/79 |
| src/customcache.rs | 43/45 |
| src/error.rs | 4/8 |
| src/export.rs | 104/113 |
| src/ffi/manager.rs | 25/27 |
| src/ffi/project.rs | 173/180 |
| src/ffi/task.rs | 94/98 |
| src/ffi/taskhandle.rs | 44/46 |
| src/handle.rs | 29/56 |
| src/manager.rs | 67/89 |
| src/precache.rs | 33/43 |
| src/project/format.rs | 8/8 |
| src/project/import.rs | 184/235 |
| src/project/load.rs | 36/51 |
| src/project/loadotio.rs | 201/224 |
| src/project/save.rs | 28/41 |
| src/project/saveotio.rs | 196/220 |
| src/proxy.rs | 114/141 |
| src/render.rs | 215/242 |
| src/task.rs | 98/103 |
The remaining gaps are the panic-guard helpers (handle.rs, exercised only
through #[no_mangle] exports that return codes directly), the
load/save serializer code-map alternatives, and a few import/manager edge
branches — all reachable but not individually asserted.
The concurrent render loop (src/render.rs) is exercised both through the
export run-path tests and the dedicated concurrency suite
(tests/render_loop_test.rs: scrambled completion order, audio-first
ordering, cancel drain, progress monotonicity, error stop, windowing).