ass_renderer/debug/player/
testing.rs1use super::{TestPoint, TestReport};
2use crate::RenderError;
3use ass_core::parser::Script;
4
5#[cfg(not(feature = "nostd"))]
6use std::time::{Duration, Instant};
7
8#[cfg(feature = "nostd")]
9use alloc::vec::Vec;
10
11impl super::DebugPlayer {
12 pub fn run_automatic_test(&mut self, test_points: Vec<u32>) -> Result<TestReport, RenderError> {
13 let script_content = self
14 .script_content
15 .as_ref()
16 .ok_or_else(|| RenderError::InvalidInput("No script loaded".into()))?;
17
18 let script = Script::parse(script_content)
19 .map_err(|e| RenderError::ParseError(format!("Failed to parse script: {e:?}")))?;
20
21 let mut report = TestReport {
22 test_points: Vec::new(),
23 total_render_time: Duration::ZERO,
24 frames_with_content: 0,
25 frames_empty: 0,
26 average_render_time_ms: 0.0,
27 };
28
29 println!(
30 "\n🧪 Running automatic test at {} points",
31 test_points.len()
32 );
33
34 for time_ms in test_points {
35 println!(" Testing at {time_ms}ms...");
36
37 let start = Instant::now();
38 let time_cs = time_ms / 10;
40 let frame = self.renderer.render_frame(&script, time_cs)?;
41 let render_time = start.elapsed();
42
43 let pixels = frame.pixels();
44 let mut has_content = false;
45
46 for chunk in pixels.chunks(4) {
47 if chunk.len() == 4 && chunk[3] > 0 {
48 has_content = true;
49 break;
50 }
51 }
52
53 if has_content {
54 report.frames_with_content += 1;
55 } else {
56 report.frames_empty += 1;
57 }
58
59 report.test_points.push(TestPoint {
60 timestamp_ms: time_ms,
61 render_time,
62 has_visible_content: has_content,
63 });
64
65 report.total_render_time += render_time;
66 }
67
68 if !report.test_points.is_empty() {
69 report.average_render_time_ms =
70 report.total_render_time.as_secs_f64() * 1000.0 / report.test_points.len() as f64;
71 }
72
73 report.print_summary();
74
75 Ok(report)
76 }
77}