Files
oak-editor/crates/oak-worker/src/main.rs
T
Mike-Solar a45a7af2ac refactor(cli,worker): cut liboakengine, link module rlibs directly (M14 R2)
- oak-cli: new engine.rs assembly layer maps every facade call to
  module Rust APIs (oaknode graph/serializer, oaktimeline commands,
  oakrender ticket arena, oaktask ExportTask, oakcommon config); the
  ffi/optional/host layers and build.rs link config are gone
- oak-worker: the worker session + POSIX shm transport moved into the
  crate (oakrender backend + serde_json control plane); no dylib
- both binaries carry zero liboakengine references (otool verified);
  tests green (30 cli / 41 worker)
2026-08-16 21:16:27 +08:00

119 lines
3.3 KiB
Rust

// 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 <http://www.gnu.org/licenses/>.
//! oak-worker: headless render worker process (Rust).
//!
//! The whole runtime lives in this binary (M14 R2): render backend
//! selection (dynamic -> OpenGL fallback through the oakrender crate's
//! direct Rust API), the startup handshake and the NDJSON control loop
//! ([`worker`], the port of `engine/src/capi/worker.cpp`), plus the
//! shared-memory frame-slot transport ([`ipc`], the port of
//! `engine/render/ipc/`). No `liboakengine` dylib is linked; the facade
//! keeps its own copies of both modules for the frozen
//! `oakengine_worker_*` / `oakengine_ipc_*` C ABI (external consumers).
//!
//! See README.md for the full status.
#![deny(unsafe_op_in_unsafe_fn)]
#![warn(missing_docs)]
mod ipc;
mod worker;
use std::process::exit;
/// Protocol version announced in the startup handshake
/// (`k_protocol_version` in worker.cpp).
pub const PROTOCOL_VERSION: i32 = 1;
/// Log a worker-side message to stderr, mirroring worker.cpp `log_error()`
/// (the `worker: ` prefix).
pub fn log_error(message: &str) {
eprintln!("worker: {message}");
}
/// Scan argv for `--backend <name>` (worker.cpp `oakengine_worker_main`).
/// The default is `"opengl"`; the value is lowercased; the last flag wins.
fn parse_backend(args: &[String]) -> String {
let mut backend = "opengl".to_string();
let mut i = 1usize;
while i < args.len() {
if args[i] == "--backend" && i + 1 < args.len() {
backend = args[i + 1].to_ascii_lowercase();
i += 2;
} else {
i += 1;
}
}
backend
}
fn main() {
let args: Vec<String> = std::env::args().collect();
let backend = parse_backend(&args);
exit(worker::worker_main(&backend));
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn protocol_version_is_one() {
assert_eq!(PROTOCOL_VERSION, 1);
}
#[test]
fn backend_parsing_matches_engine_main() {
// Default is opengl.
assert_eq!(parse_backend(&["oak-worker".to_string()]), "opengl");
// Value lowercased.
assert_eq!(
parse_backend(&[
"oak-worker".to_string(),
"--backend".to_string(),
"Vulkan".to_string()
]),
"vulkan"
);
// "none" skips renderer creation.
assert_eq!(
parse_backend(&[
"oak-worker".to_string(),
"--backend".to_string(),
"none".to_string()
]),
"none"
);
// Last flag wins.
assert_eq!(
parse_backend(&[
"oak-worker".to_string(),
"--backend".to_string(),
"vulkan".to_string(),
"--backend".to_string(),
"opengl".to_string()
]),
"opengl"
);
// Missing value leaves the default.
assert_eq!(
parse_backend(&["oak-worker".to_string(), "--backend".to_string()]),
"opengl"
);
}
}