Skip to main content

koan_core/player/
commands.rs

1use std::path::PathBuf;
2
3use crossbeam_channel::{Receiver, Sender, bounded};
4
5use super::state::{PlaylistItem, QueueItemId};
6
7/// Commands from the UI layer to the audio engine.
8#[derive(Debug)]
9pub enum PlayerCommand {
10    /// Set cursor + start playback. Replaces Play/SkipTo/SkipBack/PlayInterrupt.
11    Play(QueueItemId),
12    Pause,
13    Resume,
14    Stop,
15    Seek(u64), // position in ms
16    NextTrack,
17    PrevTrack,
18    AddToPlaylist(Vec<PlaylistItem>),
19    RemoveFromPlaylist(QueueItemId),
20    /// Batch remove: delete multiple items as a single undoable operation.
21    RemoveFromPlaylistBatch(Vec<QueueItemId>),
22    MoveInPlaylist {
23        id: QueueItemId,
24        target: QueueItemId,
25        after: bool,
26    },
27    /// Batch move: extract `ids` and reinsert them at `target` position.
28    MoveItemsInPlaylist {
29        ids: Vec<QueueItemId>,
30        target: QueueItemId,
31        after: bool,
32    },
33    /// Update file paths for playlist items after an organize operation.
34    /// On Unix, rename() doesn't invalidate open FDs so playback continues.
35    UpdatePaths(Vec<(QueueItemId, PathBuf)>),
36    /// Insert items after a specific queue item (for drag/drop at cursor position).
37    InsertInPlaylist {
38        items: Vec<PlaylistItem>,
39        after: QueueItemId,
40    },
41    /// Clear the entire playlist (stop + remove all items).
42    ClearPlaylist,
43    /// Download complete — check if cursor is waiting on this item.
44    TrackReady(QueueItemId),
45    /// Enough data buffered for streaming playback — check if cursor is waiting.
46    TrackStreamReady(QueueItemId),
47    /// Decode thread exhausted the playlist — auto-advance or stop.
48    DecodeFinished,
49    /// Undo the last reversible playlist operation.
50    Undo,
51    /// Redo the last undone operation.
52    Redo,
53    /// Begin collecting undo entries into a single batch (e.g. drag operations).
54    BeginUndoBatch,
55    /// End the batch — collapse collected entries into one undo step.
56    EndUndoBatch,
57    /// Switch output audio device by name. Restarts engine on current track.
58    SetOutputDevice(String),
59    /// Clear the configured output device, reverting to system default.
60    ClearOutputDevice,
61}
62
63/// Bounded SPSC command channel.
64///
65/// Small capacity — we don't want commands queuing up. If the engine is busy,
66/// the UI should know about it, not silently buffer 50 seeks.
67pub struct CommandChannel {
68    pub tx: Sender<PlayerCommand>,
69    pub rx: Receiver<PlayerCommand>,
70}
71
72impl Default for CommandChannel {
73    fn default() -> Self {
74        Self::new()
75    }
76}
77
78impl CommandChannel {
79    pub fn new() -> Self {
80        let (tx, rx) = bounded(16);
81        Self { tx, rx }
82    }
83}