Skip to content

Commit 2a5f698

Browse files
committed
Refactor to use ConnectConfig for opting in to SetQueue events
1 parent 5bf1c5b commit 2a5f698

5 files changed

Lines changed: 23 additions & 58 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1010
### Added
1111

1212
- [connect] Add method `add_to_queue` to `Spirc` to add tracks, episodes, albums and playlists to the queue
13-
- [playback] Add `SetQueue` player event (opt-in), emitting when the queue changes (context loaded, track added to queue, or queue set via Spotify Connect)
13+
- [playback] Add `SetQueue` player event, emitting when the queue changes (context loaded, track added to queue, or queue set via Spotify Connect). Gated behind `ConnectConfig::emit_set_queue_events`
1414

1515
### Changed
1616

connect/src/spirc.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ struct SpircTask {
9595

9696
context_resolver: ContextResolver,
9797

98+
emit_set_queue_events: bool,
99+
98100
shutdown: bool,
99101
session: Session,
100102

@@ -173,6 +175,7 @@ impl Spirc {
173175
let spirc_id = SPIRC_COUNTER.fetch_add(1, Ordering::AcqRel);
174176
debug!("new Spirc[{spirc_id}]");
175177

178+
let emit_set_queue_events = config.emit_set_queue_events;
176179
let connect_state = ConnectState::new(config, &session);
177180

178181
let connection_id_update = session
@@ -249,6 +252,8 @@ impl Spirc {
249252

250253
context_resolver: ContextResolver::new(session.clone()),
251254

255+
emit_set_queue_events,
256+
252257
shutdown: false,
253258
session,
254259

@@ -647,6 +652,10 @@ impl SpircTask {
647652

648653
/// Emit set queue event via PlayerEvent
649654
fn emit_set_queue_event(&self) {
655+
if !self.emit_set_queue_events {
656+
return;
657+
}
658+
650659
let context_uri = self.connect_state.context_uri().clone();
651660
let state_player = self.connect_state.player();
652661

connect/src/state.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ pub struct ConnectConfig {
9090
pub disable_volume: bool,
9191
/// Number of incremental steps (default: 64)
9292
pub volume_steps: u16,
93+
/// Emit `SetQueue` player events when the queue changes (default: false)
94+
pub emit_set_queue_events: bool,
9395
}
9496

9597
impl Default for ConnectConfig {
@@ -101,6 +103,7 @@ impl Default for ConnectConfig {
101103
initial_volume: u16::MAX / 2,
102104
disable_volume: false,
103105
volume_steps: 64,
106+
emit_set_queue_events: false,
104107
}
105108
}
106109
}

playback/src/player.rs

Lines changed: 7 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ struct PlayerInternal {
8080
sink_status: SinkStatus,
8181
sink_event_callback: Option<SinkEventCallback>,
8282
volume_getter: Box<dyn VolumeGetter + Send>,
83-
event_senders: Vec<EventSubscriber>,
83+
event_senders: Vec<mpsc::UnboundedSender<PlayerEvent>>,
8484
converter: Converter,
8585

8686
normalisation_integrators: [f64; 2],
@@ -113,10 +113,7 @@ enum PlayerCommand {
113113
Stop,
114114
Seek(u32),
115115
SetSession(Session),
116-
AddEventSender {
117-
sender: mpsc::UnboundedSender<PlayerEvent>,
118-
opt_in_events: OptInPlayerEvents,
119-
},
116+
AddEventSender(mpsc::UnboundedSender<PlayerEvent>),
120117
SetSinkEventCallback(Option<SinkEventCallback>),
121118
EmitVolumeChangedEvent(u16),
122119
SetAutoNormaliseAsAlbum(bool),
@@ -156,20 +153,6 @@ pub struct QueueTrack {
156153
pub provider: String,
157154
}
158155

159-
/// Opt-in player events that are not delivered to subscribers by default.
160-
///
161-
/// Use [`Player::get_player_event_channel_with`] to subscribe to these.
162-
#[derive(Clone, Copy, Debug, Default)]
163-
pub struct OptInPlayerEvents {
164-
/// Subscribe to [`PlayerEvent::SetQueue`] events.
165-
pub set_queue: bool,
166-
}
167-
168-
struct EventSubscriber {
169-
sender: mpsc::UnboundedSender<PlayerEvent>,
170-
opt_in_events: OptInPlayerEvents,
171-
}
172-
173156
#[derive(Debug, Clone)]
174157
pub enum PlayerEvent {
175158
// Play request id changed
@@ -321,14 +304,6 @@ impl PlayerEvent {
321304
_ => None,
322305
}
323306
}
324-
325-
/// Whether this event should be sent to a subscriber with the given opt-in events.
326-
fn should_send(&self, opt_in: &OptInPlayerEvents) -> bool {
327-
match self {
328-
PlayerEvent::SetQueue { .. } => opt_in.set_queue,
329-
_ => true,
330-
}
331-
}
332307
}
333308

334309
pub type PlayerEventChannel = mpsc::UnboundedReceiver<PlayerEvent>;
@@ -619,18 +594,8 @@ impl Player {
619594
}
620595

621596
pub fn get_player_event_channel(&self) -> PlayerEventChannel {
622-
self.get_player_event_channel_with(OptInPlayerEvents::default())
623-
}
624-
625-
pub fn get_player_event_channel_with(
626-
&self,
627-
opt_in_events: OptInPlayerEvents,
628-
) -> PlayerEventChannel {
629597
let (event_sender, event_receiver) = mpsc::unbounded_channel();
630-
self.command(PlayerCommand::AddEventSender {
631-
sender: event_sender,
632-
opt_in_events,
633-
});
598+
self.command(PlayerCommand::AddEventSender(event_sender));
634599
event_receiver
635600
}
636601

@@ -2353,15 +2318,7 @@ impl PlayerInternal {
23532318

23542319
PlayerCommand::SetSession(session) => self.session = session,
23552320

2356-
PlayerCommand::AddEventSender {
2357-
sender,
2358-
opt_in_events,
2359-
} => {
2360-
self.event_senders.push(EventSubscriber {
2361-
sender,
2362-
opt_in_events,
2363-
});
2364-
}
2321+
PlayerCommand::AddEventSender(sender) => self.event_senders.push(sender),
23652322

23662323
PlayerCommand::SetSinkEventCallback(callback) => self.sink_event_callback = callback,
23672324

@@ -2462,12 +2419,8 @@ impl PlayerInternal {
24622419
}
24632420

24642421
fn send_event(&mut self, event: PlayerEvent) {
2465-
self.event_senders.retain(|sub| {
2466-
if !event.should_send(&sub.opt_in_events) {
2467-
return true; // keep subscriber, skip this event
2468-
}
2469-
sub.sender.send(event.clone()).is_ok()
2470-
});
2422+
self.event_senders
2423+
.retain(|sender| sender.send(event.clone()).is_ok());
24712424
}
24722425

24732426
fn load_track(
@@ -2573,7 +2526,7 @@ impl fmt::Debug for PlayerCommand {
25732526
PlayerCommand::Stop => f.debug_tuple("Stop").finish(),
25742527
PlayerCommand::Seek(position) => f.debug_tuple("Seek").field(&position).finish(),
25752528
PlayerCommand::SetSession(_) => f.debug_tuple("SetSession").finish(),
2576-
PlayerCommand::AddEventSender { .. } => f.debug_tuple("AddEventSender").finish(),
2529+
PlayerCommand::AddEventSender(_) => f.debug_tuple("AddEventSender").finish(),
25772530
PlayerCommand::SetSinkEventCallback(_) => {
25782531
f.debug_tuple("SetSinkEventCallback").finish()
25792532
}

src/main.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use librespot::{
1616
},
1717
dither,
1818
mixer::{self, MixerConfig, MixerFn},
19-
player::{OptInPlayerEvents, Player, coefficient_to_duration, duration_to_coefficient},
19+
player::{Player, coefficient_to_duration, duration_to_coefficient},
2020
},
2121
};
2222
use librespot_oauth::OAuthClientBuilder;
@@ -1534,6 +1534,7 @@ async fn get_setup() -> Setup {
15341534
initial_volume,
15351535
disable_volume,
15361536
volume_steps,
1537+
..ConnectConfig::default()
15371538
}
15381539
};
15391540

@@ -1994,9 +1995,8 @@ async fn main() {
19941995
});
19951996

19961997
if let Some(player_event_program) = setup.player_event_program.clone() {
1997-
let opt_in_events = OptInPlayerEvents { set_queue: true };
19981998
_event_handler = Some(EventHandler::new(
1999-
player.get_player_event_channel_with(opt_in_events),
1999+
player.get_player_event_channel(),
20002000
&player_event_program,
20012001
));
20022002

0 commit comments

Comments
 (0)