proteus_lib/diagnostics/
reporter.rs1use std::{
4 sync::{Arc, Mutex},
5 time::Duration,
6};
7
8use crate::playback::player::Player;
9
10#[derive(Clone, PartialEq)]
12pub struct Report {
13 pub time: f64,
14 pub volume: f32,
15 pub duration: f64,
16 pub playing: bool,
17}
18
19#[derive(Clone)]
21pub struct Reporter {
22 player: Arc<Mutex<Player>>,
23 report: Arc<Mutex<dyn Fn(Report) + Send>>,
24 interval: Duration,
25 finish: Arc<Mutex<bool>>,
26}
27
28impl Reporter {
29 pub fn new(
31 player: Arc<Mutex<Player>>,
32 report: Arc<Mutex<dyn Fn(Report) + Send>>,
33 interval: Duration,
34 ) -> Self {
35 Self {
36 player,
37 report,
38 interval,
39 finish: Arc::new(Mutex::new(false)),
40 }
41 }
42
43 fn run(&self) {
44 let mut last_report = Report {
45 time: 0.0,
46 volume: 0.0,
47 duration: 0.0,
48 playing: false,
49 };
50
51 loop {
52 let player = self.player.lock().unwrap();
53 let time = player.get_time();
54 let volume = player.get_volume();
55 let duration = player.get_duration();
56 let playing = player.is_playing();
57
58 let report = Report {
59 time,
60 volume,
61 duration,
62 playing,
63 };
64
65 drop(player);
66
67 if report != last_report {
68 (*self.report.lock().unwrap())(report.clone());
69 last_report = report;
70 }
71
72 if *self.finish.lock().unwrap() {
73 break;
74 }
75
76 std::thread::sleep(self.interval);
77 }
78 }
79
80 pub fn start(&self) {
82 let this = self.clone();
83 Some(std::thread::spawn(move || this.run()));
84 *self.finish.lock().unwrap() = false;
85 }
86
87 pub fn stop(&self) {
89 *self.finish.lock().unwrap() = true;
90 }
94}