82 lines · 2.7 KB · Rust
RawDownload
use anyhow::{Result, bail};use ranim::{    Output, Scene,    cmd::{render_scene, render_scene_once},};use tracing::{error, info}; use crate::{RanimUserLibrary, cli::CliArgs, load_user_library}; /// Load the user library and collect its scenes.////// The returned [`RanimUserLibrary`] must be kept alive for as long as the/// scenes are used: `Scene::constructor` is a function pointer into the/// dylib, so dropping the library unmaps the code it points to.fn load_scenes(args: &CliArgs) -> Result<(RanimUserLibrary, Vec<Scene>)> {    let lib = load_user_library(args)?;    let scenes = lib.scenes().collect();    Ok((lib, scenes))} /// Render every `#[output(...)]` declared by the selected scenes.pub fn output_command(args: &CliArgs, scenes: &[String], buffer_count: usize) -> Result<()> {    let (_lib, all_scenes) = load_scenes(args)?;    let scenes_to_render: Vec<&Scene> = if scenes.is_empty() {        all_scenes.iter().collect()    } else {        all_scenes            .iter()            .filter(|scene| scenes.iter().any(|s| s == &scene.name))            .collect()    };     if scenes_to_render.is_empty() {        if scenes.is_empty() {            info!("No scenes found to render");        } else {            error!("No matching scenes found for: {scenes:?}");            error!(                "Available scenes: {:?}",                all_scenes.iter().map(|s| &s.name).collect::<Vec<_>>()            );        }        bail!("No scenes to render");    }     for scene in scenes_to_render {        info!("Rendering scene: {}", scene.name);        render_scene(scene, buffer_count);    }    Ok(())} /// Render a single scene once with default output settings/// (`1920x1080`, 60 fps, mp4). Unlike [`output_command`], this command does/// not read any `#[output(...)]` declaration and does not process/// `TimeMark::Capture`.pub fn render_command(args: &CliArgs, scene_name: &str, buffer_count: usize) -> Result<()> {    let (_lib, all_scenes) = load_scenes(args)?;     let Some(scene) = all_scenes.iter().find(|scene| scene.name == scene_name) else {        error!("No matching scene found for: {scene_name:?}");        error!(            "Available scenes: {:?}",            all_scenes.iter().map(|s| &s.name).collect::<Vec<_>>()        );        bail!("No scene to render");    };     let output = Output::default();    info!(        "Rendering scene {:?} once with default output: {}x{} {}fps {}",        scene.name, output.width, output.height, output.fps, output.format    );    render_scene_once(        scene.constructor,        scene.name.clone(),        &scene.config,        &output,        buffer_count,    );    Ok(())}