1use std::sync::mpsc::{self, Sender, TryRecvError};
2use std::sync::Arc;
3use std::thread;
4use std::time::Duration;
5
6use crate::event::FmEvents;
7
8pub struct Refresher {
10 tx: mpsc::Sender<()>,
12 handle: thread::JoinHandle<()>,
14}
15
16impl Refresher {
17 const TEN_SECONDS_IN_CENTISECONDS: u16 = 10 * 100;
19
20 pub fn new(fm_sender: Arc<Sender<FmEvents>>) -> Self {
27 let (tx, rx) = mpsc::channel();
28 let mut counter = Counter::default();
30 let handle = thread::spawn(move || loop {
31 match rx.try_recv() {
32 Ok(_) | Err(TryRecvError::Disconnected) => {
33 return;
34 }
35 Err(TryRecvError::Empty) => {}
36 }
37 counter.incr();
38 thread::sleep(Duration::from_millis(10));
39 let event = counter.pick_according_to_counter();
40 if fm_sender.send(event).is_err() {
41 break;
42 }
43 });
44 Self { tx, handle }
45 }
46
47 pub fn quit(self) {
50 let _ = self.tx.send(());
51 let _ = self.handle.join();
52 }
53}
54
55#[derive(Default)]
56struct Counter {
57 counter: u16,
58}
59
60impl Counter {
61 fn pick_according_to_counter(&mut self) -> FmEvents {
62 if self.counter >= Refresher::TEN_SECONDS_IN_CENTISECONDS {
63 self.counter = 0;
64 FmEvents::Refresh
65 } else {
66 FmEvents::UpdateTick
67 }
68 }
69
70 fn incr(&mut self) {
71 self.counter += 1;
72 }
73}