use std::process;
use std::time::{Duration, Instant};
use g2g_core::runtime::{parse_launch, run_graph_with_progress, PipelineProgress};
use g2g_plugins::clock::WallClock;
use g2g_plugins::registry::default_registry;
const LINK_CAPACITY: usize = 4;
const USAGE: &str = "usage: g2g-launch-py [-q] <element> [key=value ...] ! <element> ! ...";
fn main() {
g2g_core::log::init_from_env();
let mut quiet = false;
let mut tokens: Vec<String> = Vec::new();
let mut in_pipeline = false;
for arg in std::env::args().skip(1) {
if !in_pipeline && arg.starts_with('-') && arg != "-" {
match arg.as_str() {
"-q" | "--quiet" => quiet = true,
"-e" | "--eos-on-shutdown" | "-m" | "--messages" | "-f" | "--no-fault" | "-t"
| "--tags" | "-v" | "--verbose" => {}
"-h" | "--help" => {
println!("{USAGE}");
return;
}
other => eprintln!("g2g-launch-py: ignoring unrecognized option '{other}'"),
}
continue;
}
in_pipeline = true;
tokens.push(arg);
}
let pipeline = tokens.join(" ");
if pipeline.trim().is_empty() {
eprintln!("{USAGE}");
process::exit(2);
}
if std::env::var_os("WAYLAND_DISPLAY").is_none() {
std::env::set_var("WAYLAND_DISPLAY", "wayland-0");
if !quiet {
eprintln!("WAYLAND_DISPLAY unset, defaulting to wayland-0");
}
}
let mut reg = default_registry();
g2g_python::register(&mut reg);
#[cfg(feature = "ml")]
g2g_ml::register(&mut reg);
let graph = match parse_launch(®, &pipeline) {
Ok(graph) => graph,
Err(err) => {
eprintln!("parse error: {err}");
process::exit(1);
}
};
let rt = tokio::runtime::Builder::new_current_thread()
.enable_time()
.build()
.expect("build tokio runtime");
if !quiet {
println!("Setting pipeline to PLAYING ...");
}
let clock = WallClock::new();
let progress = PipelineProgress::new();
let started = Instant::now();
let mut printed_status = false;
let result = rt.block_on(async {
let mut run = Box::pin(run_graph_with_progress(
graph,
&clock,
LINK_CAPACITY,
&progress,
None,
));
loop {
match tokio::time::timeout(Duration::from_secs(1), &mut run).await {
Ok(r) => break r,
Err(_elapsed) => {
if !quiet {
let pos = match progress.position() {
Some(ns) => format!("t={:.1}s", ns as f64 / 1.0e9),
None => String::from("prerolling"),
};
eprint!(
"\r running... {pos} ({:.0}s wall) ",
started.elapsed().as_secs_f64()
);
use std::io::Write;
let _ = std::io::stderr().flush();
printed_status = true;
}
}
}
}
});
if printed_status {
eprintln!();
}
match result {
Ok(stats) => {
if !quiet {
let elapsed = started.elapsed().as_secs_f64();
print!("{}", stats.report());
if elapsed > 0.0 {
println!(
" run: {:.2} s wall, {:.1} fps",
elapsed,
stats.frames_consumed as f64 / elapsed
);
}
}
}
Err(err) => {
eprintln!("pipeline error: {err:?}");
process::exit(1);
}
}
}