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