1use crate::prelude::*;
4
5#[derive(Default)]
8pub struct Demo {
9 pub autoplay: bool,
10 pub frame: u64,
11 limit: Option<u64>,
12 #[cfg(not(target_arch = "wasm32"))]
13 screenshot: Option<String>,
14}
15
16impl Demo {
17 pub fn new() -> Self {
18 #[cfg(not(target_arch = "wasm32"))]
19 {
20 let mut demo = Self::default();
21 let mut args = std::env::args().skip(1);
22 while let Some(arg) = args.next() {
23 match arg.as_str() {
24 "--autoplay" => demo.autoplay = true,
25 "--smoke-frames" => {
26 demo.limit = Some(
27 args.next()
28 .and_then(|s| s.parse::<u64>().ok())
29 .filter(|n| *n > 0)
30 .expect("--smoke-frames requires a positive integer"),
31 );
32 }
33 "--screenshot" => {
34 demo.screenshot = Some(args.next().expect("--screenshot requires a path"))
35 }
36 "--help" => {
37 println!("Options: --autoplay --smoke-frames N --screenshot path.png");
38 std::process::exit(0);
39 }
40 _ => panic!("Unknown option: {arg}"),
41 }
42 }
43 demo
44 }
45 #[cfg(target_arch = "wasm32")]
46 Self {
47 autoplay: crate::autoplay_enabled(),
48 ..Self::default()
49 }
50 }
51
52 pub fn dt(&self) -> f32 {
54 if self.limit.is_some() {
55 1.0 / 60.0
56 } else {
57 get_frame_time().clamp(0.0, 0.1)
58 }
59 }
60
61 pub fn time(&self) -> f32 {
62 if self.limit.is_some() {
63 self.frame as f32 / 60.0
64 } else {
65 get_time() as f32
66 }
67 }
68
69 pub fn finish_frame(&mut self) -> bool {
71 self.frame += 1;
72 let finished = self.limit.is_some_and(|limit| self.frame >= limit);
73 #[cfg(not(target_arch = "wasm32"))]
74 if finished && let Some(path) = &self.screenshot {
75 get_screen_data().export_png(path);
76 }
77 finished
78 }
79}