Skip to main content

selene_daemon/
event_handler.rs

1use std::{
2    sync::{
3        atomic::Ordering,
4        mpsc::{Receiver, Sender, channel},
5    },
6    thread,
7};
8
9use lunar_lib::trace;
10
11use crate::{
12    PlayerEvent, SHUTDOWN,
13    listener::{IpcListener, Listener},
14    player::{PlayerError, PlayerRequest},
15};
16
17pub struct EventHandler {
18    rx: Receiver<PlayerEvent>,
19
20    listener_tx: Sender<PlayerEvent>,
21
22    #[cfg(feature = "mpris")]
23    mpris_tx: tokio::sync::mpsc::Sender<crate::mpris::MprisEvent>,
24}
25
26impl EventHandler {
27    pub fn open(player_tx: Sender<PlayerRequest>) -> Result<Sender<PlayerEvent>, PlayerError> {
28        let (tx, rx) = channel();
29
30        let listener_tx = Listener::open(player_tx.clone())?;
31
32        #[cfg(feature = "mpris")]
33        let mpris_tx = crate::mpris::MprisConnector::open(player_tx);
34
35        let event_handler = Self {
36            rx,
37
38            listener_tx,
39
40            #[cfg(feature = "mpris")]
41            mpris_tx,
42        };
43
44        thread::spawn(move || {
45            event_handler.run();
46            SHUTDOWN.store(true, Ordering::Relaxed);
47        });
48
49        Ok(tx)
50    }
51
52    fn run(self) {
53        while let Ok(event) = self.rx.recv() {
54            trace!("Sending event: {event}");
55
56            let _ = self.listener_tx.send(event.clone());
57
58            #[cfg(feature = "mpris")]
59            {
60                use crate::mpris::MprisEvent;
61
62                let mpris_event = match event {
63                    PlayerEvent::CurrentlyPlayingChanged {
64                        ref currently_playing,
65                    } => Some(MprisEvent::CurrentlyPlayingChanged {
66                        currently_playing: currently_playing.clone(),
67                    }),
68                    PlayerEvent::PlaybackIsPlayingChanged {
69                        is_playing,
70                        changed_at,
71                    } => Some(MprisEvent::IsPlayingChanged {
72                        is_playing,
73                        changed_at,
74                    }),
75                    PlayerEvent::ShuffleModeChanged { shuffle_mode } => {
76                        Some(MprisEvent::ShuffleStatusChanged { shuffle_mode })
77                    }
78                    PlayerEvent::LoopModeChanged { loop_mode } => {
79                        Some(MprisEvent::LoopStatusChanged { loop_mode })
80                    }
81                    PlayerEvent::VolumeChanged { volume } => {
82                        Some(MprisEvent::VolumeChanged { volume })
83                    }
84                    PlayerEvent::SeekOccured { time } => Some(MprisEvent::Seeked { time }),
85                    _ => None,
86                };
87
88                if let Some(mpris_event) = mpris_event {
89                    let _ = self.mpris_tx.blocking_send(mpris_event);
90                }
91            }
92        }
93    }
94}
95
96pub trait EventTx {
97    fn event(&self, event: PlayerEvent);
98}
99
100impl EventTx for Sender<PlayerEvent> {
101    fn event(&self, event: PlayerEvent) {
102        let _ = self.send(event);
103    }
104}