atagen

monolith

public
Star0
Watch0
bbe43ba0672cbfcedfad26dfaad96b449f09970d
1
ssh://brewery@pls.lobotomise.me:33/atagen/monolith.git

Blame: crates/planner/examples/filmstrip.rs

b563d2da1c80atagen2026-10-16 08:25 UTC1
//! Renders a plan's keyframes side by side as SVG.
b563d2da1c80atagen2026-10-16 08:25 UTC2
//!
b563d2da1c80atagen2026-10-16 08:25 UTC3
//! `cargo run -p monolith-planner --example filmstrip -- swap > swap.svg`
b563d2da1c80atagen2026-10-16 08:25 UTC4
b563d2da1c80atagen2026-10-16 08:25 UTC5
use monolith_planner::{Config, Rect, Style, plan};
b563d2da1c80atagen2026-10-16 08:25 UTC6
b563d2da1c80atagen2026-10-16 08:25 UTC7
const W: f64 = 320.0;
b563d2da1c80atagen2026-10-16 08:25 UTC8
const H: f64 = 200.0;
b563d2da1c80atagen2026-10-16 08:25 UTC9
const G: f64 = 6.0;
b563d2da1c80atagen2026-10-16 08:25 UTC10
const COLOURS: [&str; 6] = [
b563d2da1c80atagen2026-10-16 08:25 UTC11
    "#e0774a", "#4aa3e0", "#7bc96f", "#c77be0", "#e0c24a", "#4ae0c2",
b563d2da1c80atagen2026-10-16 08:25 UTC12
];
b563d2da1c80atagen2026-10-16 08:25 UTC13
b563d2da1c80atagen2026-10-16 08:25 UTC14
fn cols(n: usize) -> Vec<Rect> {
b563d2da1c80atagen2026-10-16 08:25 UTC15
    let w = (W - G * (n + 1) as f64) / n as f64;
b563d2da1c80atagen2026-10-16 08:25 UTC16
    (0..n)
b563d2da1c80atagen2026-10-16 08:25 UTC17
        .map(|i| Rect::new(G + i as f64 * (w + G), G, w, H - 2.0 * G))
b563d2da1c80atagen2026-10-16 08:25 UTC18
        .collect()
b563d2da1c80atagen2026-10-16 08:25 UTC19
}
b563d2da1c80atagen2026-10-16 08:25 UTC20
b563d2da1c80atagen2026-10-16 08:25 UTC21
fn rows(n: usize) -> Vec<Rect> {
b563d2da1c80atagen2026-10-16 08:25 UTC22
    let h = (H - G * (n + 1) as f64) / n as f64;
b563d2da1c80atagen2026-10-16 08:25 UTC23
    (0..n)
b563d2da1c80atagen2026-10-16 08:25 UTC24
        .map(|i| Rect::new(G, G + i as f64 * (h + G), W - 2.0 * G, h))
b563d2da1c80atagen2026-10-16 08:25 UTC25
        .collect()
b563d2da1c80atagen2026-10-16 08:25 UTC26
}
b563d2da1c80atagen2026-10-16 08:25 UTC27
b563d2da1c80atagen2026-10-16 08:25 UTC28
fn scenario(name: &str) -> Option<(Vec<Rect>, Vec<Rect>)> {
b563d2da1c80atagen2026-10-16 08:25 UTC29
    Some(match name {
b563d2da1c80atagen2026-10-16 08:25 UTC30
        "swap" => {
b563d2da1c80atagen2026-10-16 08:25 UTC31
            let c = cols(2);
b563d2da1c80atagen2026-10-16 08:25 UTC32
            (c.clone(), vec![c[1], c[0]])
b563d2da1c80atagen2026-10-16 08:25 UTC33
        }
b563d2da1c80atagen2026-10-16 08:25 UTC34
        "reverse" => {
b563d2da1c80atagen2026-10-16 08:25 UTC35
            let c = cols(4);
b563d2da1c80atagen2026-10-16 08:25 UTC36
            (c.clone(), c.iter().rev().copied().collect())
b563d2da1c80atagen2026-10-16 08:25 UTC37
        }
b563d2da1c80atagen2026-10-16 08:25 UTC38
        "flip" => (cols(3), rows(3)),
b563d2da1c80atagen2026-10-16 08:25 UTC39
        _ => return None,
b563d2da1c80atagen2026-10-16 08:25 UTC40
    })
b563d2da1c80atagen2026-10-16 08:25 UTC41
}
b563d2da1c80atagen2026-10-16 08:25 UTC42
b563d2da1c80atagen2026-10-16 08:25 UTC43
fn main() {
b563d2da1c80atagen2026-10-16 08:25 UTC44
    let name = std::env::args().nth(1).unwrap_or_else(|| "swap".into());
b563d2da1c80atagen2026-10-16 08:25 UTC45
    let Some((from, to)) = scenario(&name) else {
b563d2da1c80atagen2026-10-16 08:25 UTC46
        eprintln!("scenarios: swap, reverse, flip");
b563d2da1c80atagen2026-10-16 08:25 UTC47
        std::process::exit(2);
b563d2da1c80atagen2026-10-16 08:25 UTC48
    };
b563d2da1c80atagen2026-10-16 08:25 UTC49
    let cfg = Config {
b563d2da1c80atagen2026-10-16 08:25 UTC50
        style: Style::Orthogonal,
b563d2da1c80atagen2026-10-16 08:25 UTC51
        gap: G,
b563d2da1c80atagen2026-10-16 08:25 UTC52
        ..Config::default()
b563d2da1c80atagen2026-10-16 08:25 UTC53
    };
b563d2da1c80atagen2026-10-16 08:25 UTC54
    let p = plan(&from, &to, &cfg);
b563d2da1c80atagen2026-10-16 08:25 UTC55
    let frames = p.keyframes.len() as f64;
b563d2da1c80atagen2026-10-16 08:25 UTC56
    println!(
b563d2da1c80atagen2026-10-16 08:25 UTC57
        r#"<svg xmlns="http://www.w3.org/2000/svg" width="{}" height="{}" style="background:#111317">"#,
b563d2da1c80atagen2026-10-16 08:25 UTC58
        frames * (W + 20.0),
b563d2da1c80atagen2026-10-16 08:25 UTC59
        H + 40.0
b563d2da1c80atagen2026-10-16 08:25 UTC60
    );
b563d2da1c80atagen2026-10-16 08:25 UTC61
    for (k, frame) in p.keyframes.iter().enumerate() {
b563d2da1c80atagen2026-10-16 08:25 UTC62
        let ox = k as f64 * (W + 20.0);
b563d2da1c80atagen2026-10-16 08:25 UTC63
        println!(r##"<rect x="{ox}" y="0" width="{W}" height="{H}" fill="#1b1e25"/>"##);
b563d2da1c80atagen2026-10-16 08:25 UTC64
        for (i, r) in frame.iter().enumerate() {
b563d2da1c80atagen2026-10-16 08:25 UTC65
            if r.w > 0.5 && r.h > 0.5 {
b563d2da1c80atagen2026-10-16 08:25 UTC66
                println!(
b563d2da1c80atagen2026-10-16 08:25 UTC67
                    r#"<rect x="{}" y="{}" width="{}" height="{}" rx="4" fill="{}"/>"#,
b563d2da1c80atagen2026-10-16 08:25 UTC68
                    ox + r.x,
b563d2da1c80atagen2026-10-16 08:25 UTC69
                    r.y,
b563d2da1c80atagen2026-10-16 08:25 UTC70
                    r.w,
b563d2da1c80atagen2026-10-16 08:25 UTC71
                    r.h,
b563d2da1c80atagen2026-10-16 08:25 UTC72
                    COLOURS[i % COLOURS.len()]
b563d2da1c80atagen2026-10-16 08:25 UTC73
                );
b563d2da1c80atagen2026-10-16 08:25 UTC74
            }
b563d2da1c80atagen2026-10-16 08:25 UTC75
        }
b563d2da1c80atagen2026-10-16 08:25 UTC76
        println!(
b563d2da1c80atagen2026-10-16 08:25 UTC77
            r##"<text x="{}" y="{}" fill="#8a909c" font-family="sans-serif" font-size="13">keyframe {k}</text>"##,
b563d2da1c80atagen2026-10-16 08:25 UTC78
            ox + 4.0,
b563d2da1c80atagen2026-10-16 08:25 UTC79
            H + 18.0
b563d2da1c80atagen2026-10-16 08:25 UTC80
        );
b563d2da1c80atagen2026-10-16 08:25 UTC81
    }
b563d2da1c80atagen2026-10-16 08:25 UTC82
    println!(
b563d2da1c80atagen2026-10-16 08:25 UTC83
        r##"<text x="4" y="{}" fill="#8a909c" font-family="sans-serif" font-size="13">{name}: {:?}</text>"##,
b563d2da1c80atagen2026-10-16 08:25 UTC84
        H + 34.0,
b563d2da1c80atagen2026-10-16 08:25 UTC85
        p.groups.iter().map(|g| g.strategy).collect::<Vec<_>>()
b563d2da1c80atagen2026-10-16 08:25 UTC86
    );
b563d2da1c80atagen2026-10-16 08:25 UTC87
    println!("</svg>");
b563d2da1c80atagen2026-10-16 08:25 UTC88
}