From 0ca9cad4481e00894c27dfc4cff252d7a2253fdc Mon Sep 17 00:00:00 2001 From: Mike Solar Date: Mon, 10 Aug 2026 16:55:35 +0800 Subject: [PATCH] feat(engine): rename facade to oakengine, build liboakengine.dylib - src/facade/rust -> src/engine/rust; package oakfacade -> oakengine - crate-type += cdylib; module crates are real deps; linkage anchors force-link module C ABIs into the dylib - build.rs: -undefined dynamic_lookup for host-provided oakcore_*/fb_* - nm: 749 oakengine_* + 687 module oak*_* exports; undefined set is only the intended host-provided symbols - worker/cli updated to the new path/name; undo test race fix --- app/rust/Cargo.lock | 1 + app/rust/Cargo.toml | 4 + app/rust/docs/screenshot-window.png | Bin 467939 -> 406654 bytes app/rust/examples/screenshot.rs | 14 +- app/rust/src/app.rs | 4 +- app/rust/src/i18n.rs | 80 +- app/rust/src/oakui/mock.rs | 703 ++++++- app/rust/src/panels/mod.rs | 2 +- app/rust/src/panels/node_editor.rs | 239 ++- app/rust/src/panels/program_viewer.rs | 19 + app/rust/src/panels/source_viewer.rs | 27 +- cli/rust/Cargo.lock | 1669 ++++++++++++++++- cli/rust/Cargo.toml | 2 +- cli/rust/src/deferred.rs | 12 +- cli/rust/src/ffi.rs | 6 +- cli/rust/src/main.rs | 2 +- cli/rust/tests/cli.rs | 4 +- gpui | 2 +- src/{facade => engine}/rust/Cargo.lock | 3 +- src/engine/rust/Cargo.toml | 70 + src/{facade => engine}/rust/README.md | 30 +- src/engine/rust/build.rs | 33 + src/{facade => engine}/rust/src/audio.rs | 0 .../rust/src/bridge/audio.rs | 0 .../rust/src/bridge/codec.rs | 0 .../rust/src/bridge/common.rs | 0 src/{facade => engine}/rust/src/bridge/mod.rs | 0 .../rust/src/bridge/node.rs | 0 .../rust/src/bridge/plugin.rs | 0 .../rust/src/bridge/render.rs | 0 .../rust/src/bridge/task.rs | 0 .../rust/src/bridge/timeline.rs | 0 .../rust/src/bridge/undo.rs | 0 src/{facade => engine}/rust/src/codec.rs | 0 src/{facade => engine}/rust/src/common.rs | 0 src/{facade => engine}/rust/src/deferred.rs | 0 src/{facade => engine}/rust/src/error.rs | 0 src/{facade => engine}/rust/src/handle.rs | 0 src/{facade => engine}/rust/src/ipc.rs | 0 src/{facade => engine}/rust/src/lib.rs | 21 +- src/engine/rust/src/linkage.rs | 66 + src/{facade => engine}/rust/src/node.rs | 0 src/{facade => engine}/rust/src/plugin.rs | 0 src/{facade => engine}/rust/src/render.rs | 0 src/{facade => engine}/rust/src/task.rs | 0 src/{facade => engine}/rust/src/timeline.rs | 0 src/{facade => engine}/rust/src/undo.rs | 0 src/{facade => engine}/rust/src/worker.rs | 0 src/{facade => engine}/rust/tests/audio.rs | 2 +- src/{facade => engine}/rust/tests/codec.rs | 6 +- src/{facade => engine}/rust/tests/common.rs | 6 +- .../rust/tests/common/mod.rs | 0 src/{facade => engine}/rust/tests/linkage.rs | 0 src/{facade => engine}/rust/tests/node.rs | 14 +- src/{facade => engine}/rust/tests/plugin.rs | 4 +- src/{facade => engine}/rust/tests/render.rs | 2 +- src/{facade => engine}/rust/tests/task.rs | 8 +- src/{facade => engine}/rust/tests/timeline.rs | 12 +- src/{facade => engine}/rust/tests/undo.rs | 26 +- src/facade/rust/Cargo.toml | 55 - worker/rust/Cargo.lock | 397 +++- worker/rust/Cargo.toml | 6 +- worker/rust/build.rs | 33 + worker/rust/src/main.rs | 8 +- worker/rust/src/session.rs | 6 +- worker/rust/src/transport.rs | 4 +- 66 files changed, 3398 insertions(+), 204 deletions(-) rename src/{facade => engine}/rust/Cargo.lock (99%) create mode 100644 src/engine/rust/Cargo.toml rename src/{facade => engine}/rust/README.md (84%) create mode 100644 src/engine/rust/build.rs rename src/{facade => engine}/rust/src/audio.rs (100%) rename src/{facade => engine}/rust/src/bridge/audio.rs (100%) rename src/{facade => engine}/rust/src/bridge/codec.rs (100%) rename src/{facade => engine}/rust/src/bridge/common.rs (100%) rename src/{facade => engine}/rust/src/bridge/mod.rs (100%) rename src/{facade => engine}/rust/src/bridge/node.rs (100%) rename src/{facade => engine}/rust/src/bridge/plugin.rs (100%) rename src/{facade => engine}/rust/src/bridge/render.rs (100%) rename src/{facade => engine}/rust/src/bridge/task.rs (100%) rename src/{facade => engine}/rust/src/bridge/timeline.rs (100%) rename src/{facade => engine}/rust/src/bridge/undo.rs (100%) rename src/{facade => engine}/rust/src/codec.rs (100%) rename src/{facade => engine}/rust/src/common.rs (100%) rename src/{facade => engine}/rust/src/deferred.rs (100%) rename src/{facade => engine}/rust/src/error.rs (100%) rename src/{facade => engine}/rust/src/handle.rs (100%) rename src/{facade => engine}/rust/src/ipc.rs (100%) rename src/{facade => engine}/rust/src/lib.rs (78%) create mode 100644 src/engine/rust/src/linkage.rs rename src/{facade => engine}/rust/src/node.rs (100%) rename src/{facade => engine}/rust/src/plugin.rs (100%) rename src/{facade => engine}/rust/src/render.rs (100%) rename src/{facade => engine}/rust/src/task.rs (100%) rename src/{facade => engine}/rust/src/timeline.rs (100%) rename src/{facade => engine}/rust/src/undo.rs (100%) rename src/{facade => engine}/rust/src/worker.rs (100%) rename src/{facade => engine}/rust/tests/audio.rs (99%) rename src/{facade => engine}/rust/tests/codec.rs (98%) rename src/{facade => engine}/rust/tests/common.rs (97%) rename src/{facade => engine}/rust/tests/common/mod.rs (100%) rename src/{facade => engine}/rust/tests/linkage.rs (100%) rename src/{facade => engine}/rust/tests/node.rs (97%) rename src/{facade => engine}/rust/tests/plugin.rs (97%) rename src/{facade => engine}/rust/tests/render.rs (99%) rename src/{facade => engine}/rust/tests/task.rs (98%) rename src/{facade => engine}/rust/tests/timeline.rs (99%) rename src/{facade => engine}/rust/tests/undo.rs (93%) delete mode 100644 src/facade/rust/Cargo.toml create mode 100644 worker/rust/build.rs diff --git a/app/rust/Cargo.lock b/app/rust/Cargo.lock index 3c23ca8c7..2b6368443 100644 --- a/app/rust/Cargo.lock +++ b/app/rust/Cargo.lock @@ -3636,6 +3636,7 @@ dependencies = [ "gpui_platform", "gpui_widgets", "image", + "smallvec", ] [[package]] diff --git a/app/rust/Cargo.toml b/app/rust/Cargo.toml index 243c89efa..dc781aa1a 100644 --- a/app/rust/Cargo.toml +++ b/app/rust/Cargo.toml @@ -37,6 +37,10 @@ gpui = { path = "../../gpui/crates/gpui" } gpui_platform = { path = "../../gpui/crates/gpui_platform", features = ["font-kit"] } # Oak's widget library: menus, viewer, form controls, project explorer. gpui_widgets = { path = "../../gpui/crates/gpui_widgets" } +# The mock engine's synthetic viewer frames (`image::Frame` in a +# `RenderImage`), matching the versions gpui itself uses. +image = "0.25" +smallvec = "1" [dev-dependencies] # `#[gpui::test]` harness for engine-seam smoke tests (test-support feature). diff --git a/app/rust/docs/screenshot-window.png b/app/rust/docs/screenshot-window.png index c656a9afc5429dc2e84200c0eee74606491e25b6..5e20ab3cf02db9e5c2ad46aad348012ec1df67d8 100644 GIT binary patch delta 161571 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
J@a*)@sNZ-3B@3thoK}^PSSSR!X!-3 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ⅇ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
    !mYOz!Koq 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 N-7@l(Z{4%t{{fY^w!{Dc diff --git a/app/rust/examples/screenshot.rs b/app/rust/examples/screenshot.rs index 2566a2660..f61fc110e 100644 --- a/app/rust/examples/screenshot.rs +++ b/app/rust/examples/screenshot.rs @@ -57,12 +57,16 @@ fn main() -> Result<()> { })?; let handle: AnyWindowHandle = window.into(); - // Let the platform settle, then draw one full frame into the rendered - // scene so `render_to_image` has something to capture. + // Draw a few frames so the layout settles: the node editor fits its graph + // once the canvas size is known and the viewers upload their first CPU + // frame, both of which happen on the frame after the initial render. + for _ in 0..4 { + cx.run_until_parked(); + cx.update_window(handle, |_root, window, app| { + let _ = window.draw(app); + })?; + } cx.run_until_parked(); - cx.update_window(handle, |_root, window, app| { - let _ = window.draw(app); - })?; let image = cx.capture_screenshot(handle)?; std::fs::create_dir_all(std::path::Path::new(OUT).parent().unwrap())?; diff --git a/app/rust/src/app.rs b/app/rust/src/app.rs index 41f228a13..8ed355c88 100644 --- a/app/rust/src/app.rs +++ b/app/rust/src/app.rs @@ -152,7 +152,7 @@ impl PanelRegistry for AppPanelRegistry { cx, )), "node-editor" => Some(PanelHandle::new( - cx.new(|cx| NodeEditorPanel::new(window, cx)), + cx.new(|cx| NodeEditorPanel::new(self.engine.clone(), window, cx)), cx, )), "inspector" => Some(PanelHandle::new( @@ -234,7 +234,7 @@ impl OakApp { cx, ) }); - let node_editor = cx.new(|cx| NodeEditorPanel::new(window, cx)); + let node_editor = cx.new(|cx| NodeEditorPanel::new(engine.clone(), window, cx)); let inspector = cx.new(|cx| InspectorPanel::new(engine.clone(), window, cx)); let history = cx.new(|cx| HistoryPanel::new(window, cx)); let timeline_panel = diff --git a/app/rust/src/i18n.rs b/app/rust/src/i18n.rs index d621126ac..1a328994f 100644 --- a/app/rust/src/i18n.rs +++ b/app/rust/src/i18n.rs @@ -95,17 +95,19 @@ pub fn set_language(language: Language) { Language::ZhCN => 1, }, Ordering::Relaxed); persist_language(language); + sync_widgets(); } /// Loads the persisted language from the oakcommon config C ABI. Called once /// at startup. Never fails: without liboakcommon the default (en-US) stays. pub fn init() { let Some(store) = ConfigAbi::load() else { + sync_widgets(); return; }; match store.get("Language") { Some(code) if !code.is_empty() => set_language(Language::from_code(&code)), - _ => {} + _ => sync_widgets(), } } @@ -127,6 +129,28 @@ pub fn tr(key: &'static str) -> &'static str { } } +/// The keys the gpui widget crates localize through +/// `gpui_widgets::i18n` (viewer transport labels, effect-stack empty state). +pub const WIDGET_KEYS: &[&str] = &[ + "viewer.safe_frames", + "viewer.zoom", + "viewer.no_frame_source", + "effect_stack.empty", + "effect_stack.add", +]; + +/// Installs the active language's widget strings into the +/// `gpui_widgets::i18n` string-table hook, so the widget-baked labels follow +/// the app language on the next render. Called on startup and on every +/// language switch; the widgets keep their built-in defaults otherwise. +pub fn sync_widgets() { + let mut table = gpui_widgets::i18n::StringTable::new(); + for key in WIDGET_KEYS { + table.insert((*key).to_string(), tr(key).to_string()); + } + gpui_widgets::i18n::set_table(table); +} + /// Looks `key` up in the en-US table. fn en(key: &'static str) -> &'static str { EN @@ -226,14 +250,16 @@ const EN: &[(&str, &str)] = &[ ("timeline.track_height", "Track Height"), ("timeline.snap", "Snap"), // --- node editor --- - ("node.zoom_in", "Zoom In"), - ("node.zoom_out", "Zoom Out"), ("node.fit", "Fit"), - ("node.fit_window", "Fit Window"), - ("node.placeholder", "Node Editor · Placeholder — gpui::node_graph not wired up yet"), // --- viewer header chips --- ("viewer.source", "Source Viewer · Source"), ("viewer.program", "Program Viewer · Program"), + // --- widget-baked strings (synced to gpui_widgets::i18n) --- + ("viewer.safe_frames", "Safe Frames"), + ("viewer.zoom", "Zoom"), + ("viewer.no_frame_source", "No frame source"), + ("effect_stack.empty", "No selection"), + ("effect_stack.add", "+ Add Effect"), // --- inspector --- ("inspector.params", "Parameters (placeholder)"), ]; @@ -319,14 +345,16 @@ const ZH: &[(&str, &str)] = &[ ("timeline.track_height", "轨道高"), ("timeline.snap", "吸附"), // --- node editor --- - ("node.zoom_in", "放大"), - ("node.zoom_out", "缩小"), ("node.fit", "适配"), - ("node.fit_window", "适配窗口"), - ("node.placeholder", "节点编辑器 · 占位 — gpui::node_graph 尚未接入"), // --- viewer header chips --- ("viewer.source", "素材查看器 · 源"), ("viewer.program", "序列查看器 · 节目"), + // --- widget-baked strings (synced to gpui_widgets::i18n) --- + ("viewer.safe_frames", "安全框"), + ("viewer.zoom", "缩放"), + ("viewer.no_frame_source", "无帧源"), + ("effect_stack.empty", "未选择"), + ("effect_stack.add", "+ 添加效果"), // --- inspector --- ("inspector.params", "参数(占位)"), ]; @@ -534,6 +562,40 @@ mod tests { assert_eq!(tr("menu.file.save"), "Save"); } + /// `sync_widgets` installs the active language's strings into the widget + /// string-table hook, so the widget-baked labels follow the app language. + #[test] + fn sync_widgets_installs_the_active_language() { + let _guard = lang_lock().lock().unwrap(); + set_language(Language::EnUs); + gpui_widgets::i18n::clear_table(); // simulate a fresh process + sync_widgets(); + assert_eq!( + gpui_widgets::i18n::tr("viewer.safe_frames", "安全框").to_string(), + "Safe Frames" + ); + assert_eq!( + gpui_widgets::i18n::tr("viewer.zoom", "缩放").to_string(), + "Zoom" + ); + // Every widget key is covered by the installed table. + for key in WIDGET_KEYS { + let installed = gpui_widgets::i18n::tr(key, "fallback").to_string(); + assert_ne!(installed, "fallback", "widget key {key} not synced"); + } + + set_language(Language::ZhCN); + assert_eq!( + gpui_widgets::i18n::tr("viewer.safe_frames", "Safe Frames").to_string(), + "安全框" + ); + assert_eq!( + gpui_widgets::i18n::tr("effect_stack.add", "+ Add Effect").to_string(), + "+ 添加效果" + ); + set_language(Language::EnUs); + } + /// The config code round-trips. #[test] fn language_code_round_trips() { diff --git a/app/rust/src/oakui/mock.rs b/app/rust/src/oakui/mock.rs index 6407fa937..c6533de20 100644 --- a/app/rust/src/oakui/mock.rs +++ b/app/rust/src/oakui/mock.rs @@ -36,17 +36,25 @@ //! The real engine will later implement the same gateway over the //! `liboakengine` C ABI; only the wiring in [`crate::app`] changes. +use std::collections::{BTreeSet, HashMap}; use std::path::PathBuf; -use std::sync::Arc; +use std::sync::{Arc, Mutex}; use std::time::Instant; use gpui::effect_stack::{ EffectCardKind, EffectData, EffectId, EffectStackDataSource, EffectStackEvent, }; +use gpui::node_graph::{ + EdgeData, EdgeId, NodeData, NodeGraphDataSource, NodeGraphEvent, NodeId, PortData, + PortDataType, PortId, PortKind, +}; use gpui::timeline::{ ClipData, ClipId, Frame, FrameRange, FrameRate, TimelineDataSource, TrackData, TrackKind, }; -use gpui::{prelude::*, px, App, Context, Entity, Hsla, Pixels, SharedString}; +use gpui::{ + hsla, point, prelude::*, px, App, Context, Entity, Hsla, Pixels, Point, RenderImage, + SharedString, +}; use gpui_widgets::audio_meter::AudioMeterDataSource; use gpui_widgets::project_explorer::{ProjectDataSource, ProjectEntry}; use gpui_widgets::viewer::PlaybackClock; @@ -57,6 +65,12 @@ use super::transport::TransportState; /// The demo sequence length: 00:04:18:18 at 25 fps. const SEQUENCE_LENGTH: i64 = 6468; +/// The synthetic viewer test frame is rendered at a small proxy size (the +/// real engine will deliver full-resolution frames; the mock only needs to +/// prove the CPU-frame path end to end). +const SYNTH_FRAME_WIDTH: u32 = 384; +const SYNTH_FRAME_HEIGHT: u32 = 216; + // --------------------------------------------------------------------------- // Clocks // --------------------------------------------------------------------------- @@ -256,6 +270,125 @@ impl EffectData for MockEffect { } } +// --------------------------------------------------------------------------- +// Node graph model +// --------------------------------------------------------------------------- + +/// A port on a mock node. `connected` is a model-side cache refreshed by +/// [`MockEngine::refresh_port_connectivity`] after every graph mutation. +#[derive(Debug, Clone)] +pub struct MockPort { + id: PortId, + kind: PortKind, + label: SharedString, + data_type: PortDataType, + connected: bool, +} + +impl PortData for MockPort { + fn id(&self) -> PortId { + self.id + } + + fn kind(&self) -> PortKind { + self.kind + } + + fn label(&self) -> SharedString { + self.label.clone() + } + + fn data_type(&self) -> PortDataType { + self.data_type.clone() + } + + fn is_connected(&self) -> bool { + self.connected + } +} + +/// A node in the mock graph (媒体 → 变换 → … → 输出). +#[derive(Debug, Clone)] +pub struct MockNode { + id: NodeId, + title: SharedString, + position: Point, + inputs: Vec, + outputs: Vec, + header_color: Option, + enabled: bool, + collapsed: bool, +} + +impl NodeData for MockNode { + type Port = MockPort; + + fn id(&self) -> NodeId { + self.id + } + + fn title(&self) -> SharedString { + self.title.clone() + } + + fn position(&self) -> Point { + self.position + } + + fn inputs(&self) -> Vec { + self.inputs.clone() + } + + fn outputs(&self) -> Vec { + self.outputs.clone() + } + + fn header_color(&self) -> Option { + self.header_color + } + + fn is_collapsed(&self) -> bool { + self.collapsed + } + + fn is_enabled(&self) -> bool { + self.enabled + } +} + +/// An edge in the mock graph: a connection from an output port to an input +/// port. +#[derive(Debug, Clone)] +pub struct MockEdge { + id: EdgeId, + from_node: NodeId, + from_port: PortId, + to_node: NodeId, + to_port: PortId, +} + +impl EdgeData for MockEdge { + fn id(&self) -> EdgeId { + self.id + } + + fn from_node(&self) -> NodeId { + self.from_node + } + + fn from_port(&self) -> PortId { + self.from_port + } + + fn to_node(&self) -> NodeId { + self.to_node + } + + fn to_port(&self) -> PortId { + self.to_port + } +} + // --------------------------------------------------------------------------- // The engine // --------------------------------------------------------------------------- @@ -281,6 +414,19 @@ pub struct MockEngine { selected_item: Option, /// Phase counter driving the demo audio levels. meter_phase: u32, + /// The demo node graph shown in the node editor. + nodes: Vec, + /// The demo node-graph edges. + edges: Vec, + /// Id allocator for edges added at runtime. + next_edge_id: u64, + /// The node selection, kept in sync with the node editor (and, later, the + /// effect stack) so both views share one selection. + node_selection: BTreeSet, + /// Cache of the synthetic CPU frames handed to the viewers, keyed by + /// monitor. Entries are the playhead frame that produced the image, so a + /// paused viewer never regenerates its picture. + cpu_frame_cache: Mutex)>>, } impl MockEngine { @@ -307,8 +453,122 @@ impl MockEngine { l: 0.55, a: 1.0, }; + let node_color = |h: f32| Hsla { + h, + s: 0.55, + l: 0.5, + a: 1.0, + }; - Self { + // The demo node graph: two clips, one through the transform, one + // through the blur, merged in the mixer and LUT'd to the viewer. + // Port ids are globally unique. + let video_type = PortDataType::new("video", hsla(0.55, 0.75, 0.6, 1.0)); + let audio_type = PortDataType::new("audio", hsla(0.1, 0.7, 0.55, 1.0)); + let port = |id: u64, + kind: PortKind, + label: &str, + data_type: &PortDataType| MockPort { + id: PortId(id), + kind, + label: label.into(), + data_type: data_type.clone(), + connected: false, + }; + let node = |id: u64, + title: &str, + position: (f32, f32), + color: f32, + inputs: Vec, + outputs: Vec| MockNode { + id: NodeId(id), + title: title.into(), + position: point(px(position.0), px(position.1)), + inputs, + outputs, + header_color: Some(node_color(color)), + enabled: true, + collapsed: false, + }; + let nodes = vec![ + node( + 0, + "第一稿.mp4", + (40.0, 40.0), + 0.55, + vec![], + vec![port(1, PortKind::Output, "video", &video_type)], + ), + node( + 1, + "B-roll.mp4", + (40.0, 230.0), + 0.60, + vec![], + vec![ + port(3, PortKind::Output, "video", &video_type), + port(4, PortKind::Output, "audio", &audio_type), + ], + ), + node( + 2, + "变换", + (320.0, 40.0), + 0.35, + vec![ + port(20, PortKind::Input, "in", &video_type), + port(22, PortKind::Input, "mask", &video_type), + ], + vec![port(21, PortKind::Output, "out", &video_type)], + ), + node( + 3, + "模糊", + (320.0, 230.0), + 0.78, + vec![port(30, PortKind::Input, "in", &video_type)], + vec![port(31, PortKind::Output, "out", &video_type)], + ), + node( + 4, + "混合", + (600.0, 130.0), + 0.08, + vec![ + port(40, PortKind::Input, "A", &video_type), + port(41, PortKind::Input, "B", &video_type), + ], + vec![port(42, PortKind::Output, "out", &video_type)], + ), + node( + 5, + "输出", + (880.0, 130.0), + 0.0, + vec![port(50, PortKind::Input, "in", &video_type)], + vec![], + ), + ]; + let edge = |id: u64, + from_node: u64, + from_port: u64, + to_node: u64, + to_port: u64| MockEdge { + id: EdgeId(id), + from_node: NodeId(from_node), + from_port: PortId(from_port), + to_node: NodeId(to_node), + to_port: PortId(to_port), + }; + let edges = vec![ + edge(1, 0, 1, 2, 20), + edge(2, 1, 3, 3, 30), + edge(3, 2, 21, 4, 40), + edge(4, 3, 31, 4, 41), + edge(5, 4, 42, 5, 50), + ]; + + let mut this = Self { project: Project { name: "第一稿".into(), path: PathBuf::from("/home/mikesolar/Videos/aaa.ove"), @@ -407,7 +667,16 @@ impl MockEngine { program_playing: false, selected_item: None, meter_phase: 0, - } + nodes, + edges, + next_edge_id: 6, + node_selection: BTreeSet::new(), + cpu_frame_cache: Mutex::new(HashMap::new()), + }; + // The demo graph is born connected: derive every port's `connected` + // flag from the edge list. + this.refresh_port_connectivity(); + this } /// The current sequence length (also used by the gateway). @@ -476,6 +745,134 @@ impl MockEngine { cx.notify(); } + /// Applies a node-editor request to the mock graph (the "edits are + /// requests" loop: the view emits, the engine applies and notifies). + pub fn apply_node_graph_event(&mut self, event: &NodeGraphEvent, cx: &mut Context) { + match event { + NodeGraphEvent::NodeMovePreview { .. } | NodeGraphEvent::ViewChanged { .. } => {} + NodeGraphEvent::NodeMoveRequested { nodes, delta } => { + for id in nodes { + if let Some(node) = self.nodes.iter_mut().find(|n| n.id() == *id) { + node.position = node.position + *delta; + } + } + } + NodeGraphEvent::ConnectionRequested { from, to } => { + if self.can_connect(*from, *to) { + let from_node = self.node_with_port(*from).map(|n| n.id()); + let to_node = self.node_with_port(*to).map(|n| n.id()); + if let (Some(from_node), Some(to_node)) = (from_node, to_node) { + self.edges.push(MockEdge { + id: EdgeId(self.next_edge_id), + from_node, + from_port: *from, + to_node, + to_port: *to, + }); + self.next_edge_id += 1; + self.refresh_port_connectivity(); + } + } + } + NodeGraphEvent::DisconnectionRequested { edge } => { + if let Some(index) = self.edges.iter().position(|e| e.id() == *edge) { + self.edges.remove(index); + self.refresh_port_connectivity(); + } + } + NodeGraphEvent::DeleteRequested { nodes, edges } => { + self.edges.retain(|edge| { + !edges.contains(&edge.id()) + && !nodes.contains(&edge.from_node()) + && !nodes.contains(&edge.to_node()) + }); + self.nodes.retain(|node| !nodes.contains(&node.id())); + self.node_selection.clear(); + self.refresh_port_connectivity(); + } + NodeGraphEvent::SelectionChanged { nodes } => { + self.node_selection = nodes.clone(); + } + NodeGraphEvent::BackgroundClicked { position } => { + // The real app opens an "add node" menu here; the mock logs it. + println!("[node editor] add-node menu at graph {position:?} (mock: ignored)"); + } + } + cx.notify(); + } + + /// The node currently under the cursor selection (demo state; the effect + /// stack will sync to this once it drives the same selection). + pub fn selected_node_ids(&self) -> &BTreeSet { + &self.node_selection + } + + /// Looks up a node by id (test helper). + #[cfg(test)] + fn node(&self, id: NodeId) -> Option<&MockNode> { + self.nodes.iter().find(|n| n.id() == id) + } + + /// Looks up a port by its globally unique id. + fn port(&self, id: PortId) -> Option<&MockPort> { + self.nodes + .iter() + .flat_map(|n| n.inputs.iter().chain(n.outputs.iter())) + .find(|p| p.id() == id) + } + + /// Returns the node that owns `port`. + fn node_with_port(&self, port: PortId) -> Option<&MockNode> { + self.nodes.iter().find(|n| { + n.inputs.iter().any(|p| p.id() == port) + || n.outputs.iter().any(|p| p.id() == port) + }) + } + + /// Whether an edge with the same endpoints already exists. + fn edge_exists(&self, from: PortId, to: PortId) -> bool { + self.edges + .iter() + .any(|e| e.from_port() == from && e.to_port() == to) + } + + /// Whether there is a directed path from node `from` to node `to` + /// following the existing edges (DFS). `from == to` counts as a path. + fn reaches(&self, from: NodeId, to: NodeId) -> bool { + if from == to { + return true; + } + let mut visited = std::collections::HashSet::new(); + let mut stack = vec![from]; + while let Some(current) = stack.pop() { + if !visited.insert(current) { + continue; + } + for edge in &self.edges { + if edge.from_node() == current { + let next = edge.to_node(); + if next == to { + return true; + } + stack.push(next); + } + } + } + false + } + + /// Recomputed every port's `connected` flag from the current edge list. + fn refresh_port_connectivity(&mut self) { + for node in &mut self.nodes { + for port in node.inputs.iter_mut().chain(node.outputs.iter_mut()) { + port.connected = self + .edges + .iter() + .any(|e| e.from_port() == port.id || e.to_port() == port.id); + } + } + } + /// Sets the row height of every timeline track (demo toolbar). pub fn set_track_height(&mut self, height: Pixels, cx: &mut Context) { for track in &mut self.tracks { @@ -649,6 +1046,44 @@ impl EffectStackDataSource for MockEngine { } } +impl NodeGraphDataSource for MockEngine { + type Node = MockNode; + type Edge = MockEdge; + + fn nodes(&self) -> Vec { + self.nodes.clone() + } + + fn edges(&self) -> Vec { + self.edges.clone() + } + + fn can_connect(&self, from: PortId, to: PortId) -> bool { + let (Some(from_node), Some(to_node)) = (self.node_with_port(from), self.node_with_port(to)) + else { + return false; + }; + if from_node.id() == to_node.id() { + return false; + } + let (Some(from_port), Some(to_port)) = (self.port(from), self.port(to)) else { + return false; + }; + if from_port.kind() != PortKind::Output || to_port.kind() != PortKind::Input { + return false; + } + if from_port.data_type() != to_port.data_type() { + return false; + } + if self.edge_exists(from, to) { + return false; + } + // Connecting from_node → to_node would create a cycle iff there is + // already a path from to_node back to from_node. + !self.reaches(to_node.id(), from_node.id()) + } +} + impl ProjectDataSource for MockEngine { fn roots(&self) -> Vec { vec![ @@ -698,6 +1133,87 @@ impl MockEngine { pub fn clock_frame(&self, monitor: Monitor, cx: &App) -> Frame { self.clock(monitor).read(cx).transport.frame() } + + /// The synthetic CPU test frame for `monitor`, cached per playhead frame so + /// a paused viewer never regenerates its picture. This is the frame the + /// source/program viewers display through [`ViewerWidget::set_cpu_frame`], + /// proving the CPU-frame path end to end before the real engine lands. + pub fn cpu_frame(&self, monitor: Monitor, cx: &App) -> Arc { + let frame = self.clock_frame(monitor, cx); + let mut cache = self.cpu_frame_cache.lock().unwrap(); + if let Some((cached_frame, image)) = cache.get(&monitor) { + if *cached_frame == frame.0 { + return image.clone(); + } + } + let image = Arc::new(self.synthetic_frame(frame)); + cache.insert(monitor, (frame.0, image.clone())); + image + } + + /// Generates a synthetic test frame: SMPTE-style color bars with a white + /// sweep whose x position follows `frame`, so playback is visibly moving. + /// + /// Samples are computed as F32 RGBA (mirroring the real engine's pixel + /// pipeline) and downconverted to BGRA8 for the viewer's CPU-frame path. + /// The picture is rendered at a small proxy size ([`SYNTH_FRAME_WIDTH`] × + /// [`SYNTH_FRAME_HEIGHT`]); the real engine delivers full resolution. + fn synthetic_frame(&self, frame: Frame) -> RenderImage { + let width = SYNTH_FRAME_WIDTH; + let height = SYNTH_FRAME_HEIGHT; + + // F32 RGBA samples, then quantized to BGRA8 for the sprite atlas. + let mut samples = vec![0.0f32; (width * height * 4) as usize]; + // SMPTE bars: 75% white, yellow, cyan, green, magenta, red, blue. + let bars: [(f32, f32, f32); 7] = [ + (1.0, 1.0, 1.0), + (1.0, 1.0, 0.0), + (0.0, 1.0, 1.0), + (0.0, 1.0, 0.0), + (1.0, 0.0, 1.0), + (1.0, 0.0, 0.0), + (0.0, 0.0, 1.0), + ]; + // Bottom strip: blue, magenta, 75% white, black. + let strip: [(f32, f32, f32); 4] = [ + (0.0, 0.0, 1.0), + (1.0, 0.0, 1.0), + (0.75, 0.75, 0.75), + (0.0, 0.0, 0.0), + ]; + // The sweep moves 6 px per frame and wraps around the width, so + // transport playback shows up as motion across the picture. + let sweep = (frame.0 as f32 * 6.0) % width as f32; + let bars_top = height as f32 * 0.66; + + for y in 0..height { + for x in 0..width { + let in_sweep = (x as f32 - sweep).abs() < 6.0; + let color = if in_sweep { + (1.0, 1.0, 1.0) + } else if (y as f32) < bars_top { + bars[((x as f32 / width as f32) * 7.0) as usize] + } else { + strip[((x as f32 / width as f32) * 4.0) as usize] + }; + let i = ((y * width + x) * 4) as usize; + samples[i] = color.0; + samples[i + 1] = color.1; + samples[i + 2] = color.2; + samples[i + 3] = 1.0; + } + } + + let mut bytes = Vec::with_capacity((width * height * 4) as usize); + for i in (0..samples.len()).step_by(4) { + bytes.push((samples[i + 2] * 255.0) as u8); // B + bytes.push((samples[i + 1] * 255.0) as u8); // G + bytes.push((samples[i] * 255.0) as u8); // R + bytes.push((samples[i + 3] * 255.0) as u8); // A + } + let buffer = image::RgbaImage::from_raw(width, height, bytes).expect("synthetic frame"); + RenderImage::new(smallvec::SmallVec::from_elem(image::Frame::new(buffer), 1)) + } } #[cfg(test)] @@ -799,4 +1315,183 @@ mod tests { assert_eq!(before, after); }); } + + #[gpui::test] + async fn demo_graph_has_six_nodes_and_five_edges(cx: &mut TestAppContext) { + cx.update(|app| { + let engine = demo_engine(app); + let engine = engine.read(app); + let nodes = engine.nodes(); + let edges = engine.edges(); + + assert_eq!(nodes.len(), 6, "media, transform, blur, mixer, viewer"); + assert_eq!(edges.len(), 5); + + // The chain ends at the viewer node, fed by the mixer. + let viewer = nodes + .iter() + .find(|n| n.title() == "输出") + .expect("viewer node"); + assert_eq!(viewer.inputs().len(), 1); + assert!(viewer.outputs().is_empty()); + + // Every edge endpoint references an existing port, and every port + // connectivity flag matches the edge list. + for edge in &edges { + assert!( + nodes.iter().any(|n| n.id() == edge.from_node()), + "edge {} from-node exists", + edge.id().0 + ); + assert!( + nodes.iter().any(|n| n.id() == edge.to_node()), + "edge {} to-node exists", + edge.id().0 + ); + } + for node in nodes { + for port in node.inputs().into_iter().chain(node.outputs()) { + let expected = engine + .edges() + .iter() + .any(|e| e.from_port() == port.id() || e.to_port() == port.id()); + assert_eq!(port.is_connected(), expected, "port {}", port.id().0); + } + } + }); + } + + #[gpui::test] + async fn can_connect_enforces_direction_type_duplicates_and_cycles( + cx: &mut TestAppContext, + ) { + cx.update(|app| { + let engine = demo_engine(app); + let engine = engine.read(app); + + // A valid, still-free connection: Clip1.video → Transform.in (the + // transform already takes the clip-0 path, so this would be the + // second input). + assert!(engine.can_connect(PortId(3), PortId(20))); + // The existing connection is not offered again. + assert!(!engine.can_connect(PortId(21), PortId(40)), "duplicate edge"); + // Input → output is rejected (wrong direction). + assert!(!engine.can_connect(PortId(20), PortId(1)), "wrong direction"); + // A port cannot connect to itself. + assert!(!engine.can_connect(PortId(42), PortId(40)), "self connection"); + // Type mismatch: the clip's audio output is not a video signal. + assert!( + !engine.can_connect(PortId(4), PortId(20)), + "audio cannot feed a video input" + ); + // Unknown ports are rejected. + assert!(!engine.can_connect(PortId(999), PortId(20))); + assert!(!engine.can_connect(PortId(1), PortId(999))); + + // Cycle rule: the graph flows left-to-right (Clip → Transform → + // Mixer → Viewer), so no connection can close a loop — but the + // reachability helper behind the rule is exercised directly. + assert!(engine.reaches(NodeId(0), NodeId(5)), "main chain path"); + assert!(!engine.reaches(NodeId(5), NodeId(0)), "no backward path"); + assert!(engine.reaches(NodeId(4), NodeId(4))); + }); + } + + #[gpui::test] + async fn node_edits_apply_to_the_model(cx: &mut TestAppContext) { + cx.update(|app| { + let engine = demo_engine(app); + // Move the viewer node. + engine.update(app, |engine, cx| { + engine.apply_node_graph_event( + &NodeGraphEvent::NodeMoveRequested { + nodes: vec![NodeId(5)], + delta: point(px(100.0), px(-20.0)), + }, + cx, + ); + }); + let moved = engine.read(app).node(NodeId(5)).expect("viewer node"); + assert_eq!(moved.position(), point(px(980.0), px(110.0))); + + // Connect the B-roll clip's video to the transform's unused mask + // input, then disconnect the transform → mixer edge. + engine.update(app, |engine, cx| { + engine.apply_node_graph_event( + &NodeGraphEvent::ConnectionRequested { + from: PortId(3), + to: PortId(22), + }, + cx, + ); + }); + let engine_read = engine.read(app); + assert_eq!(engine_read.edges().len(), 6); + assert!(engine_read.port(PortId(22)).is_some_and(|p| p.is_connected())); + let edges = engine_read.edges(); + let extra = edges + .iter() + .find(|e| e.to_port() == PortId(22)) + .expect("the new connection"); + + engine.update(app, |engine, cx| { + engine.apply_node_graph_event( + &NodeGraphEvent::DisconnectionRequested { edge: extra.id() }, + cx, + ); + }); + assert_eq!(engine.read(app).edges().len(), 5); + assert!( + !engine.read(app).port(PortId(22)).is_some_and(|p| p.is_connected()), + "mask input freed again" + ); + + // Deleting the blur node takes its incident edges with it. + engine.update(app, |engine, cx| { + engine.apply_node_graph_event( + &NodeGraphEvent::DeleteRequested { + nodes: vec![NodeId(3)], + edges: vec![], + }, + cx, + ); + }); + let engine_read = engine.read(app); + assert_eq!(engine_read.nodes().len(), 5); + assert!( + !engine_read.edges().iter().any(|e| e.to_node() == NodeId(3) + || e.from_node() == NodeId(3)), + "edges incident to the deleted node are removed" + ); + }); + } + + #[gpui::test] + async fn cpu_frame_is_cached_per_playhead_and_advances(cx: &mut TestAppContext) { + cx.update(|app| { + let engine = demo_engine(app); + + // Same playhead → same cached image (Arc identity), so a paused + // viewer never regenerates its picture. + let a = engine.read(app).cpu_frame(Monitor::Program, app); + let b = engine.read(app).cpu_frame(Monitor::Program, app); + assert!(Arc::ptr_eq(&a, &b), "paused frame must be cached"); + + // Advancing the playhead produces a different image: the sweep + // moved, so playback is visible. + engine.update(app, |engine, cx| { + engine.step(Monitor::Program, 25, cx); + }); + let c = engine.read(app).cpu_frame(Monitor::Program, app); + assert!(!Arc::ptr_eq(&a, &c), "a new playhead frame regenerates"); + + // The frame has the documented proxy size and opaque BGRA8 bytes. + let size = c.size(0); + assert_eq!(size.width, SYNTH_FRAME_WIDTH.into()); + assert_eq!(size.height, SYNTH_FRAME_HEIGHT.into()); + let bytes = c.as_bytes(0).expect("single frame"); + assert_eq!(bytes.len(), (SYNTH_FRAME_WIDTH * SYNTH_FRAME_HEIGHT * 4) as usize); + assert!(bytes.chunks_exact(4).all(|px| px[3] == 255), "opaque alpha"); + }); + } } diff --git a/app/rust/src/panels/mod.rs b/app/rust/src/panels/mod.rs index 6c50b3fd5..b09438b9a 100644 --- a/app/rust/src/panels/mod.rs +++ b/app/rust/src/panels/mod.rs @@ -43,7 +43,7 @@ pub mod ids { pub const SOURCE_VIEWER: PanelId = PanelId::new(2); /// The program viewer (序列查看器). pub const PROGRAM_VIEWER: PanelId = PanelId::new(3); - /// The node editor placeholder (节点编辑器). + /// The node editor (节点编辑器). pub const NODE_EDITOR: PanelId = PanelId::new(4); /// The inspector / effect stack (检查器·效果栈). pub const INSPECTOR: PanelId = PanelId::new(5); diff --git a/app/rust/src/panels/node_editor.rs b/app/rust/src/panels/node_editor.rs index 06178c76e..9c36d291f 100644 --- a/app/rust/src/panels/node_editor.rs +++ b/app/rust/src/panels/node_editor.rs @@ -14,35 +14,139 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -//! The node editor panel (节点编辑器): a placeholder tab sharing the program -//! viewer's dock group. +//! The node editor panel (节点编辑器): the real `gpui::node_graph` canvas over +//! the engine's mock graph, with the design's zoom controls (+ / − / 适配). //! -//! The design puts the node editor in the center, switchable with the program -//! viewer. The real `gpui::node_graph` widget exists in the gpui submodule -//! but is not wired up yet — this panel is a placeholder surface with the -//! zoom controls the design specifies (+ / − / fit). +//! The graph is a full [`NodeGraphView`] fed by the [`MockEngine`]'s +//! [`NodeGraphDataSource`] implementation. Every gesture the view emits +//! (move, connect, disconnect, delete, selection) is forwarded to the engine +//! as a request; the engine applies it to its model and notifies, so the +//! view re-reads on the next frame. The toolbar buttons drive the viewport +//! directly: zoom in/out at the canvas center, or fit the whole graph. use gpui::colors::DefaultColors; use gpui::dock::{DockPanel, PanelEvent}; +use gpui::node_graph::{ + MAX_ZOOM, MIN_ZOOM, NodeData, NodeElement, NodeGraphDataSource, NodeGraphEvent, NodeGraphView, + NodeVisualState, +}; use gpui::{ - div, prelude::*, AnyElement, App, ClickEvent, Context, EventEmitter, Render, SharedString, - Window, + div, point, prelude::*, px, AnyElement, App, Bounds, ClickEvent, Context, Entity, + EventEmitter, Pixels, Render, SharedString, Window, }; +use crate::oakui::MockEngine; use crate::panels::ids::NODE_EDITOR; -/// The node editor placeholder panel. -pub struct NodeEditorPanel; +/// The node editor panel. +pub struct NodeEditorPanel { + /// The node-graph canvas over the engine's mock graph. + graph: Entity>, + engine: Entity, + /// Whether the initial fit-to-window has been applied (the canvas size is + /// only known after the first layout). + fitted: bool, +} impl NodeEditorPanel { - /// Creates the placeholder. - pub fn new(_window: &mut Window, _cx: &mut Context) -> Self { - Self + /// Builds the graph canvas over `engine` and routes its edit requests back + /// to the engine. + pub fn new( + engine: Entity, + window: &mut Window, + cx: &mut Context, + ) -> Self { + let graph = cx.new(|cx| NodeGraphView::new(engine.clone(), window, cx)); + // The "edits are requests" loop: every graph gesture goes to the + // engine, which applies it to its model and notifies. + cx.subscribe(&graph, |this, _graph, event: &NodeGraphEvent, cx| { + this.engine + .update(cx, |engine, cx| engine.apply_node_graph_event(event, cx)); + }) + .detach(); + + Self { + graph, + engine, + fitted: false, + } + } + + /// The union of every node's bounds in graph space, if the graph is + /// non-empty. + fn graph_bounds(&self, cx: &App) -> Option> { + let nodes = self.engine.read(cx).nodes(); + if nodes.is_empty() { + return None; + } + let mut min_x = f32::MAX; + let mut min_y = f32::MAX; + let mut max_x = f32::MIN; + let mut max_y = f32::MIN; + for node in &nodes { + let element = NodeElement::from_node(node, NodeVisualState::default()); + let position = node.position(); + let width = gpui::node_graph::DEFAULT_NODE_WIDTH; + let height = element.height(); + let (x, y) = (f32::from(position.x), f32::from(position.y)); + min_x = min_x.min(x); + min_y = min_y.min(y); + max_x = max_x.max(x + f32::from(width)); + max_y = max_y.max(y + f32::from(height)); + } + Some(Bounds::from_corners( + point(px(min_x), px(min_y)), + point(px(max_x), px(max_y)), + )) + } + + /// The canvas size to fit against: the graph view's own painted size once + /// known, otherwise the window (before the first layout). + fn fit_viewport(&self, window: &Window, cx: &App) -> gpui::Size { + let viewport = self.graph.read(cx).viewport_size(); + if viewport.width > px(0.0) && viewport.height > px(0.0) { + viewport + } else { + window.viewport_size() + } + } + + /// Fits the whole graph into the canvas (the 适配 button). + fn fit_graph(&mut self, window: &mut Window, cx: &mut Context) { + let Some(rect) = self.graph_bounds(cx) else { + return; + }; + let viewport = self.fit_viewport(window, cx); + self.graph.update(cx, |graph, cx| { + graph.state_mut().fit_to_rect(rect, viewport); + cx.notify(); + }); + } + + /// Zooms the canvas by `factor` at its center (`+` / `−` buttons). + fn zoom(&mut self, factor: f32, window: &mut Window, cx: &mut Context) { + let viewport = self.fit_viewport(window, cx); + let anchor = point(viewport.width * 0.5, viewport.height * 0.5); + self.graph.update(cx, |graph, cx| { + graph.state_mut().zoom_at(anchor, factor); + cx.notify(); + }); } } impl Render for NodeEditorPanel { - fn render(&mut self, _window: &mut Window, cx: &mut Context) -> impl IntoElement { + fn render(&mut self, window: &mut Window, cx: &mut Context) -> impl IntoElement { + // Fit the graph once the canvas size is known (first layout). Before + // that the viewport is zero-sized, so ask for another frame instead. + if !self.fitted { + if self.graph.read(cx).viewport_size() != Default::default() { + self.fitted = true; + self.fit_graph(window, cx); + } else { + cx.notify(); + } + } + let colors = cx.default_colors().clone(); div() .size_full() @@ -57,43 +161,46 @@ impl Render for NodeEditorPanel { .py_1() .border_b_1() .border_color(colors.border) - .child(zoom_button( - cx, - "node-zoom-in", - "+", - crate::i18n::tr("node.zoom_in"), - )) - .child(zoom_button( - cx, - "node-zoom-out", - "−", - crate::i18n::tr("node.zoom_out"), - )) + .child(zoom_button(cx, "node-zoom-in", "+", |this, window, cx| { + this.zoom(1.25, window, cx); + })) + .child(zoom_button(cx, "node-zoom-out", "−", |this, window, cx| { + this.zoom(1.0 / 1.25, window, cx); + })) .child(zoom_button( cx, "node-zoom-fit", crate::i18n::tr("node.fit"), - crate::i18n::tr("node.fit_window"), - )), + |this, window, cx| this.fit_graph(window, cx), + )) + .child(div().flex_1()) + .child( + div() + .text_color(colors.disabled) + .child(format!( + "{}% · {}–{}", + (self.graph.read(cx).state().zoom() * 100.0).round(), + MIN_ZOOM, + MAX_ZOOM, + )), + ), ) .child( div() + .debug_selector(|| "node-editor-canvas".into()) .flex_1() - .flex() - .items_center() - .justify_center() - .text_color(colors.disabled) - .child(crate::i18n::tr("node.placeholder")), + .min_h_0() + .child(self.graph.clone()), ) } } -/// A small toolbar button (the design's `+`/`−`/`适配` controls). +/// A small toolbar button driving the graph viewport. fn zoom_button( cx: &mut Context, id: &'static str, - label: &'static str, - title: &'static str, + label: impl IntoElement, + action: impl Fn(&mut NodeEditorPanel, &mut Window, &mut Context) + 'static, ) -> impl gpui::IntoElement { let colors = cx.default_colors().clone(); let container = colors.container; @@ -107,11 +214,9 @@ fn zoom_button( .text_color(colors.text) .cursor_pointer() .hover(move |style| style.bg(container)) - .on_click( - cx.listener(move |_this, _event: &ClickEvent, _window, _cx| { - println!("[node editor] {title} (placeholder)"); - }), - ) + .on_click(cx.listener(move |this, _event: &ClickEvent, window, cx| { + action(this, window, cx); + })) .child(label) } @@ -132,3 +237,55 @@ impl DockPanel for NodeEditorPanel { .into_any_element() } } + +#[cfg(test)] +mod tests { + use super::*; + use gpui::{TestAppContext, VisualTestContext, size}; + + /// Builds the panel in a window and returns a `VisualTestContext` for + /// bounds assertions. + fn panel_window( + cx: &mut TestAppContext, + ) -> (&'static mut VisualTestContext, Entity) { + cx.update(|cx| cx.init_colors()); + let window = cx.open_window(size(px(640.0), px(480.0)), |window, cx| { + let engine = cx.new(|cx| crate::oakui::MockEngine::demo(cx)); + NodeEditorPanel::new(engine, window, cx) + }); + cx.run_until_parked(); + // The graph canvas reports its size only after the first paint, so the + // initial fit applies on the following frame: draw a few more. + for _ in 0..3 { + cx.update_window(window.into(), |_root, window, app| { + let _ = window.draw(app); + }) + .expect("window still open"); + cx.run_until_parked(); + } + let panel = window.root(cx).expect("node editor panel root"); + let cx = VisualTestContext::from_window(window.into(), cx).into_mut(); + (cx, panel) + } + + /// The panel lays out a graph canvas below the zoom toolbar, and the + /// initial fit centers the graph so every demo node is on screen. + #[gpui::test] + async fn canvas_fills_the_panel_below_the_toolbar(cx: &mut TestAppContext) { + let (cx, panel) = panel_window(cx); + + let canvas = cx + .debug_bounds("node-editor-canvas") + .expect("graph canvas rendered"); + assert!(canvas.size.width > px(0.0)); + assert!(canvas.size.height > px(0.0)); + + // The initial fit moved the viewport off the default origin, so the + // graph is framed rather than clipped at the corner. + let state = cx.read(|app| { + panel.read(app).graph.read(app).state().clone() + }); + assert_ne!(state.offset(), gpui::node_graph::GraphViewState::new().offset()); + assert!(state.zoom() > 0.0); + } +} diff --git a/app/rust/src/panels/program_viewer.rs b/app/rust/src/panels/program_viewer.rs index d0acfe425..92a41839a 100644 --- a/app/rust/src/panels/program_viewer.rs +++ b/app/rust/src/panels/program_viewer.rs @@ -40,6 +40,9 @@ pub struct ProgramViewerPanel { viewer: Entity>, meter: Entity>, engine: Entity, + /// The last CPU frame handed to the viewer (compared by `Arc` identity so + /// a paused playhead does not re-upload the picture every frame). + last_cpu_frame: Option>, } impl ProgramViewerPanel { @@ -69,12 +72,28 @@ impl ProgramViewerPanel { viewer, meter, engine, + last_cpu_frame: None, + } + } + + /// Pushes the engine's synthetic test frame into the viewer, but only when + /// it actually changed (the engine caches one image per playhead frame). + fn sync_frame(&mut self, cx: &mut Context) { + let frame = self.engine.read(cx).cpu_frame(Monitor::Program, cx); + if self.last_cpu_frame.as_ref().is_none_or(|last| !std::sync::Arc::ptr_eq(last, &frame)) + { + self.last_cpu_frame = Some(frame.clone()); + let frame = frame.clone(); + self.viewer + .update(cx, |viewer, cx| viewer.set_cpu_frame(Some(frame), cx)); } } } impl Render for ProgramViewerPanel { fn render(&mut self, _window: &mut Window, cx: &mut Context) -> impl IntoElement { + self.sync_frame(cx); + let colors = cx.default_colors().clone(); let format = self .engine diff --git a/app/rust/src/panels/source_viewer.rs b/app/rust/src/panels/source_viewer.rs index 380710a44..a27ccfd3b 100644 --- a/app/rust/src/panels/source_viewer.rs +++ b/app/rust/src/panels/source_viewer.rs @@ -20,7 +20,8 @@ use gpui::colors::DefaultColors; use gpui::dock::{DockPanel, PanelEvent}; use gpui::{ - div, prelude::*, AnyElement, App, Context, Entity, EventEmitter, Render, SharedString, Window, + div, prelude::*, AnyElement, App, Context, Entity, EventEmitter, Render, SharedString, + Window, }; use gpui_widgets::viewer::{ViewerEvent, ViewerWidget}; @@ -33,6 +34,9 @@ use crate::panels::ids::SOURCE_VIEWER; pub struct SourceViewerPanel { viewer: Entity>, engine: Entity, + /// The last CPU frame handed to the viewer (compared by `Arc` identity so + /// a paused playhead does not re-upload the picture every frame). + last_cpu_frame: Option>, } impl SourceViewerPanel { @@ -56,12 +60,31 @@ impl SourceViewerPanel { }) .detach(); - Self { viewer, engine } + Self { + viewer, + engine, + last_cpu_frame: None, + } + } + + /// Pushes the engine's synthetic test frame into the viewer, but only when + /// it actually changed (the engine caches one image per playhead frame). + fn sync_frame(&mut self, cx: &mut Context) { + let frame = self.engine.read(cx).cpu_frame(Monitor::Source, cx); + if self.last_cpu_frame.as_ref().is_none_or(|last| !std::sync::Arc::ptr_eq(last, &frame)) + { + self.last_cpu_frame = Some(frame.clone()); + let frame = frame.clone(); + self.viewer + .update(cx, |viewer, cx| viewer.set_cpu_frame(Some(frame), cx)); + } } } impl Render for SourceViewerPanel { fn render(&mut self, _window: &mut Window, cx: &mut Context) -> impl IntoElement { + self.sync_frame(cx); + let colors = cx.default_colors().clone(); let format = self .engine diff --git a/cli/rust/Cargo.lock b/cli/rust/Cargo.lock index 1a42e595d..4af6b8780 100644 --- a/cli/rust/Cargo.lock +++ b/cli/rust/Cargo.lock @@ -2,6 +2,30 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "adler2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" + +[[package]] +name = "aho-corasick" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c982642fa9e8606056828ee9a8505737230110bb1099153c79efe865c59d12ba" +dependencies = [ + "memchr", +] + +[[package]] +name = "android_system_properties" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae221649c9976a6f6c56ae1facf410f3ddb33cc661c4b7b61020a912d4237fbc" +dependencies = [ + "libc", +] + [[package]] name = "anstream" version = "1.0.0" @@ -52,6 +76,155 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "arrayvec" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3fb67a6e08acf24fdeccbac2cb6ac4305825bd1f117462e0e6f2f193345ad56" + +[[package]] +name = "ash" +version = "0.38.0+1.3.281" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bb44936d800fea8f016d7f2311c6a4f97aebd5dc86f09906139ec848cf3a46f" +dependencies = [ + "libloading", +] + +[[package]] +name = "autocfg" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" + +[[package]] +name = "bindgen" +version = "0.72.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895" +dependencies = [ + "bitflags 2.13.1", + "cexpr", + "clang-sys", + "itertools", + "proc-macro2", + "quote", + "regex", + "rustc-hash 2.1.3", + "shlex 1.3.0", + "syn 2.0.119", +] + +[[package]] +name = "bit-set" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da" +dependencies = [ + "serde_core", +] + +[[package]] +name = "block" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" + +[[package]] +name = "bumpalo" +version = "3.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" + +[[package]] +name = "bytemuck" +version = "1.25.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95832e849adfb21180ccb6826a99da14e5d266ae5c2e668e1602cf234f153797" +dependencies = [ + "bytemuck_derive", +] + +[[package]] +name = "bytemuck_derive" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc0e56a716f1e132ff6bf4bdac1c944a3fcdc1cae65f70a4a2a1ac3b401d2d1f" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.3", +] + +[[package]] +name = "byteorder-lite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" + +[[package]] +name = "cc" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d262e149917187838d5b42777c8253bcb64500067342904e7d429499a6f277e" +dependencies = [ + "find-msvc-tools", + "shlex 2.0.1", +] + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "cfg_aliases" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f079e83a288787bcd14a6aea84cee5c87a67c5a3e660c30f557a3d24761b3527" + +[[package]] +name = "clang-sys" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "157a8ba7b480713b56f4c09fd13fc3e0a22a5dfab8097ba61cbc5feef950788a" +dependencies = [ + "glob", + "libc", + "libloading", +] + [[package]] name = "clap" version = "4.6.6" @@ -83,7 +256,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn", + "syn 3.0.3", ] [[package]] @@ -92,35 +265,742 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" +[[package]] +name = "cmake" +version = "0.1.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0f78a02292a74a88ac736019ab962ece0bc380e3f977bf72e376c5d78ff0678" +dependencies = [ + "cc", +] + +[[package]] +name = "codespan-reporting" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe6d2e5af09e8c8ad56c969f2157a3d4238cebc7c55f0a517728c38f7b200f81" +dependencies = [ + "serde", + "termcolor", + "unicode-width", +] + [[package]] name = "colorchoice" version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "core-graphics-types" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crunchy" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" + +[[package]] +name = "document-features" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4b8a88685455ed29a21542a33abd9cb6510b6b129abadabdcef0f4c55bc8f61" +dependencies = [ + "litrs", +] + +[[package]] +name = "either" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e5e8f6c15a24b9a3ee5efec809ccd006d3b30e8b3bb63c39af737c7f87daa1d" + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "fax" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "caf1079563223d5d59d83c85886a56e586cfd5c1a26292e971a0fa266531ac5a" + +[[package]] +name = "ffmpeg-next" +version = "9.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6380599799e175191eb7ffe82c97f36a2a90a36cbc54c738a903e5287d7f516a" +dependencies = [ + "bitflags 2.13.1", + "ffmpeg-sys-next", + "libc", +] + +[[package]] +name = "ffmpeg-sys-next" +version = "9.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b939bf79dd5949412a4b81cfe21a07f48ea21b47fcbb5f57816c8c2de5ae30b" +dependencies = [ + "bindgen", + "cc", + "libc", + "num_cpus", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "find-msvc-tools" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b73573e6edcd2af0cdf47bd6cb58f0b3839491263c314eaad1ccf24430e1de" + +[[package]] +name = "flate2" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + +[[package]] +name = "foreign-types" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" +dependencies = [ + "foreign-types-macros", + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-macros" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea5190182e6915eb873ddbc16e23b711b6eb1f9c00a0d0a3a91b5f6228475225" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.3", +] + +[[package]] +name = "foreign-types-shared" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" + +[[package]] +name = "futures-core" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2cd50c473c80f6d7c3670a752354b8e569b1a7cbfdc0419ec88e5edad85e0dc7" + +[[package]] +name = "futures-task" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b231ed28831efb4a61a08580c4bc233ec56bc009f4cd8f52da2c3cb97df0c109" + +[[package]] +name = "futures-util" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a77a90a256fce34da66415271e30f94ee91c57b04b8a2c042d9cf3220179deaa" +dependencies = [ + "futures-core", + "futures-task", + "pin-project-lite", + "slab", +] + +[[package]] +name = "gl_generator" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a95dfc23a2b4a9a2f5ab41d194f8bfda3cabec42af4e39f08c339eb2a0c124d" +dependencies = [ + "khronos_api", + "log", + "xml-rs", +] + +[[package]] +name = "glob" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4eba85ea1d0a966a983acd07deee566e67395d2d96b6fb39e62b5a833f1eb0b" + +[[package]] +name = "glow" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5e5ea60d70410161c8bf5da3fdfeaa1c72ed2c15f8bbb9d19fe3a4fad085f08" +dependencies = [ + "js-sys", + "slotmap", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "glutin_wgl_sys" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c4ee00b289aba7a9e5306d57c2d05499b2e5dc427f84ac708bd2c090212cf3e" +dependencies = [ + "gl_generator", +] + +[[package]] +name = "gpu-alloc" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45cf04b2726f02df5508c6de726acdc90cdf97ac771a9a0ffd8ba10a6e696bf9" +dependencies = [ + "bitflags 2.13.1", + "gpu-alloc-types", +] + +[[package]] +name = "gpu-alloc-types" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2bbed164dd10ed526c2e4fe3e721ca4a71c61730e5aafac6844b417b3227058" +dependencies = [ + "bitflags 2.13.1", +] + +[[package]] +name = "gpu-allocator" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c151a2a5ef800297b4e79efa4f4bec035c5f51d5ae587287c9b952bdf734cacd" +dependencies = [ + "log", + "presser", + "thiserror 1.0.69", + "windows", +] + +[[package]] +name = "gpu-descriptor" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b89c83349105e3732062a895becfc71a8f921bb71ecbbdd8ff99263e3b53a0ca" +dependencies = [ + "bitflags 2.13.1", + "gpu-descriptor-types", + "hashbrown 0.15.5", +] + +[[package]] +name = "gpu-descriptor-types" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdf242682df893b86f33a73828fb09ca4b2d3bb6cc95249707fc684d27484b91" +dependencies = [ + "bitflags 2.13.1", +] + +[[package]] +name = "half" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" +dependencies = [ + "cfg-if", + "crunchy", + "num-traits", + "zerocopy", +] + +[[package]] +name = "hashbrown" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +dependencies = [ + "foldhash", +] + +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" + [[package]] name = "heck" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +[[package]] +name = "hermit-abi" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" + +[[package]] +name = "hexf-parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" + +[[package]] +name = "image" +version = "0.25.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85ab80394333c02fe689eaf900ab500fbd0c2213da414687ebf995a65d5a6104" +dependencies = [ + "bytemuck", + "byteorder-lite", + "moxcms", + "num-traits", + "tiff", +] + +[[package]] +name = "indexmap" +version = "2.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" +dependencies = [ + "equivalent", + "hashbrown 0.17.1", +] + [[package]] name = "is_terminal_polyfill" version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + +[[package]] +name = "jni-sys" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41a652e1f9b6e0275df1f15b32661cf0d4b78d4d87ddec5e0c3c20f097433258" +dependencies = [ + "jni-sys 0.4.1", +] + +[[package]] +name = "jni-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6377a88cb3910bee9b0fa88d4f42e1d2da8e79915598f65fb0c7ee14c878af2" +dependencies = [ + "jni-sys-macros", +] + +[[package]] +name = "jni-sys-macros" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264" +dependencies = [ + "quote", + "syn 2.0.119", +] + +[[package]] +name = "js-sys" +version = "0.3.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e0c1080212aad755ea003d18543e8768dd432c48819efd73a7bf1e39b7a5a3a" +dependencies = [ + "cfg-if", + "futures-util", + "wasm-bindgen", +] + +[[package]] +name = "khronos-egl" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6aae1df220ece3c0ada96b8153459b67eebe9ae9212258bb0134ae60416fdf76" +dependencies = [ + "libc", + "libloading", + "pkg-config", +] + +[[package]] +name = "khronos_api" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" + +[[package]] +name = "libc" +version = "0.2.189" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2" + +[[package]] +name = "libloading" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" +dependencies = [ + "cfg-if", + "windows-link", +] + +[[package]] +name = "libm" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" + +[[package]] +name = "litrs" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092" + +[[package]] +name = "lock_api" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad" + +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] + +[[package]] +name = "memchr" +version = "2.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" + +[[package]] +name = "metal" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f569fb946490b5743ad69813cb19629130ce9374034abe31614a36402d18f99e" +dependencies = [ + "bitflags 2.13.1", + "block", + "core-graphics-types", + "foreign-types", + "log", + "objc", + "paste", +] + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +dependencies = [ + "adler2", + "simd-adler32", +] + +[[package]] +name = "moxcms" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb85c154ba489f01b25c0d36ae69a87e4a1c73a72631fc6c0eb6dde34a73e44b" +dependencies = [ + "num-traits", + "pxfm", +] + +[[package]] +name = "naga" +version = "25.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b977c445f26e49757f9aca3631c3b8b836942cb278d69a92e7b80d3b24da632" +dependencies = [ + "arrayvec", + "bit-set", + "bitflags 2.13.1", + "cfg_aliases", + "codespan-reporting", + "half", + "hashbrown 0.15.5", + "hexf-parse", + "indexmap", + "log", + "num-traits", + "once_cell", + "rustc-hash 1.1.0", + "spirv", + "strum", + "thiserror 2.0.20", + "unicode-ident", +] + +[[package]] +name = "ndk-sys" +version = "0.5.0+25.2.9519653" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c196769dd60fd4f363e11d948139556a344e79d451aeb2fa2fd040738ef7691" +dependencies = [ + "jni-sys 0.3.1", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "num_cpus" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b" +dependencies = [ + "hermit-abi", + "libc", +] + [[package]] name = "oak-cli" version = "0.1.0" dependencies = [ "clap", - "oakfacade", + "oakengine", ] [[package]] -name = "oakfacade" +name = "oakaudio" version = "0.1.0" +dependencies = [ + "oakcore-rs", +] + +[[package]] +name = "oakcodec" +version = "0.1.0" +dependencies = [ + "ffmpeg-next", + "oakcore-rs", +] + +[[package]] +name = "oakcommon" +version = "0.1.0" +dependencies = [ + "image", + "log", + "oakcore-rs", + "ocio-rs", + "quick-xml", +] + +[[package]] +name = "oakcore-rs" +version = "0.1.0" + +[[package]] +name = "oakengine" +version = "0.1.0" +dependencies = [ + "libc", + "oakaudio", + "oakcodec", + "oakcommon", + "oakcore-rs", + "oaknode", + "oakplugin", + "oakrender", + "oaktask", + "oaktimeline", + "oakundo", + "serde", + "serde_json", +] + +[[package]] +name = "oaknode" +version = "0.1.0" +dependencies = [ + "oakcore-rs", +] + +[[package]] +name = "oakotio" +version = "0.1.0" +dependencies = [ + "oakcore-rs", + "quick-xml", + "serde", + "serde_json", +] + +[[package]] +name = "oakplugin" +version = "0.1.0" +dependencies = [ + "cc", +] + +[[package]] +name = "oakrender" +version = "0.1.0" +dependencies = [ + "oakcore-rs", + "ocio-rs", + "wgpu", +] + +[[package]] +name = "oaktask" +version = "0.1.0" +dependencies = [ + "oakcore-rs", + "oakotio", +] + +[[package]] +name = "oaktimeline" +version = "0.1.0" +dependencies = [ + "oakcore-rs", +] + +[[package]] +name = "oakundo" +version = "0.1.0" +dependencies = [ + "oakcore-rs", +] + +[[package]] +name = "objc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" +dependencies = [ + "malloc_buf", +] + +[[package]] +name = "ocio-rs" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3492534019b59e29dba06014f907dd12824537ed4d293d4108c4bfc669de7fd" +dependencies = [ + "ocio-sys", + "thiserror 1.0.69", +] + +[[package]] +name = "ocio-sys" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e63251d72d848de5eda39d59cd6490260cf031738ebd518ea37d76b5aae614ec" +dependencies = [ + "cc", + "cmake", +] + +[[package]] +name = "once_cell" +version = "1.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "once_cell_polyfill" @@ -128,6 +1008,68 @@ version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" +[[package]] +name = "ordered-float" +version = "4.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bb71e1b3fa6ca1c61f383464aaf2bb0e2f8e772a1f01d486832464de363b951" +dependencies = [ + "num-traits", +] + +[[package]] +name = "parking_lot" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-link", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "pin-project-lite" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" + +[[package]] +name = "pkg-config" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" + +[[package]] +name = "portable-atomic" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d20d5497ef88037a52ff98267d066e7f11fcc5e99bbfbd58a42336193aacec3" + +[[package]] +name = "presser" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8cf8e6a8aa66ce33f63993ffc4ea4271eb5b0530a9002db8455ea6050c77bfa" + [[package]] name = "proc-macro2" version = "1.0.107" @@ -137,6 +1079,33 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "profiling" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d595e54a326bc53c1c197b32d295e14b169e3cfeaa8dc82b529f947fba6bcf5" + +[[package]] +name = "pxfm" +version = "0.1.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d55d956fa96f5ec02be2e13af0e20391a5aa83d6a074e3ad368959d0fab299ea" + +[[package]] +name = "quick-error" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" + +[[package]] +name = "quick-xml" +version = "0.41.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e660451e55124f798a69a5af3f49ccfbefbd41910eefd25caf2393e1f3473ec1" +dependencies = [ + "memchr", +] + [[package]] name = "quote" version = "1.0.47" @@ -146,12 +1115,223 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "range-alloc" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca45419789ae5a7899559e9512e58ca889e41f04f1f2445e9f4b290ceccd1d08" + +[[package]] +name = "raw-window-handle" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" + +[[package]] +name = "redox_syscall" +version = "0.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +dependencies = [ + "bitflags 2.13.1", +] + +[[package]] +name = "regex" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f020237b6c8eed93db2e2cb53c00c60a8e1bc73da7d073199a1180401450218d" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad8553b9b26413251cbf30e620595c7a41b3887f03da04579c0e6b0d6a06b4b2" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" + +[[package]] +name = "renderdoc-sys" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc-hash" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b1e7f9a428571be2dc5bc0505c13fb6bf936822b894ec87abf8a08a4e51742d" + +[[package]] +name = "rustversion" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "serde" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.3", +] + +[[package]] +name = "serde_json" +version = "1.0.151" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14" +dependencies = [ + "indexmap", + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "shlex" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" + +[[package]] +name = "simd-adler32" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a219298ac11a56ea9a6d2120044824d6f01aeb034955e7af7bc16858527deea" + +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + +[[package]] +name = "slotmap" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdd58c3c93c3d278ca835519292445cb4b0d4dc59ccfdf7ceadaab3f8aeb4038" +dependencies = [ + "version_check", +] + +[[package]] +name = "smallvec" +version = "1.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" + +[[package]] +name = "spirv" +version = "0.3.0+sdk-1.3.268.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eda41003dc44290527a59b13432d4a0379379fa074b70174882adfbdfd917844" +dependencies = [ + "bitflags 2.13.1", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + [[package]] name = "strsim" version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +[[package]] +name = "strum" +version = "0.26.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.119", +] + +[[package]] +name = "syn" +version = "2.0.119" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "syn" version = "3.0.3" @@ -163,24 +1343,396 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec86235f5fcc2a73650310756d2ac5b138a5780bbbdfae3eeccec992c435ba4f" +dependencies = [ + "thiserror-impl 2.0.20", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc04cd3e1236dd4a98afca4569f2deb3f120e5422a4023be2cb683f8486292af" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.3", +] + +[[package]] +name = "tiff" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b63feaf3343d35b6ca4d50483f94843803b0f51634937cc2ec519fc32232bc52" +dependencies = [ + "fax", + "flate2", + "half", + "quick-error", + "weezl", + "zune-jpeg", +] + [[package]] name = "unicode-ident" version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" +[[package]] +name = "unicode-width" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" + [[package]] name = "utf8parse" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "wasm-bindgen" +version = "0.2.127" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b70935747edd64d89de3efa29d73789b806c15798f8e7dca4d8ac356b50ce70" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b7777d5cc23d0e91404e53ce2d5e8ec7acae3026b16233dba62cd3246457950" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.127" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77775f8f3f7217702089053b94958f8f54061a3f663417df76e19cbdcca29bc1" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.127" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e11d33f857dc2fb11b8bc75aee111aa9cbeb12cd9f25efd3d4c2a3dd4e235284" +dependencies = [ + "bumpalo", + "proc-macro2", + "quote", + "syn 2.0.119", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.127" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef64dbcc55df09c7e5a46182d181c2cfa3e925f3da937ea764728b4bbb9dcbf" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "web-sys" +version = "0.3.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c435338968042f4f59a557f690a253676d47ce13ceb55d70100e7facf6620a30" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "weezl" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28ac98ddc8b9274cb41bb4d9d4d5c425b6020c50c46f25559911905610b4a88" + +[[package]] +name = "wgpu" +version = "25.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec8fb398f119472be4d80bc3647339f56eb63b2a331f6a3d16e25d8144197dd9" +dependencies = [ + "arrayvec", + "bitflags 2.13.1", + "cfg_aliases", + "document-features", + "hashbrown 0.15.5", + "js-sys", + "log", + "naga", + "parking_lot", + "portable-atomic", + "profiling", + "raw-window-handle", + "smallvec", + "static_assertions", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "wgpu-core", + "wgpu-hal", + "wgpu-types", +] + +[[package]] +name = "wgpu-core" +version = "25.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7b882196f8368511d613c6aeec80655160db6646aebddf8328879a88d54e500" +dependencies = [ + "arrayvec", + "bit-set", + "bit-vec", + "bitflags 2.13.1", + "cfg_aliases", + "document-features", + "hashbrown 0.15.5", + "indexmap", + "log", + "naga", + "once_cell", + "parking_lot", + "portable-atomic", + "profiling", + "raw-window-handle", + "rustc-hash 1.1.0", + "smallvec", + "thiserror 2.0.20", + "wgpu-core-deps-apple", + "wgpu-core-deps-emscripten", + "wgpu-core-deps-windows-linux-android", + "wgpu-hal", + "wgpu-types", +] + +[[package]] +name = "wgpu-core-deps-apple" +version = "25.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfd488b3239b6b7b185c3b045c39ca6bf8af34467a4c5de4e0b1a564135d093d" +dependencies = [ + "wgpu-hal", +] + +[[package]] +name = "wgpu-core-deps-emscripten" +version = "25.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f09ad7aceb3818e52539acc679f049d3475775586f3f4e311c30165cf2c00445" +dependencies = [ + "wgpu-hal", +] + +[[package]] +name = "wgpu-core-deps-windows-linux-android" +version = "25.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cba5fb5f7f9c98baa7c889d444f63ace25574833df56f5b817985f641af58e46" +dependencies = [ + "wgpu-hal", +] + +[[package]] +name = "wgpu-hal" +version = "25.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f968767fe4d3d33747bbd1473ccd55bf0f6451f55d733b5597e67b5deab4ad17" +dependencies = [ + "android_system_properties", + "arrayvec", + "ash", + "bit-set", + "bitflags 2.13.1", + "block", + "bytemuck", + "cfg-if", + "cfg_aliases", + "core-graphics-types", + "glow", + "glutin_wgl_sys", + "gpu-alloc", + "gpu-allocator", + "gpu-descriptor", + "hashbrown 0.15.5", + "js-sys", + "khronos-egl", + "libc", + "libloading", + "log", + "metal", + "naga", + "ndk-sys", + "objc", + "ordered-float", + "parking_lot", + "portable-atomic", + "profiling", + "range-alloc", + "raw-window-handle", + "renderdoc-sys", + "smallvec", + "thiserror 2.0.20", + "wasm-bindgen", + "web-sys", + "wgpu-types", + "windows", + "windows-core", +] + +[[package]] +name = "wgpu-types" +version = "25.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2aa49460c2a8ee8edba3fca54325540d904dd85b2e086ada762767e17d06e8bc" +dependencies = [ + "bitflags 2.13.1", + "bytemuck", + "js-sys", + "log", + "thiserror 2.0.20", + "web-sys", +] + +[[package]] +name = "winapi-util" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "windows" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" +dependencies = [ + "windows-core", + "windows-targets", +] + +[[package]] +name = "windows-core" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-result", + "windows-strings", + "windows-targets", +] + +[[package]] +name = "windows-implement" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "windows-interface" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + [[package]] name = "windows-link" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" +[[package]] +name = "windows-result" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-strings" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +dependencies = [ + "windows-result", + "windows-targets", +] + [[package]] name = "windows-sys" version = "0.61.2" @@ -189,3 +1741,114 @@ checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" dependencies = [ "windows-link", ] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "xml-rs" +version = "0.8.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e450f9b2ed1dff33c94c12589a87338689467b9c4f5d8a5710bd09a847d2c8a7" + +[[package]] +name = "zerocopy" +version = "0.8.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "556764e583adb45a9f8d413c2a147fa7e8d821e48e12b14fd560b607998b75eb" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2ab42fc20575779bd240faa45f94a74256f755c0fa9e89f0ede20d91d0cdfc1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "zmij" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" + +[[package]] +name = "zune-core" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d56377fd46368984a170bc5aac5567e52ca5da874caa60bea39fcbca78fb658b" + +[[package]] +name = "zune-jpeg" +version = "0.5.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27bc9d5b815bc103f142aa054f561d9187d191692ec7c2d1e2b4737f8dbd7296" +dependencies = [ + "zune-core", +] diff --git a/cli/rust/Cargo.toml b/cli/rust/Cargo.toml index 826e6bbec..c8e8d5804 100644 --- a/cli/rust/Cargo.toml +++ b/cli/rust/Cargo.toml @@ -37,7 +37,7 @@ clap = { version = "4", features = ["derive"] } # deferral (src/deferred.rs). The extern declarations in src/ffi.rs mirror # the engine headers verbatim and resolve against this rlib the moment a # family is wrapped -- no manifest change needed. -oakfacade = { path = "../../src/facade/rust" } +oakengine = { path = "../../src/engine/rust" } [profile.release] panic = "unwind" diff --git a/cli/rust/src/deferred.rs b/cli/rust/src/deferred.rs index 568c31a82..4f1b565bd 100644 --- a/cli/rust/src/deferred.rs +++ b/cli/rust/src/deferred.rs @@ -17,7 +17,7 @@ //! Facade-family availability, mirroring `src/facade/rust/src/deferred.rs`. //! //! Every `oak-cli` subcommand depends on one or more families of the -//! `oakengine_*` C ABI. Those families live in the `oakfacade` crate, and +//! `oakengine_*` C ABI. Those families live in the `oakengine` crate, and //! some of them are **deferred**: the facade does not wrap them yet, so the //! subcommands must report a clear "not yet available" error instead of //! calling into the facade (the calls would not link, and faking behavior @@ -47,7 +47,7 @@ pub struct DeferredFamily { pub const INIT: DeferredFamily = DeferredFamily { name: "init", headers: "init.h", - reason: "the facade shell (oakengine_init/shutdown) is not wrapped in oakfacade yet (its scope table covers only undo/common/audio/plugin)", + reason: "the facade shell (oakengine_init/shutdown) is not wrapped in oakengine yet (its scope table covers only undo/common/audio/plugin)", }; /// `project.h` + `footage.h` — the oaknode module family. @@ -80,13 +80,13 @@ pub const TIMELINE: DeferredFamily = DeferredFamily { pub const RENDER: DeferredFamily = DeferredFamily { name: "render", headers: "renderer.h", - reason: "deferred for session scope: the engine renderer.h family is not wrapped in oakfacade yet (no structural blocker)", + reason: "deferred for session scope: the engine renderer.h family is not wrapped in oakengine yet (no structural blocker)", }; /// `exporter.h` — export/encode family. /// /// Facade deferred.rs: exporter is a "genuinely facade-only area" (the -/// liboakengine assembly layer) with no files in the oakfacade crate. +/// liboakengine assembly layer) with no files in the oakengine crate. pub const EXPORT: DeferredFamily = DeferredFamily { name: "exporter", headers: "exporter.h", @@ -107,7 +107,7 @@ pub fn require(families: &[&DeferredFamily]) -> Result<(), String> { detail.push_str(&format!("\n - {} ({}): {}", f.name, f.headers, f.reason)); } Err(format!( - "not yet available in the Rust facade (oakfacade): these family(ies) are still deferred \ + "not yet available in the Rust facade (oakengine): these family(ies) are still deferred \ (see src/facade/rust/src/deferred.rs):{detail}" )) } @@ -126,7 +126,7 @@ mod tests { let err = require(&[&INIT]).unwrap_err(); assert!(err.contains("not yet available")); assert!(err.contains("init")); - assert!(err.contains("oakfacade")); + assert!(err.contains("oakengine")); } #[test] diff --git a/cli/rust/src/ffi.rs b/cli/rust/src/ffi.rs index 424331867..98353b2b7 100644 --- a/cli/rust/src/ffi.rs +++ b/cli/rust/src/ffi.rs @@ -28,15 +28,15 @@ //! - `engine/include/oakengine/exporter.h` (export options + render) //! //! All of these families are **deferred** in the Rust facade crate -//! (`oakfacade`, `src/facade/rust/src/deferred.rs`), so none of the symbols +//! (`oakengine`, `src/facade/rust/src/deferred.rs`), so none of the symbols //! below is referenced from this crate yet — the subcommands gate on //! [`crate::deferred`] and report "not yet available" instead of calling //! them. The declarations exist so that: //! //! 1. the exact contract the CLI expects is pinned in one place (types, //! signatures, string conventions, error codes), and -//! 2. when a family is wrapped by oakfacade, the call-through code in -//! `src/cmd/` resolves against the already-linked `oakfacade` rlib +//! 2. when a family is wrapped by oakengine, the call-through code in +//! `src/cmd/` resolves against the already-linked `oakengine` rlib //! without any manifest or signature churn. //! //! Nothing here is ever called today, so no symbol needs to exist in the diff --git a/cli/rust/src/main.rs b/cli/rust/src/main.rs index f7fdcf729..400f9d94f 100644 --- a/cli/rust/src/main.rs +++ b/cli/rust/src/main.rs @@ -30,7 +30,7 @@ //! 64 usage error. //! //! The facade families every subcommand depends on (init/project/timeline/ -//! render/footage/exporter) are still **deferred** in the `oakfacade` crate +//! render/footage/exporter) are still **deferred** in the `oakengine` crate //! (see `src/facade/rust/src/deferred.rs`), so each subcommand validates its //! arguments faithfully, then reports the deferral with its reason and exits //! with the C++-compatible code — never crashing, never faking output. diff --git a/cli/rust/tests/cli.rs b/cli/rust/tests/cli.rs index a29163911..677b725fc 100644 --- a/cli/rust/tests/cli.rs +++ b/cli/rust/tests/cli.rs @@ -71,7 +71,9 @@ fn info_on_a_fixture_reports_not_yet_available() { let (code, _stdout, stderr) = run(&["info", "tests/project_with_footage.ove"]); assert_eq!(code, 1); assert!(stderr.contains("error: info: not yet available"), "stderr: {stderr}"); - assert!(stderr.contains("oakfacade")); + // The crate was renamed oakfacade -> oakengine; the deferral reason + // names the current crate. + assert!(stderr.contains("oakengine")); } #[test] diff --git a/gpui b/gpui index 16ae7c42d..49e471ae6 160000 --- a/gpui +++ b/gpui @@ -1 +1 @@ -Subproject commit 16ae7c42dfebee0901aa27620bfc2e04dfbc1eb0 +Subproject commit 49e471ae64a1dc9e15237b14cc69c3dbcef48ca1 diff --git a/src/facade/rust/Cargo.lock b/src/engine/rust/Cargo.lock similarity index 99% rename from src/facade/rust/Cargo.lock rename to src/engine/rust/Cargo.lock index 1157f05c0..42ba8cd8e 100644 --- a/src/facade/rust/Cargo.lock +++ b/src/engine/rust/Cargo.lock @@ -784,13 +784,14 @@ name = "oakcore-rs" version = "0.1.0" [[package]] -name = "oakfacade" +name = "oakengine" version = "0.1.0" dependencies = [ "libc", "oakaudio", "oakcodec", "oakcommon", + "oakcore-rs", "oaknode", "oakplugin", "oakrender", diff --git a/src/engine/rust/Cargo.toml b/src/engine/rust/Cargo.toml new file mode 100644 index 000000000..52287ad60 --- /dev/null +++ b/src/engine/rust/Cargo.toml @@ -0,0 +1,70 @@ +[package] +name = "oakengine" +version = "0.1.0" +edition = "2021" +description = "Oak Video Editor facade: re-exports the frozen oakengine_* C ABI over the module C ABIs (Rust)" +license = "GPL-3.0-or-later" + +[lib] +crate-type = ["cdylib", "staticlib", "rlib"] + +[profile.release] +# FFI discipline: panics must be catchable at every exported entry. +panic = "unwind" + +[dependencies] +# NDJSON control-plane protocol for the worker session (src/worker.rs) and +# the shm error formatting in src/ipc.rs. +serde = { version = "1", features = ["derive"] } +serde_json = "1" +# POSIX shm_open/mmap/munmap/shm_unlink constants + syscalls for the +# shared-memory frame-slot transport (src/ipc.rs). +libc = "0.2" + +# Every module call crosses the module C ABI as an `extern "C"` import +# (src/bridge/). The module crates below are REAL dependencies so their +# `#[no_mangle]` exports are linked into the final `liboakengine` cdylib: +# the dylib then carries the module C ABIs itself (oakundo_*, oakcommon_*, +# oaktimeline_*, oakcodec_*, oakaudio_*, oakrender_*, oaktask_*, +# oakplugin_*, oaknode_*) alongside the facade's oakengine_* exports. +# +# The crates are linked WITHOUT their `test-stubs` features so the real +# exports ship. Cross-module calls that the modules resolve with +# dlsym(RTLD_DEFAULT) (oaknode, oakplugin, oakrender) now resolve against +# the sibling modules inside the same dylib; the remaining undefined +# imports are the C++ host-provided symbols (`oakcore_audioparams_*`, +# `oakcore_rational_*` from liboakcore, `fb_*` from ffmpeg_bridge), which +# build.rs leaves as runtime lookups for the host app. +# +# Tests link the same crates; the dev-dependencies below re-declare +# oakcommon/oakplugin WITH `test-stubs` so their in-crate C ABI mocks +# (the ffmpeg_bridge replacement and the oakrender dlsym stubs) are +# compiled into the test binaries (features union with the normal +# dependencies for test builds). +# +# NOTE (oaktimeline/oaktask): their `test-stubs` features are never used +# here — the in-crate mocks define `oakundo_command_init` etc., which +# would collide with the real oakundo rlib in one binary. Without +# test-stubs their real exports reference the oaknode/oakundo/oakcommon +# C ABI symbols as link-time externs, provided by the sibling crates in +# the same dylib (or by the dev-dependency rlibs in a test binary). +# +# rustc would normally prune rlibs that are only touched through +# `extern "C"` imports from the link; src/linkage.rs anchors every crate +# (and oakcore-rs) so the linker pulls their object files. +oakcore-rs = { path = "../../oakcore-rs" } +oakundo = { path = "../../undo/rust" } +oakcommon = { path = "../../common/rust" } +oaktimeline = { path = "../../timeline/rust" } +oakcodec = { path = "../../codec/rust" } +oakaudio = { path = "../../audio/rust" } +oakrender = { path = "../../render/rust" } +oaktask = { path = "../../task/rust" } +oakplugin = { path = "../../plugin/rust" } +oaknode = { path = "../../node/rust" } + +[dev-dependencies] +# Test-only feature union (see the comment above): tests keep the +# in-crate mocks these features compile. +oakcommon = { path = "../../common/rust", features = ["test-stubs"] } +oakplugin = { path = "../../plugin/rust", features = ["test-stubs"] } diff --git a/src/facade/rust/README.md b/src/engine/rust/README.md similarity index 84% rename from src/facade/rust/README.md rename to src/engine/rust/README.md index fbb906d3c..88774e5e3 100644 --- a/src/facade/rust/README.md +++ b/src/engine/rust/README.md @@ -42,9 +42,16 @@ tests/ The facade's regular dependencies are `serde`/`serde_json` (the worker's NDJSON control-plane protocol, `src/worker.rs`) and `libc` (POSIX `shm_open`/`mmap`/`munmap`/`shm_unlink` for `src/ipc.rs`). Every module -call still crosses the module C ABI as an `extern "C"` import -(`src/bridge/`), resolved at the final app link against the module shared -libraries. +call crosses the module C ABI as an `extern "C"` import (`src/bridge/`), +and the module crates themselves are real dependencies: [`linkage`](src/linkage.rs) +anchors them so their `#[no_mangle]` exports are linked into the +`liboakengine` cdylib — the dylib carries the module C ABIs (oakundo_*, +oakcommon_*, oaktimeline_*, oakcodec_*, oakaudio_*, oakrender_*, +oaktask_*, oakplugin_*, oaknode_*) next to the facade's oakengine_* +exports. The only remaining imports are the C++ host symbols +(`oakcore_*` from liboakcore, `fb_*` from ffmpeg_bridge), which +`build.rs` leaves as runtime lookups (macOS `-undefined dynamic_lookup`) +resolved from the host Oak process. ### Handle mapping @@ -89,16 +96,16 @@ control-plane message serializers remain unwrapped. ## Testing -`cargo test` links the module crates' rlibs (dev-dependencies) so the -facade's bridge imports resolve: +The module crates are real dependencies, so `cargo test` links the same +rlibs the cdylib embeds; the dev-dependencies re-declare +`oakcommon`/`oakplugin` with their `test-stubs` features so the test +binaries keep the in-crate mocks (ffmpeg_bridge stub / render mocks): -- `oakcommon`/`oakplugin` use their `test-stubs` features (ffmpeg_bridge - stub / in-crate render mocks). - `oaknode`/`oaktimeline`/`oaktask` are linked WITHOUT their `test-stubs` features: their in-crate mocks would collide with the real oakundo rlib in one test binary. Without test-stubs their real exports reference the oaknode/oakundo/oakcommon C ABI symbols as link-time externs, which the - dev-dependency rlibs provide; oaknode itself resolves cross-module + sibling crate rlibs provide; oaknode itself resolves cross-module symbols at runtime with `dlsym(RTLD_DEFAULT)`. - `tests/common/mod.rs` defines the `oakcore_*` (liboakcore) and `fb_*` (libffmpeg_bridge) symbols the oakcodec/oakaudio rlibs reference, and @@ -106,7 +113,9 @@ facade's bridge imports resolve: factory so the oaknode serializer's dlsym lookups resolve in every test binary. - `src/lib.rs`'s test-only `test_link` forces the oakrender/oaknode/ - oaktimeline/oaktask rlibs into the lib unit-test binary. + oaktimeline/oaktask rlibs into the lib unit-test binary (the always-on + `src/linkage.rs` anchors are `#[cfg(not(test))]`; they are what embeds + the module C ABIs in the cdylib for `cargo build`). Families whose wrapped behavior requires the real module dylibs carry `#[ignore]` tests with a documented reason; the smoke tests here exercise @@ -118,7 +127,8 @@ payloads in both directions, including wraparound and full/empty edges. cargo test # 71 tests green + 1 ignored (lib 35: ipc 17 + worker 18; # integration: undo 3, common 4, audio 4, plugin 3, codec 5, # render 6, linkage 1, node 3, timeline 2 + 1 ignored, task 5) -cargo build # staticlib + rlib; module symbols resolve at the final app link +cargo build # cdylib embeds the module C ABIs; oakcore_*/fb_* stay + # runtime lookups (see build.rs) ``` ## FFI discipline diff --git a/src/engine/rust/build.rs b/src/engine/rust/build.rs new file mode 100644 index 000000000..788824278 --- /dev/null +++ b/src/engine/rust/build.rs @@ -0,0 +1,33 @@ +// Oak Video Editor - Non-Linear Video Editor +// Copyright (C) 2026 Oak Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +//! Build-time link configuration for the `liboakengine` cdylib. +//! +//! The dylib now carries the module C ABIs itself (oakundo_*, oakcommon_*, +//! ... — see Cargo.toml), so the only remaining undefined imports are the +//! C++ host-provided symbols the modules call directly: `oakcore_*` +//! (liboakcore's `oakcore_audioparams_*` / `oakcore_rational_*`, called by +//! oakcodec) and `fb_find_best_pix_fmt_of_list` (ffmpeg_bridge, called by +//! oakcommon's pixel-format helper). Those live in the host Oak process, +//! which loads this dylib, so macOS `ld` must accept them as runtime +//! lookups instead of link-time errors. Only the cdylib gets this flag — +//! the rlib/staticlib (and the worker/cli consumers) are unaffected. + +fn main() { + if std::env::var("CARGO_CFG_TARGET_OS").as_deref() == Ok("macos") { + println!("cargo:rustc-cdylib-link-arg=-Wl,-undefined,dynamic_lookup"); + } +} diff --git a/src/facade/rust/src/audio.rs b/src/engine/rust/src/audio.rs similarity index 100% rename from src/facade/rust/src/audio.rs rename to src/engine/rust/src/audio.rs diff --git a/src/facade/rust/src/bridge/audio.rs b/src/engine/rust/src/bridge/audio.rs similarity index 100% rename from src/facade/rust/src/bridge/audio.rs rename to src/engine/rust/src/bridge/audio.rs diff --git a/src/facade/rust/src/bridge/codec.rs b/src/engine/rust/src/bridge/codec.rs similarity index 100% rename from src/facade/rust/src/bridge/codec.rs rename to src/engine/rust/src/bridge/codec.rs diff --git a/src/facade/rust/src/bridge/common.rs b/src/engine/rust/src/bridge/common.rs similarity index 100% rename from src/facade/rust/src/bridge/common.rs rename to src/engine/rust/src/bridge/common.rs diff --git a/src/facade/rust/src/bridge/mod.rs b/src/engine/rust/src/bridge/mod.rs similarity index 100% rename from src/facade/rust/src/bridge/mod.rs rename to src/engine/rust/src/bridge/mod.rs diff --git a/src/facade/rust/src/bridge/node.rs b/src/engine/rust/src/bridge/node.rs similarity index 100% rename from src/facade/rust/src/bridge/node.rs rename to src/engine/rust/src/bridge/node.rs diff --git a/src/facade/rust/src/bridge/plugin.rs b/src/engine/rust/src/bridge/plugin.rs similarity index 100% rename from src/facade/rust/src/bridge/plugin.rs rename to src/engine/rust/src/bridge/plugin.rs diff --git a/src/facade/rust/src/bridge/render.rs b/src/engine/rust/src/bridge/render.rs similarity index 100% rename from src/facade/rust/src/bridge/render.rs rename to src/engine/rust/src/bridge/render.rs diff --git a/src/facade/rust/src/bridge/task.rs b/src/engine/rust/src/bridge/task.rs similarity index 100% rename from src/facade/rust/src/bridge/task.rs rename to src/engine/rust/src/bridge/task.rs diff --git a/src/facade/rust/src/bridge/timeline.rs b/src/engine/rust/src/bridge/timeline.rs similarity index 100% rename from src/facade/rust/src/bridge/timeline.rs rename to src/engine/rust/src/bridge/timeline.rs diff --git a/src/facade/rust/src/bridge/undo.rs b/src/engine/rust/src/bridge/undo.rs similarity index 100% rename from src/facade/rust/src/bridge/undo.rs rename to src/engine/rust/src/bridge/undo.rs diff --git a/src/facade/rust/src/codec.rs b/src/engine/rust/src/codec.rs similarity index 100% rename from src/facade/rust/src/codec.rs rename to src/engine/rust/src/codec.rs diff --git a/src/facade/rust/src/common.rs b/src/engine/rust/src/common.rs similarity index 100% rename from src/facade/rust/src/common.rs rename to src/engine/rust/src/common.rs diff --git a/src/facade/rust/src/deferred.rs b/src/engine/rust/src/deferred.rs similarity index 100% rename from src/facade/rust/src/deferred.rs rename to src/engine/rust/src/deferred.rs diff --git a/src/facade/rust/src/error.rs b/src/engine/rust/src/error.rs similarity index 100% rename from src/facade/rust/src/error.rs rename to src/engine/rust/src/error.rs diff --git a/src/facade/rust/src/handle.rs b/src/engine/rust/src/handle.rs similarity index 100% rename from src/facade/rust/src/handle.rs rename to src/engine/rust/src/handle.rs diff --git a/src/facade/rust/src/ipc.rs b/src/engine/rust/src/ipc.rs similarity index 100% rename from src/facade/rust/src/ipc.rs rename to src/engine/rust/src/ipc.rs diff --git a/src/facade/rust/src/lib.rs b/src/engine/rust/src/lib.rs similarity index 78% rename from src/facade/rust/src/lib.rs rename to src/engine/rust/src/lib.rs index 3d7b495bd..dadf1fed1 100644 --- a/src/facade/rust/src/lib.rs +++ b/src/engine/rust/src/lib.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -//! # oakfacade — the `liboakengine` facade (Rust) +//! # oakengine — the `liboakengine` facade (Rust) //! //! Re-exports the frozen `oakengine_*` C ABI //! (`engine/include/oakengine/*.h`) verbatim on top of the module C ABIs @@ -42,12 +42,17 @@ //! //! ## Testing //! -//! `cargo test` links the module crates' rlibs (dev-dependencies) so the -//! bridge imports resolve; `tests/linkage.rs` references every crate to -//! force rustc to pull the rlibs into the link. Where a wrapped family -//! needs module behavior the crates do not implement yet, the engine -//! function is a documented stub and its test carries `#[ignore]` with a -//! reason (see README.md). +//! The module crates are real dependencies (see Cargo.toml) and +//! [`linkage`] anchors them into every link of this crate, so the module +//! C ABIs are embedded in the `liboakengine` cdylib next to the facade's +//! own exports. `cargo test` links the same crates' rlibs (plus the +//! `test-stubs` feature union declared in the dev-dependencies, which +//! compiles the oakcommon/oakplugin in-crate mocks); `tests/linkage.rs` +//! additionally references every crate for the integration-test binaries +//! and `test_link` (below) covers the unit-test binary. Where a wrapped +//! family needs module behavior the crates do not implement yet, the +//! engine function is a documented stub and its test carries `#[ignore]` +//! with a reason (see README.md). #![deny(unsafe_op_in_unsafe_fn)] #![warn(missing_docs)] @@ -60,6 +65,8 @@ pub mod deferred; pub mod error; pub mod handle; pub mod ipc; +#[cfg(not(test))] +pub mod linkage; pub mod node; pub mod plugin; pub mod render; diff --git a/src/engine/rust/src/linkage.rs b/src/engine/rust/src/linkage.rs new file mode 100644 index 000000000..d40e63f9b --- /dev/null +++ b/src/engine/rust/src/linkage.rs @@ -0,0 +1,66 @@ +// Oak Video Editor - Non-Linear Video Editor +// Copyright (C) 2026 Oak Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +//! Linkage anchors — force the module crates' rlibs into every link. +//! +//! The facade talks to the modules exclusively through `extern "C"` +//! imports (src/bridge/), so rustc would otherwise consider the module +//! crates unused and prune their rlibs from the link. This module +//! references one `#[no_mangle]` export of every module crate (and +//! `oakcore-rs`) from a `#[used]` static, which (a) marks each crate as +//! used so its rlib reaches the linker and (b) keeps the anchor alive so +//! the referenced object files are pulled. For the `liboakengine` cdylib +//! this is what actually embeds the module C ABIs (oakundo_*, +//! oakcommon_*, ...) into the dylib next to the facade's own oakengine_* +//! exports. +//! +//! The per-crate symbol mirrors the test-force-link in +//! tests/common/mod.rs (same paths, same `as usize` cast idiom), so the +//! crate/module paths are proven against the current module layouts. + +#![allow(dead_code)] + +/// Pull every module crate into the link. Mirrors +/// `tests/common/mod.rs::force_link`; the oakcommon XML/undo anchors are +/// repeated because oaknode's serializer resolves those C ABI symbols at +/// runtime via dlsym(RTLD_DEFAULT) and they must be present in the dylib +/// for that lookup to succeed. +fn force_link() -> usize { + let fns: [usize; 13] = [ + // oakcore-rs (pure value types; referenced so its rlib is linked). + oakcore_rs::Rational::new(1, 2).numerator() as usize, + // One exported C ABI symbol per module crate. + oakundo::ffi::undostack::oakundo_undostack_init as usize, + oakcommon::ffi::config::oakcommon_config_get_int as usize, + oaktimeline::ffi::marker::oaktimeline_marker_list_create as usize, + oakcodec::ffi::format::oakcodec_encoding_format_count as usize, + oakaudio::ffi::waveform::oakaudio_waveform_length as usize, + oakrender::ffi::cache::oakrender_cache_indicator_height as usize, + oaktask::ffi::manager::oaktask_manager_init as usize, + oakplugin::ffi::oakplugin_host_plugin_count as usize, + oaknode::ffi::project::oaknode_project_init as usize, + // oaknode's dlsym(RTLD_DEFAULT) targets (see tests/common/mod.rs). + oakcommon::ffi::xmlutils::oakcommon_xml_writer_init as usize, + oakcommon::ffi::xmlutils::oakcommon_xml_reader_init as usize, + oakundo::ffi::command::oakundo_command_init as usize, + ]; + fns.iter().sum() +} + +/// Keeps [`force_link`] (and through it every referenced export) alive in +/// the cdylib/staticlib even though nothing calls it directly. +#[used] +static FORCE_LINK_ANCHOR: fn() -> usize = force_link; diff --git a/src/facade/rust/src/node.rs b/src/engine/rust/src/node.rs similarity index 100% rename from src/facade/rust/src/node.rs rename to src/engine/rust/src/node.rs diff --git a/src/facade/rust/src/plugin.rs b/src/engine/rust/src/plugin.rs similarity index 100% rename from src/facade/rust/src/plugin.rs rename to src/engine/rust/src/plugin.rs diff --git a/src/facade/rust/src/render.rs b/src/engine/rust/src/render.rs similarity index 100% rename from src/facade/rust/src/render.rs rename to src/engine/rust/src/render.rs diff --git a/src/facade/rust/src/task.rs b/src/engine/rust/src/task.rs similarity index 100% rename from src/facade/rust/src/task.rs rename to src/engine/rust/src/task.rs diff --git a/src/facade/rust/src/timeline.rs b/src/engine/rust/src/timeline.rs similarity index 100% rename from src/facade/rust/src/timeline.rs rename to src/engine/rust/src/timeline.rs diff --git a/src/facade/rust/src/undo.rs b/src/engine/rust/src/undo.rs similarity index 100% rename from src/facade/rust/src/undo.rs rename to src/engine/rust/src/undo.rs diff --git a/src/facade/rust/src/worker.rs b/src/engine/rust/src/worker.rs similarity index 100% rename from src/facade/rust/src/worker.rs rename to src/engine/rust/src/worker.rs diff --git a/src/facade/rust/tests/audio.rs b/src/engine/rust/tests/audio.rs similarity index 99% rename from src/facade/rust/tests/audio.rs rename to src/engine/rust/tests/audio.rs index 123e0481c..2cfad0bcb 100644 --- a/src/facade/rust/tests/audio.rs +++ b/src/engine/rust/tests/audio.rs @@ -22,7 +22,7 @@ #[path = "common/mod.rs"] mod common; -use oakfacade::audio::{ +use oakengine::audio::{ oakengine_audio_clear_buffered_output, oakengine_audio_create_instance, oakengine_audio_destroy_instance, oakengine_audio_estimate_envelope_offset, oakengine_audio_get_output_device, oakengine_audio_hard_reset, diff --git a/src/facade/rust/tests/codec.rs b/src/engine/rust/tests/codec.rs similarity index 98% rename from src/facade/rust/tests/codec.rs rename to src/engine/rust/tests/codec.rs index fe540a086..e56e7581e 100644 --- a/src/facade/rust/tests/codec.rs +++ b/src/engine/rust/tests/codec.rs @@ -22,7 +22,7 @@ mod common; use std::ffi::{c_char, c_int}; -use oakfacade::codec::{ +use oakengine::codec::{ oakengine_encoding_codec_is_lossless, oakengine_encoding_codec_is_still_image, oakengine_encoding_codec_name, oakengine_encoding_filename_contains_digit_placeholder, oakengine_encoding_filename_remove_digit_placeholder, oakengine_encoding_format_audio_codec_count, @@ -45,7 +45,7 @@ use oakfacade::codec::{ oakengine_encoding_params_video_pix_fmt, oakengine_encoding_params_set_video_pix_fmt, oakengine_encoding_pix_fmt_index, }; -use oakfacade::common::OakVideoParamsPod; +use oakengine::common::OakVideoParamsPod; /// Container format / codec metadata queries. #[test] @@ -142,7 +142,7 @@ fn params_handle_round_trip() { let mut vp: OakVideoParamsPod = unsafe { std::mem::zeroed() }; assert_eq!( unsafe { - oakfacade::common::oakengine_video_params_make(&mut vp, 1920, 1080, 1001, 30000, 4, 1, 1, 0, 1, 1) + oakengine::common::oakengine_video_params_make(&mut vp, 1920, 1080, 1001, 30000, 4, 1, 1, 0, 1, 1) }, 0 ); diff --git a/src/facade/rust/tests/common.rs b/src/engine/rust/tests/common.rs similarity index 97% rename from src/facade/rust/tests/common.rs rename to src/engine/rust/tests/common.rs index 039f35580..038015a29 100644 --- a/src/facade/rust/tests/common.rs +++ b/src/engine/rust/tests/common.rs @@ -25,7 +25,7 @@ mod common; use std::ffi::{c_char, c_int}; -use oakfacade::common::{ +use oakengine::common::{ oakengine_config_get_int, oakengine_config_get_string, oakengine_config_load, oakengine_config_save, oakengine_config_set_error_handler, oakengine_config_set_int, oakengine_config_set_string, oakengine_video_params_bytes_per_pixel, @@ -87,12 +87,12 @@ fn config_error_handler() { assert_eq!(unsafe { oakengine_config_set_error_handler(Some(handler), std::ptr::null_mut()) }, 0); // Report an error through the handler. assert_eq!(unsafe { - oakfacade::common::oakengine_config_report_error(c"t".as_ptr(), c"m".as_ptr()) + oakengine::common::oakengine_config_report_error(c"t".as_ptr(), c"m".as_ptr()) }, 0); assert_eq!(CALLED.load(std::sync::atomic::Ordering::SeqCst), 1); // NULL handler clears; reporting then does not invoke. assert_eq!(unsafe { oakengine_config_set_error_handler(None, std::ptr::null_mut()) }, 0); - unsafe { oakfacade::common::oakengine_config_report_error(c"t".as_ptr(), c"m".as_ptr()) }; + unsafe { oakengine::common::oakengine_config_report_error(c"t".as_ptr(), c"m".as_ptr()) }; assert_eq!(CALLED.load(std::sync::atomic::Ordering::SeqCst), 1); } diff --git a/src/facade/rust/tests/common/mod.rs b/src/engine/rust/tests/common/mod.rs similarity index 100% rename from src/facade/rust/tests/common/mod.rs rename to src/engine/rust/tests/common/mod.rs diff --git a/src/facade/rust/tests/linkage.rs b/src/engine/rust/tests/linkage.rs similarity index 100% rename from src/facade/rust/tests/linkage.rs rename to src/engine/rust/tests/linkage.rs diff --git a/src/facade/rust/tests/node.rs b/src/engine/rust/tests/node.rs similarity index 97% rename from src/facade/rust/tests/node.rs rename to src/engine/rust/tests/node.rs index 34a8e4952..50972686c 100644 --- a/src/facade/rust/tests/node.rs +++ b/src/engine/rust/tests/node.rs @@ -28,7 +28,7 @@ mod common; use std::ffi::{c_char, c_int}; -use oakfacade::node::{ +use oakengine::node::{ oakengine_footage_borrow, oakengine_footage_last_error, oakengine_footage_probe, oakengine_node_connect, oakengine_node_disconnect, oakengine_node_factory_create_from_id, oakengine_node_factory_id_count, oakengine_node_factory_name_from_id, @@ -83,7 +83,7 @@ fn float_value(x: f64) -> OakNodeValue { } /// The index of the first project node whose type id matches `id`, or -1. -unsafe fn find_node(project: *mut oakfacade::handle::OakEngineProject, id: &str) -> c_int { +unsafe fn find_node(project: *mut oakengine::handle::OakEngineProject, id: &str) -> c_int { let count = unsafe { oakengine_project_node_count(project) }; for i in 0..count { let node = unsafe { oakengine_project_node_at(project, i) }; @@ -137,15 +137,15 @@ fn project_node_keyframe_lifecycle() { 0 ); assert_eq!( - unsafe { oakengine_project_set_filename(project, c"/tmp/oakfacade_node_test.ovexml".as_ptr()) }, + unsafe { oakengine_project_set_filename(project, c"/tmp/oakengine_node_test.ovexml".as_ptr()) }, 0 ); let len = unsafe { oakengine_project_filename(project, buf.as_mut_ptr(), 256) }; assert!(len > 0); - assert!(unsafe { read_buf(&mut buf) }.ends_with("oakfacade_node_test.ovexml")); + assert!(unsafe { read_buf(&mut buf) }.ends_with("oakengine_node_test.ovexml")); let len = unsafe { oakengine_project_name(project, buf.as_mut_ptr(), 256) }; assert!(len > 0); - assert_eq!(unsafe { read_buf(&mut buf) }, "oakfacade_node_test"); + assert_eq!(unsafe { read_buf(&mut buf) }, "oakengine_node_test"); // ---- factory + node creation --------------------------------------- let factory_count = oakengine_node_factory_id_count(); @@ -269,9 +269,9 @@ fn project_node_keyframe_lifecycle() { assert!((at.f[0] - 0.5).abs() < 1e-6); // ---- project save → fresh load round-trip --------------------------- - let path = c"/tmp/oakfacade_node_test.ovexml"; + let path = c"/tmp/oakengine_node_test.ovexml"; assert_eq!(unsafe { oakengine_project_save(project, path.as_ptr()) }, 0); - assert!(std::path::Path::new("/tmp/oakfacade_node_test.ovexml").exists()); + assert!(std::path::Path::new("/tmp/oakengine_node_test.ovexml").exists()); unsafe { oakengine_project_free(project) }; diff --git a/src/facade/rust/tests/plugin.rs b/src/engine/rust/tests/plugin.rs similarity index 97% rename from src/facade/rust/tests/plugin.rs rename to src/engine/rust/tests/plugin.rs index ba4483702..46404c03f 100644 --- a/src/facade/rust/tests/plugin.rs +++ b/src/engine/rust/tests/plugin.rs @@ -19,7 +19,7 @@ #[path = "common/mod.rs"] mod common; -use oakfacade::plugin::{ +use oakengine::plugin::{ oakengine_plugin_load_plugins, oakengine_plugin_node_push_button_clicked, oakengine_plugin_set_active_viewer_provider, oakengine_plugin_set_progress_reporter_factory, }; @@ -27,7 +27,7 @@ use oakfacade::plugin::{ /// Callback registration round-trips (NULL clears). #[test] fn provider_registration() { - unsafe extern "C" fn viewer(_userdata: *mut std::ffi::c_void) -> *mut oakfacade::handle::OakEngineNode { + unsafe extern "C" fn viewer(_userdata: *mut std::ffi::c_void) -> *mut oakengine::handle::OakEngineNode { std::ptr::null_mut() } assert_eq!(unsafe { diff --git a/src/facade/rust/tests/render.rs b/src/engine/rust/tests/render.rs similarity index 99% rename from src/facade/rust/tests/render.rs rename to src/engine/rust/tests/render.rs index 3a7956c0a..3d31a999d 100644 --- a/src/facade/rust/tests/render.rs +++ b/src/engine/rust/tests/render.rs @@ -26,7 +26,7 @@ mod common; use std::ffi::{c_char, c_double}; -use oakfacade::render::{ +use oakengine::render::{ oakengine_color_last_error, oakengine_color_manager_get_config_filename, oakengine_color_processor_convert_color, oakengine_color_processor_create, oakengine_color_processor_free, oakengine_color_processor_is_valid, diff --git a/src/facade/rust/tests/task.rs b/src/engine/rust/tests/task.rs similarity index 98% rename from src/facade/rust/tests/task.rs rename to src/engine/rust/tests/task.rs index 3e3e1ea3e..3883e371c 100644 --- a/src/facade/rust/tests/task.rs +++ b/src/engine/rust/tests/task.rs @@ -34,11 +34,11 @@ mod common; use std::ffi::{c_char, c_int, c_void}; -use oakfacade::node::{ +use oakengine::node::{ oakengine_node_free, oakengine_project_create, oakengine_project_free, oakengine_project_new, oakengine_project_root, oakengine_project_set_filename, }; -use oakfacade::task::{ +use oakengine::task::{ oakengine_cli_task_dialog_run, oakengine_task_cancel, oakengine_task_create_export, oakengine_task_create_project_import, oakengine_task_create_project_load, oakengine_task_create_project_load_otio, oakengine_task_create_project_save, @@ -187,7 +187,7 @@ fn project_task_lifecycle() { // ---- save task on a real project → sync run writes the file ---------- let save_path = std::env::temp_dir().join(format!( - "oakfacade_task_save_{}.ovexml", + "oakengine_task_save_{}.ovexml", std::process::id() )); let save_c = std::ffi::CString::new(save_path.to_str().unwrap()).unwrap(); @@ -217,7 +217,7 @@ fn project_task_lifecycle() { // project's own filename; NULL without one, a real task with one. ------ assert!(unsafe { oakengine_task_create_project_save_otio(project) }.is_null()); assert_eq!( - unsafe { oakengine_project_set_filename(project, c"/tmp/oakfacade_task_otio.otio".as_ptr()) }, + unsafe { oakengine_project_set_filename(project, c"/tmp/oakengine_task_otio.otio".as_ptr()) }, 0 ); let otio_task = unsafe { oakengine_task_create_project_save_otio(project) }; diff --git a/src/facade/rust/tests/timeline.rs b/src/engine/rust/tests/timeline.rs similarity index 99% rename from src/facade/rust/tests/timeline.rs rename to src/engine/rust/tests/timeline.rs index 6171933a0..e87c8bcd3 100644 --- a/src/facade/rust/tests/timeline.rs +++ b/src/engine/rust/tests/timeline.rs @@ -31,12 +31,12 @@ mod common; use std::ffi::{c_char, c_int}; -use oakfacade::handle::{box_handle, OakEngineNode}; -use oakfacade::node::{ +use oakengine::handle::{box_handle, OakEngineNode}; +use oakengine::node::{ oakengine_footage_borrow, oakengine_project_create, oakengine_project_free, oakengine_project_new, }; -use oakfacade::timeline::{ +use oakengine::timeline::{ oakengine_block_get_range, oakengine_block_get_track, oakengine_block_is_enabled, oakengine_block_is_gap, oakengine_block_link_count, oakengine_block_next, oakengine_block_prev, oakengine_block_set_enabled, oakengine_block_set_length_and_media_out, @@ -103,7 +103,7 @@ fn force_runtime_syms() -> usize { /// Convert a facade `CHandle` to the layout-identical oaknode `CHandle` /// (distinct Rust types over the same C ABI struct). -fn to_node_handle(h: oakfacade::handle::CHandle) -> oaknode::handle::CHandle { +fn to_node_handle(h: oakengine::handle::CHandle) -> oaknode::handle::CHandle { oaknode::handle::CHandle { ctx: h.ctx, addref: h.addref, @@ -113,8 +113,8 @@ fn to_node_handle(h: oakfacade::handle::CHandle) -> oaknode::handle::CHandle { } /// Convert an oaknode `CHandle` back to the facade `CHandle`. -fn to_facade_handle(h: oaknode::handle::CHandle) -> oakfacade::handle::CHandle { - oakfacade::handle::CHandle { +fn to_facade_handle(h: oaknode::handle::CHandle) -> oakengine::handle::CHandle { + oakengine::handle::CHandle { ctx: h.ctx, addref: h.addref, release: h.release, diff --git a/src/facade/rust/tests/undo.rs b/src/engine/rust/tests/undo.rs similarity index 93% rename from src/facade/rust/tests/undo.rs rename to src/engine/rust/tests/undo.rs index af90d04f5..d714d98f3 100644 --- a/src/facade/rust/tests/undo.rs +++ b/src/engine/rust/tests/undo.rs @@ -28,7 +28,7 @@ mod common; use std::ffi::{c_char, c_int, c_void}; use std::sync::atomic::{AtomicI32, Ordering}; -use oakfacade::undo::{ +use oakengine::undo::{ oakengine_undo_can_redo, oakengine_undo_can_undo, oakengine_undo_clear, oakengine_undo_command_create, oakengine_undo_command_create_multi, oakengine_undo_command_free, oakengine_undo_command_multi_add_child, @@ -53,16 +53,28 @@ static CMD_FREE_COUNT: AtomicI32 = AtomicI32::new(0); static STK_REDO_COUNT: AtomicI32 = AtomicI32::new(0); static STK_UNDO_COUNT: AtomicI32 = AtomicI32::new(0); +/// Stack-test callbacks: bump only the `STK_*` counters. They must not +/// touch the `CMD_*` counters — the command-lifecycle tests reset and +/// assert those in parallel threads, so a stray bump here would race. unsafe extern "C" fn redo_cb(_userdata: *mut c_void) { - CMD_REDO_COUNT.fetch_add(1, Ordering::SeqCst); STK_REDO_COUNT.fetch_add(1, Ordering::SeqCst); } unsafe extern "C" fn undo_cb(_userdata: *mut c_void) { - CMD_UNDO_COUNT.fetch_add(1, Ordering::SeqCst); STK_UNDO_COUNT.fetch_add(1, Ordering::SeqCst); } +/// Command-lifecycle-only callbacks: bump only the `CMD_*` counters. The +/// serialized stack test runs in a parallel thread and must not flip +/// these. +unsafe extern "C" fn cmd_redo_cb(_userdata: *mut c_void) { + CMD_REDO_COUNT.fetch_add(1, Ordering::SeqCst); +} + +unsafe extern "C" fn cmd_undo_cb(_userdata: *mut c_void) { + CMD_UNDO_COUNT.fetch_add(1, Ordering::SeqCst); +} + unsafe extern "C" fn free_cb(_userdata: *mut c_void) { CMD_FREE_COUNT.fetch_add(1, Ordering::SeqCst); } @@ -77,8 +89,8 @@ fn command_create_redo_undo_free() { let cmd = unsafe { oakengine_undo_command_create( c"custom".as_ptr(), - Some(redo_cb), - Some(undo_cb), + Some(cmd_redo_cb), + Some(cmd_undo_cb), Some(free_cb), std::ptr::null_mut(), ) @@ -108,8 +120,8 @@ fn multi_command_add_child_count_redo() { let child = unsafe { oakengine_undo_command_create( c"child".as_ptr(), - Some(redo_cb), - Some(undo_cb), + Some(cmd_redo_cb), + Some(cmd_undo_cb), None, std::ptr::null_mut(), ) diff --git a/src/facade/rust/Cargo.toml b/src/facade/rust/Cargo.toml deleted file mode 100644 index 36b20e72e..000000000 --- a/src/facade/rust/Cargo.toml +++ /dev/null @@ -1,55 +0,0 @@ -[package] -name = "oakfacade" -version = "0.1.0" -edition = "2021" -description = "Oak Video Editor facade: re-exports the frozen oakengine_* C ABI over the module C ABIs (Rust)" -license = "GPL-3.0-or-later" - -[lib] -crate-type = ["staticlib", "rlib"] - -[profile.release] -# FFI discipline: panics must be catchable at every exported entry. -panic = "unwind" - -[dependencies] -# NDJSON control-plane protocol for the worker session (src/worker.rs) and -# the shm error formatting in src/ipc.rs. -serde = { version = "1", features = ["derive"] } -serde_json = "1" -# POSIX shm_open/mmap/munmap/shm_unlink constants + syscalls for the -# shared-memory frame-slot transport (src/ipc.rs). -libc = "0.2" - -# Every module call crosses the module C ABI as an `extern "C"` import -# (src/bridge/), resolved at the final link against the module shared -# libraries (see README.md). -# -# `cargo test` links the module crates' rlibs instead (dev-dependencies -# below): the crates' `#[no_mangle]` exports satisfy the facade's bridge -# imports, so the smoke tests exercise the real module code where the -# crates implement it. Tests reference every crate so rustc pulls the -# rlibs into the link (see tests/common/mod.rs). -# -# test-stubs on oakcommon/oakplugin compiles those crates' in-crate C ABI -# mocks: oakcommon's stub replaces the ffmpeg_bridge symbol, and -# oakplugin's stubs replace its runtime dlsym lookups. -# -# NOTE (oaktimeline/oaktask): linked WITHOUT their `test-stubs` features. -# Their in-crate mocks define `oakundo_command_init` etc., which would -# collide with the real oakundo rlib in one test binary; without -# test-stubs their real exports reference the oaknode/oakundo/oakcommon -# C ABI symbols as link-time externs, which the dev-dependency rlibs -# (oaknode, oakundo, oakcommon[test-stubs]) provide. oaknode itself -# resolves cross-module symbols at runtime with dlsym(RTLD_DEFAULT), which -# finds the linked rlibs in the test binary (see src/bridge/node.rs). -[dev-dependencies] -oakundo = { path = "../../undo/rust" } -oakcodec = { path = "../../codec/rust" } -oakaudio = { path = "../../audio/rust" } -oakrender = { path = "../../render/rust" } -oakcommon = { path = "../../common/rust", features = ["test-stubs"] } -oakplugin = { path = "../../plugin/rust", features = ["test-stubs"] } -oaknode = { path = "../../node/rust" } -oaktimeline = { path = "../../timeline/rust" } -oaktask = { path = "../../task/rust" } diff --git a/worker/rust/Cargo.lock b/worker/rust/Cargo.lock index b7d0c4e1c..a7c52ae5d 100644 --- a/worker/rust/Cargo.lock +++ b/worker/rust/Cargo.lock @@ -2,6 +2,21 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "adler2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" + +[[package]] +name = "aho-corasick" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c982642fa9e8606056828ee9a8505737230110bb1099153c79efe865c59d12ba" +dependencies = [ + "memchr", +] + [[package]] name = "android_system_properties" version = "0.1.6" @@ -82,6 +97,24 @@ version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" +[[package]] +name = "bindgen" +version = "0.72.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895" +dependencies = [ + "bitflags 2.13.1", + "cexpr", + "clang-sys", + "itertools", + "proc-macro2", + "quote", + "regex", + "rustc-hash 2.1.3", + "shlex 1.3.0", + "syn 2.0.119", +] + [[package]] name = "bit-set" version = "0.8.0" @@ -144,6 +177,12 @@ dependencies = [ "syn 3.0.3", ] +[[package]] +name = "byteorder-lite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" + [[package]] name = "cc" version = "1.4.2" @@ -151,7 +190,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d262e149917187838d5b42777c8253bcb64500067342904e7d429499a6f277e" dependencies = [ "find-msvc-tools", - "shlex", + "shlex 2.0.1", +] + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", ] [[package]] @@ -166,6 +214,17 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f079e83a288787bcd14a6aea84cee5c87a67c5a3e660c30f557a3d24761b3527" +[[package]] +name = "clang-sys" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "157a8ba7b480713b56f4c09fd13fc3e0a22a5dfab8097ba61cbc5feef950788a" +dependencies = [ + "glob", + "libc", + "libloading", +] + [[package]] name = "clap" version = "4.6.6" @@ -259,6 +318,15 @@ dependencies = [ "libc", ] +[[package]] +name = "crc32fast" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +dependencies = [ + "cfg-if", +] + [[package]] name = "crunchy" version = "0.2.4" @@ -274,18 +342,65 @@ dependencies = [ "litrs", ] +[[package]] +name = "either" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e5e8f6c15a24b9a3ee5efec809ccd006d3b30e8b3bb63c39af737c7f87daa1d" + [[package]] name = "equivalent" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" +[[package]] +name = "fax" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "caf1079563223d5d59d83c85886a56e586cfd5c1a26292e971a0fa266531ac5a" + +[[package]] +name = "ffmpeg-next" +version = "9.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6380599799e175191eb7ffe82c97f36a2a90a36cbc54c738a903e5287d7f516a" +dependencies = [ + "bitflags 2.13.1", + "ffmpeg-sys-next", + "libc", +] + +[[package]] +name = "ffmpeg-sys-next" +version = "9.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b939bf79dd5949412a4b81cfe21a07f48ea21b47fcbb5f57816c8c2de5ae30b" +dependencies = [ + "bindgen", + "cc", + "libc", + "num_cpus", + "pkg-config", + "vcpkg", +] + [[package]] name = "find-msvc-tools" version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26b73573e6edcd2af0cdf47bd6cb58f0b3839491263c314eaad1ccf24430e1de" +[[package]] +name = "flate2" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + [[package]] name = "foldhash" version = "0.1.5" @@ -354,6 +469,12 @@ dependencies = [ "xml-rs", ] +[[package]] +name = "glob" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4eba85ea1d0a966a983acd07deee566e67395d2d96b6fb39e62b5a833f1eb0b" + [[package]] name = "glow" version = "0.16.0" @@ -459,12 +580,31 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +[[package]] +name = "hermit-abi" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" + [[package]] name = "hexf-parse" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" +[[package]] +name = "image" +version = "0.25.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85ab80394333c02fe689eaf900ab500fbd0c2213da414687ebf995a65d5a6104" +dependencies = [ + "bytemuck", + "byteorder-lite", + "moxcms", + "num-traits", + "tiff", +] + [[package]] name = "indexmap" version = "2.14.0" @@ -481,6 +621,15 @@ version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.18" @@ -616,6 +765,32 @@ dependencies = [ "paste", ] +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +dependencies = [ + "adler2", + "simd-adler32", +] + +[[package]] +name = "moxcms" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb85c154ba489f01b25c0d36ae69a87e4a1c73a72631fc6c0eb6dde34a73e44b" +dependencies = [ + "num-traits", + "pxfm", +] + [[package]] name = "naga" version = "25.0.1" @@ -634,7 +809,7 @@ dependencies = [ "log", "num-traits", "once_cell", - "rustc-hash", + "rustc-hash 1.1.0", "spirv", "strum", "thiserror 2.0.20", @@ -650,6 +825,16 @@ dependencies = [ "jni-sys 0.3.1", ] +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + [[package]] name = "num-traits" version = "0.2.19" @@ -660,30 +845,100 @@ dependencies = [ "libm", ] +[[package]] +name = "num_cpus" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b" +dependencies = [ + "hermit-abi", + "libc", +] + [[package]] name = "oak-worker" version = "0.1.0" dependencies = [ "clap", - "oakfacade", + "oakengine", "oakrender", "serde", "serde_json", ] +[[package]] +name = "oakaudio" +version = "0.1.0" +dependencies = [ + "oakcore-rs", +] + +[[package]] +name = "oakcodec" +version = "0.1.0" +dependencies = [ + "ffmpeg-next", + "oakcore-rs", +] + +[[package]] +name = "oakcommon" +version = "0.1.0" +dependencies = [ + "image", + "log", + "oakcore-rs", + "ocio-rs", + "quick-xml", +] + [[package]] name = "oakcore-rs" version = "0.1.0" [[package]] -name = "oakfacade" +name = "oakengine" version = "0.1.0" dependencies = [ "libc", + "oakaudio", + "oakcodec", + "oakcommon", + "oakcore-rs", + "oaknode", + "oakplugin", + "oakrender", + "oaktask", + "oaktimeline", + "oakundo", "serde", "serde_json", ] +[[package]] +name = "oaknode" +version = "0.1.0" +dependencies = [ + "oakcore-rs", +] + +[[package]] +name = "oakotio" +version = "0.1.0" +dependencies = [ + "oakcore-rs", + "quick-xml", + "serde", + "serde_json", +] + +[[package]] +name = "oakplugin" +version = "0.1.0" +dependencies = [ + "cc", +] + [[package]] name = "oakrender" version = "0.1.0" @@ -693,6 +948,28 @@ dependencies = [ "wgpu", ] +[[package]] +name = "oaktask" +version = "0.1.0" +dependencies = [ + "oakcore-rs", + "oakotio", +] + +[[package]] +name = "oaktimeline" +version = "0.1.0" +dependencies = [ + "oakcore-rs", +] + +[[package]] +name = "oakundo" +version = "0.1.0" +dependencies = [ + "oakcore-rs", +] + [[package]] name = "objc" version = "0.2.7" @@ -811,6 +1088,27 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d595e54a326bc53c1c197b32d295e14b169e3cfeaa8dc82b529f947fba6bcf5" +[[package]] +name = "pxfm" +version = "0.1.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d55d956fa96f5ec02be2e13af0e20391a5aa83d6a074e3ad368959d0fab299ea" + +[[package]] +name = "quick-error" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" + +[[package]] +name = "quick-xml" +version = "0.41.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e660451e55124f798a69a5af3f49ccfbefbd41910eefd25caf2393e1f3473ec1" +dependencies = [ + "memchr", +] + [[package]] name = "quote" version = "1.0.47" @@ -841,6 +1139,35 @@ dependencies = [ "bitflags 2.13.1", ] +[[package]] +name = "regex" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f020237b6c8eed93db2e2cb53c00c60a8e1bc73da7d073199a1180401450218d" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad8553b9b26413251cbf30e620595c7a41b3887f03da04579c0e6b0d6a06b4b2" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" + [[package]] name = "renderdoc-sys" version = "1.1.0" @@ -853,6 +1180,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" +[[package]] +name = "rustc-hash" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b1e7f9a428571be2dc5bc0505c13fb6bf936822b894ec87abf8a08a4e51742d" + [[package]] name = "rustversion" version = "1.0.23" @@ -901,6 +1234,7 @@ version = "1.0.151" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14" dependencies = [ + "indexmap", "itoa", "memchr", "serde", @@ -908,12 +1242,24 @@ dependencies = [ "zmij", ] +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "shlex" version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" +[[package]] +name = "simd-adler32" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a219298ac11a56ea9a6d2120044824d6f01aeb034955e7af7bc16858527deea" + [[package]] name = "slab" version = "0.4.12" @@ -1049,6 +1395,20 @@ dependencies = [ "syn 3.0.3", ] +[[package]] +name = "tiff" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b63feaf3343d35b6ca4d50483f94843803b0f51634937cc2ec519fc32232bc52" +dependencies = [ + "fax", + "flate2", + "half", + "quick-error", + "weezl", + "zune-jpeg", +] + [[package]] name = "unicode-ident" version = "1.0.24" @@ -1067,6 +1427,12 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "version_check" version = "0.9.5" @@ -1138,6 +1504,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "weezl" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28ac98ddc8b9274cb41bb4d9d4d5c425b6020c50c46f25559911905610b4a88" + [[package]] name = "wgpu" version = "25.0.2" @@ -1187,7 +1559,7 @@ dependencies = [ "portable-atomic", "profiling", "raw-window-handle", - "rustc-hash", + "rustc-hash 1.1.0", "smallvec", "thiserror 2.0.20", "wgpu-core-deps-apple", @@ -1468,3 +1840,18 @@ name = "zmij" version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" + +[[package]] +name = "zune-core" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d56377fd46368984a170bc5aac5567e52ca5da874caa60bea39fcbca78fb658b" + +[[package]] +name = "zune-jpeg" +version = "0.5.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27bc9d5b815bc103f142aa054f561d9187d191692ec7c2d1e2b4737f8dbd7296" +dependencies = [ + "zune-core", +] diff --git a/worker/rust/Cargo.toml b/worker/rust/Cargo.toml index 348c5aa8c..f145407fd 100644 --- a/worker/rust/Cargo.toml +++ b/worker/rust/Cargo.toml @@ -33,11 +33,11 @@ serde_json = "1" # The liboakengine facade (Rust): its worker module owns the whole worker # runtime — render backend selection through the oakrender module C ABI, # the startup handshake and the NDJSON control loop -# (`oakfacade::worker::worker_main`, the port of engine/src/capi/worker.cpp). +# (`oakengine::worker::worker_main`, the port of engine/src/capi/worker.cpp). # This binary is a thin shell over it, like worker/workermain.cpp. Its ipc # module provides the real shared-memory frame-slot transport -# (`oakfacade::ipc`) that src/session.rs + src/transport.rs attach through. -oakfacade = { path = "../../src/facade/rust" } +# (`oakengine::ipc`) that src/session.rs + src/transport.rs attach through. +oakengine = { path = "../../src/engine/rust" } # The oakrender module crate (the Rust rewrite of the oakrender module): # its C ABI (include/render/renderer.h) is how the facade's worker diff --git a/worker/rust/build.rs b/worker/rust/build.rs new file mode 100644 index 000000000..96f63152e --- /dev/null +++ b/worker/rust/build.rs @@ -0,0 +1,33 @@ +// Oak Video Editor - Non-Linear Video Editor +// Copyright (C) 2026 Oak Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +//! Link configuration for the `oak-worker` binary. +//! +//! The facade rlib (src/engine/rust) links the module C ABIs into any +//! consumer that pulls its codec surface — oak-worker's use of +//! `oakengine::worker` transitively pulls the facade's codec module, whose +//! oakcodec references carry a few C++-host imports (`oakcore_audioparams_*` +//! from liboakcore, `fb_*` from ffmpeg_bridge). Those live in the host Oak +//! process and are only reachable on media-decode paths this worker never +//! exercises; the CMake worker has the same property through the +//! liboakengine dylib (whose build.rs allows runtime lookups). Mirror that +//! here so the standalone Rust worker binary links. + +fn main() { + if std::env::var("CARGO_CFG_TARGET_OS").as_deref() == Ok("macos") { + println!("cargo:rustc-link-arg=-Wl,-undefined,dynamic_lookup"); + } +} diff --git a/worker/rust/src/main.rs b/worker/rust/src/main.rs index b45b5d930..dc4235e8c 100644 --- a/worker/rust/src/main.rs +++ b/worker/rust/src/main.rs @@ -19,7 +19,7 @@ //! A thin shell over the facade, mirroring `worker/workermain.cpp`: all //! runtime logic — render backend selection (dynamic -> OpenGL fallback //! through the oakrender module C ABI), the startup handshake and the -//! NDJSON control loop — lives in `oakfacade::worker` (the Rust port of +//! NDJSON control loop — lives in `oakengine::worker` (the Rust port of //! `engine/src/capi/worker.cpp`, contract in //! `engine/include/oakengine/worker.h`). This crate keeps only the CLI //! surface (arg parsing) and the in-process session mirror @@ -37,7 +37,7 @@ use std::process::exit; use clap::Parser; // Force-link the oakrender module crate: the facade's worker module -// (oakfacade::worker) initializes the render backend through the oakrender +// (oakengine::worker) initializes the render backend through the oakrender // C ABI, but its bridge imports are `extern "C"` declarations — nothing in // the worker source names the crate, so without this the oakrender rlib // would not be added to the link and those imports would stay undefined. @@ -46,7 +46,7 @@ use oakrender as _; /// Protocol version announced in the startup handshake /// (`k_protocol_version` in worker.cpp). Mirrors -/// `oakfacade::worker::PROTOCOL_VERSION`. +/// `oakengine::worker::PROTOCOL_VERSION`. pub const PROTOCOL_VERSION: i32 = 1; /// CLI surface (the C++ worker scans argv for `--backend`; clap formalizes @@ -68,7 +68,7 @@ fn main() { let args = Args::parse(); // The facade's worker_main is the C++ oakengine_worker_main() — the // whole worker flow. Like workermain.cpp, this main only forwards. - exit(oakfacade::worker::worker_main(&args.backend.to_ascii_lowercase())); + exit(oakengine::worker::worker_main(&args.backend.to_ascii_lowercase())); } /// Log a worker-side message to stderr, mirroring worker.cpp `log_error()` diff --git a/worker/rust/src/session.rs b/worker/rust/src/session.rs index 9774181e5..40119f52f 100644 --- a/worker/rust/src/session.rs +++ b/worker/rust/src/session.rs @@ -16,7 +16,7 @@ //! The worker-side session state machine — the in-process mirror of //! `OakWorkerSession` in `engine/src/capi/worker.cpp` (whose production -//! Rust port lives in `oakfacade::worker`). +//! Rust port lives in `oakengine::worker`). //! //! The session holds the attached shared-memory frame-slot pools //! ([`crate::transport::AttachedPools`]) and the shutdown flag, and @@ -61,7 +61,7 @@ impl WorkerSession { } /// The attached output pool (the worker->main frame-slot pool). - pub fn output_pool(&self) -> Option<&oakfacade::ipc::FrameSlotPool> { + pub fn output_pool(&self) -> Option<&oakengine::ipc::FrameSlotPool> { self.pools.as_ref().map(|p| &p.output_pool) } @@ -196,7 +196,7 @@ impl Default for WorkerSession { #[cfg(test)] mod tests { use super::*; - use oakfacade::ipc::{FrameSlotPool, SharedMemoryRegion, ShmMode}; + use oakengine::ipc::{FrameSlotPool, SharedMemoryRegion, ShmMode}; use serde_json::json; /// A unique, temporary POSIX segment key for a test. diff --git a/worker/rust/src/transport.rs b/worker/rust/src/transport.rs index 11fc39764..91759e5b1 100644 --- a/worker/rust/src/transport.rs +++ b/worker/rust/src/transport.rs @@ -20,7 +20,7 @@ //! shared-memory segments holding an `olive::ipc::FrameSlotPool` — a fixed //! pool of frame slots whose free/ready queues are synchronized by the //! lock-free single-producer/single-consumer `SpscRingBuffer`. That -//! machinery is implemented in the facade crate (`oakfacade::ipc`, the +//! machinery is implemented in the facade crate (`oakengine::ipc`, the //! Rust port of `engine/render/ipc/` behind //! `engine/include/oakengine/ipc.h`) — this module is the worker-side //! transport over it. @@ -36,7 +36,7 @@ //! as before: `oaknode` is a `todo!()` skeleton and the oakrender crate //! does not yet evaluate an arbitrary loaded graph to a frame. -use oakfacade::ipc::{FrameSlotPool, SharedMemoryRegion, ShmMode}; +use oakengine::ipc::{FrameSlotPool, SharedMemoryRegion, ShmMode}; use crate::ipc::HandshakeMsg;