kithara_queue/event.rs
1use kithara_events::{Event, TrackId};
2
3/// Why queue navigation advanced away from the previous current track.
4#[derive(Clone, Copy, Debug, PartialEq, Eq)]
5pub enum AdvanceReason {
6 InitialLoad,
7 NaturalEof,
8 CrossfadePreArm,
9 UserSelect,
10 UserNext,
11 UserPrev,
12 TrackFailed,
13 RemovedCurrent,
14 Repeat,
15 Cancelled,
16}
17
18/// Queue repeat mode mirrored into the event surface.
19#[derive(Clone, Copy, Debug, PartialEq, Eq)]
20pub enum QueueRepeatMode {
21 Off,
22 One,
23 All,
24}
25
26/// Loading lifecycle of a track in the queue.
27#[derive(Clone, Debug, PartialEq, Eq)]
28pub enum TrackStatus {
29 /// Queued but loading has not started.
30 Pending,
31 /// Currently loading.
32 Loading,
33 /// Loading longer than the soft timeout.
34 Slow,
35 /// Loaded and ready for playback.
36 Loaded,
37 /// Loading failed. The string renders the underlying error.
38 Failed(String),
39 /// Consumed by the engine after playback — needs a fresh load before
40 /// it can be selected again.
41 Consumed,
42 /// In-flight load was overridden by a later [`Queue::select`] of a
43 /// different track. The slot is intentionally left unpopulated so
44 /// auto-advance does not flip onto a track the user explicitly
45 /// walked away from. An explicit `select(id)` from the user
46 /// re-engages this state and triggers a fresh load.
47 Cancelled,
48}
49
50/// Queue-level events emitted by `kithara-queue::Queue`.
51#[derive(Clone, Debug, Event)]
52pub enum QueueEvent {
53 /// A new track was appended / inserted at `index`.
54 TrackAdded {
55 id: TrackId,
56 index: usize,
57 },
58 /// A track was removed from the queue.
59 TrackRemoved {
60 id: TrackId,
61 },
62 /// A track's loading status changed.
63 TrackStatusChanged {
64 id: TrackId,
65 status: TrackStatus,
66 },
67 /// The currently playing track changed.
68 CurrentTrackChanged {
69 id: Option<TrackId>,
70 },
71 /// Why the current track advanced.
72 CurrentTrackAdvance {
73 id: Option<TrackId>,
74 reason: AdvanceReason,
75 },
76 /// Queue reached the end and is not repeating.
77 QueueEnded,
78 /// The current track failed to load or continue, and the queue may have skipped it.
79 TrackLoadFailed {
80 id: TrackId,
81 reason: String,
82 auto_skipped: bool,
83 },
84 CrossfadeSettingsChanged {
85 settings: crate::CrossfadeSettings,
86 },
87 PlaybackOrderChanged {
88 order: crate::PlaybackOrder,
89 },
90 ActionAtItemEndChanged {
91 action: crate::ActionAtItemEnd,
92 },
93 /// Repeat mode changed.
94 RepeatModeChanged {
95 mode: QueueRepeatMode,
96 },
97 /// A successor finished loading and is ready for navigation / handover.
98 NextTrackReady {
99 id: TrackId,
100 index: usize,
101 },
102 /// A crossfade between tracks just started. Emitted when
103 /// [`Queue::select`](https://docs.rs/kithara-queue) triggers the engine
104 /// to fade from a currently-playing track to the newly selected one.
105 /// UIs can inspect the exact profile captured for this transition.
106 CrossfadeStarted {
107 settings: crate::CrossfadeSettings,
108 },
109}
110
111#[derive(Clone, Debug, Event)]
112pub enum ItemEvent {
113 PlaybackLikelyToKeepUp,
114 PlaybackStalled,
115}
116
117#[cfg(test)]
118mod tests {
119 use kithara_test_utils::kithara;
120
121 use super::*;
122
123 #[kithara::test]
124 fn queue_and_item_events_are_owned_by_kithara_queue() {
125 assert_eq!(
126 ::core::any::type_name::<QueueEvent>(),
127 "kithara_queue::event::QueueEvent"
128 );
129 assert_eq!(
130 ::core::any::type_name::<ItemEvent>(),
131 "kithara_queue::event::ItemEvent"
132 );
133 }
134}