dump_schedule/
main.rs

1#![doc = include_str!("../README.md")]
2
3use std::io;
4use std::io::Write;
5use std::path::PathBuf;
6use std::process::{Command, Stdio};
7
8use clap::Parser;
9use valence::prelude::*;
10
11#[derive(Parser)]
12#[command(author, version, about)]
13struct Cli {
14    /// Name of the schedule to dump. If absent, the list of available
15    /// schedules is printed to stdout.
16    schedule: Option<String>,
17    /// Output SVG file path.
18    #[clap(short, long, default_value = "graph.svg")]
19    output: PathBuf,
20    /// Disables transitive reduction of the output schedule graph.
21    #[clap(short = 't', long)]
22    no_tred: bool,
23}
24
25fn main() -> io::Result<()> {
26    let cli = Cli::parse();
27
28    let mut app = App::new();
29
30    app.add_plugins(DefaultPlugins);
31
32    let schedules = app.world().resource::<Schedules>();
33
34    let Some(sched_name) = cli.schedule else {
35        print_available_schedules(schedules);
36        return Ok(());
37    };
38
39    let Some((_, schedule)) = schedules
40        .iter()
41        .find(|(label, _)| format!("{label:?}") == sched_name)
42    else {
43        eprintln!("Unknown schedule \"{sched_name}\"");
44        print_available_schedules(schedules);
45        std::process::exit(1)
46    };
47
48    let dot_graph = bevy_mod_debugdump::schedule_graph::schedule_graph_dot(
49        schedule,
50        app.world(),
51        &bevy_mod_debugdump::schedule_graph::Settings {
52            ambiguity_enable: false,
53            ..Default::default()
54        },
55    );
56
57    let mut dot_command = Command::new("dot");
58    dot_command.arg("-Tsvg").arg("-o").arg(cli.output);
59
60    if cli.no_tred {
61        let mut dot_child = dot_command.stdin(Stdio::piped()).spawn()?;
62
63        dot_child
64            .stdin
65            .as_mut()
66            .unwrap()
67            .write_all(dot_graph.as_bytes())?;
68
69        dot_child.wait_with_output()?;
70    } else {
71        let tred_child = Command::new("tred")
72            .stdin(Stdio::piped())
73            .stdout(Stdio::piped())
74            .spawn()?;
75
76        let dot_child = dot_command.stdin(tred_child.stdout.unwrap()).spawn()?;
77
78        tred_child.stdin.unwrap().write_all(dot_graph.as_bytes())?;
79
80        dot_child.wait_with_output()?;
81    };
82
83    Ok(())
84}
85
86fn print_available_schedules(schedules: &Schedules) {
87    eprintln!("==== Available Schedules ====");
88
89    for (label, _) in schedules.iter() {
90        println!("{label:?}");
91    }
92
93    eprintln!("\nSee `--help` for more information.");
94}