kithara_queue/queue/
access.rs1use kithara_audio::AudioObserver;
2use kithara_bufpool::HasPool;
3use kithara_events::{EventReceiver, EventSet, TrackId};
4use smallvec::SmallVec;
5
6use super::QueueControl;
7use crate::{
8 event::{QueueEvent, QueueRepeatMode},
9 navigation::{ActionAtItemEnd, PlaybackOrder, RepeatMode},
10 track::{TrackEntry, TrackRecord, TrackSource},
11};
12
13impl<S> QueueControl<S>
14where
15 S: HasPool<u8> + HasPool<f32> + Send + Sync + 'static,
16{
17 #[must_use]
18 pub fn action_at_item_end(&self) -> ActionAtItemEnd {
19 *self
20 .action_at_item_end
21 .lock()
22 .unwrap_or_else(std::sync::PoisonError::into_inner)
23 }
24
25 #[must_use]
34 pub fn current(&self) -> Option<TrackEntry> {
35 let id = self.lock_navigation().current()?;
36 self.track(id)
37 }
38
39 #[must_use]
41 pub fn current_index(&self) -> Option<usize> {
42 let idx = self.player.current_index();
43 if idx < self.len() { Some(idx) } else { None }
44 }
45
46 pub fn set_action_at_item_end(&self, action: ActionAtItemEnd) {
47 self.command(|queue| {
48 *queue
49 .action_at_item_end
50 .lock()
51 .unwrap_or_else(std::sync::PoisonError::into_inner) = action;
52 queue
53 .bus
54 .publish(QueueEvent::ActionAtItemEndChanged { action });
55 });
56 }
57
58 pub fn set_playback_order(&self, order: PlaybackOrder) {
59 self.command(|queue| {
60 let ids = queue
61 .tracks()
62 .into_iter()
63 .map(|track| track.id)
64 .collect::<SmallVec<[_; 16]>>();
65 queue.lock_navigation_mut().set_playback_order(order, &ids);
66 queue
67 .bus
68 .publish(QueueEvent::PlaybackOrderChanged { order });
69 });
70 }
71
72 pub fn set_repeat(&self, mode: RepeatMode) {
74 self.command(|queue| {
75 queue.lock_navigation_mut().set_repeat(mode);
76 queue.bus.publish(QueueEvent::RepeatModeChanged {
77 mode: map_repeat_mode(mode),
78 });
79 });
80 }
81
82 #[must_use]
86 pub fn subscribe<E: EventSet>(&self) -> EventReceiver<E> {
87 self.bus.subscribe()
88 }
89
90 #[must_use]
92 pub fn track(&self, id: TrackId) -> Option<TrackEntry> {
93 self.lock_tracks()
94 .iter()
95 .find(|r| r.id == id)
96 .map(TrackRecord::entry)
97 }
98
99 #[must_use]
102 pub fn track_source(&self, id: TrackId) -> Option<TrackSource<S>> {
103 self.tracks.source(id)
104 }
105
106 delegate::delegate! {
107 to self.loader {
108 pub fn attach_observer<O: AudioObserver>(&self, id: TrackId, observer: O);
113 }
114 to self.player {
115 #[must_use]
120 pub fn current_abr_handle(&self) -> Option<kithara_abr::AbrHandle>;
121 #[must_use]
124 pub fn sample_rate(&self) -> u32;
125 }
126 to self {
127 #[must_use]
132 #[expr($?.current_variant())]
133 #[call(current_abr_handle)]
134 pub fn current_variant(&self) -> Option<kithara_abr::VariantInfo>;
135 #[must_use]
137 #[expr($.is_empty())]
138 #[call(lock_tracks)]
139 pub fn is_empty(&self) -> bool;
140 #[must_use]
142 #[expr($.playback_order())]
143 #[call(lock_navigation)]
144 pub fn playback_order(&self) -> PlaybackOrder;
145 #[must_use]
147 #[expr($.len())]
148 #[call(lock_tracks)]
149 pub fn len(&self) -> usize;
150 #[must_use]
152 #[expr($.repeat_mode())]
153 #[call(lock_navigation)]
154 pub fn repeat_mode(&self) -> RepeatMode;
155 #[must_use]
157 #[expr($.iter().map(TrackRecord::entry).collect())]
158 #[call(lock_tracks)]
159 pub fn tracks(&self) -> Vec<TrackEntry>;
160 }
161 }
162}
163
164const fn map_repeat_mode(mode: RepeatMode) -> QueueRepeatMode {
165 match mode {
166 RepeatMode::Off => QueueRepeatMode::Off,
167 RepeatMode::One => QueueRepeatMode::One,
168 RepeatMode::All => QueueRepeatMode::All,
169 }
170}