1use web_time::Instant;
2
3use repose_core::{Color, Rect, Scene, SceneNode};
4
5pub struct Hud {
6 pub inspector_enabled: bool,
7 pub hovered: Option<Rect>,
8 frame_count: u64,
9 last_frame: Option<Instant>,
10 fps_smooth: f32,
11 pub metrics: Option<Metrics>,
12}
13
14impl Default for Hud {
15 fn default() -> Self {
16 Self::new()
17 }
18}
19
20impl Hud {
21 pub fn new() -> Self {
22 Self {
23 inspector_enabled: false,
24 hovered: None,
25 frame_count: 0,
26 last_frame: None,
27 fps_smooth: 0.0,
28 metrics: None,
29 }
30 }
31 pub fn toggle_inspector(&mut self) {
32 self.inspector_enabled = !self.inspector_enabled;
33 }
34 pub fn set_hovered(&mut self, r: Option<Rect>) {
35 self.hovered = r;
36 }
37
38 pub fn overlay(&mut self, scene: &mut Scene) {
39 self.frame_count += 1;
40 let now = Instant::now();
42 if let Some(prev) = self.last_frame.replace(now) {
43 let dt = (now - prev).as_secs_f32();
44 if dt > 0.0 {
45 let fps = 1.0 / dt;
46 let a = 0.2;
48 self.fps_smooth = if self.fps_smooth == 0.0 {
49 fps
50 } else {
51 (1.0 - a) * self.fps_smooth + a * fps
52 };
53 }
54 }
55 let mut lines = vec![
56 format!("frame: {}", self.frame_count),
57 format!("fps: {:.1}", self.fps_smooth),
58 ];
59 if let Some(m) = &self.metrics {
60 lines.push(format!("build+layout: {:.2} ms", m.build_layout_ms));
61 lines.push(format!("nodes: {}", m.scene_nodes));
62 }
63 let text = lines.join(" | ");
64 scene.nodes.push(SceneNode::Text {
65 rect: Rect {
66 x: 8.0,
67 y: 8.0,
68 w: 200.0,
69 h: 16.0,
70 },
71 text,
72 color: Color::from_hex("#AAAAAA"),
73 size: 14.0,
74 });
75
76 if let Some(r) = self.hovered {
77 scene.nodes.push(SceneNode::Border {
78 rect: r,
79 color: Color::from_hex("#44AAFF"),
80 width: 2.0,
81 radius: 0.0,
82 });
83 }
84 }
85}
86
87#[derive(Clone, Debug, Default)]
88pub struct Metrics {
89 pub build_layout_ms: f32,
90 pub scene_nodes: usize,
91}
92
93pub struct Inspector {
94 pub hud: Hud,
95}
96impl Default for Inspector {
97 fn default() -> Self {
98 Self::new()
99 }
100}
101
102impl Inspector {
103 pub fn new() -> Self {
104 Self { hud: Hud::new() }
105 }
106 pub fn frame(&mut self, scene: &mut Scene) {
107 if self.hud.inspector_enabled {
108 self.hud.overlay(scene);
109 }
110 }
111}