Add clear and pause-after REPL commands

This commit is contained in:
NGnius (Graham) 2023-10-29 17:40:48 -04:00
parent c7d3b2582e
commit 9a3919754e
5 changed files with 72 additions and 1 deletions

View file

@ -38,6 +38,7 @@ enum DbusControl {
Die, Die,
SetMetadata(Metadata), SetMetadata(Metadata),
SetPosition(i64), SetPosition(i64),
SetPlaybackMode(PlaybackStatus),
} }
#[cfg(all(target_os = "linux", feature = "os-controls", feature = "mpris-player"))] #[cfg(all(target_os = "linux", feature = "os-controls", feature = "mpris-player"))]
@ -149,6 +150,9 @@ impl SystemControlWrapper {
} }
Ok(DbusControl::SetPosition(pos)) => { Ok(DbusControl::SetPosition(pos)) => {
dbus_conn.set_position(pos); dbus_conn.set_position(pos);
},
Ok(DbusControl::SetPlaybackMode(mode)) => {
dbus_conn.set_playback_status(mode);
} }
} }
} }
@ -259,6 +263,9 @@ impl SystemControlWrapper {
dbus_ctrl dbus_ctrl
.send(DbusControl::SetMetadata(Self::build_metadata(item, duration))) .send(DbusControl::SetMetadata(Self::build_metadata(item, duration)))
.unwrap_or(()); .unwrap_or(());
dbus_ctrl
.send(DbusControl::SetPlaybackMode(PlaybackStatus::Playing))
.unwrap_or(());
} }
fn empty(dbus_ctrl: &Sender<DbusControl>) { fn empty(dbus_ctrl: &Sender<DbusControl>) {
@ -277,11 +284,17 @@ impl SystemControlWrapper {
url: None, url: None,
})) }))
.unwrap_or(()); .unwrap_or(());
dbus_ctrl
.send(DbusControl::SetPlaybackMode(PlaybackStatus::Stopped))
.unwrap_or(());
} }
fn time(item: Item, duration: &std::time::Duration, dbus_ctrl: &Sender<DbusControl>) { fn time(item: Item, duration: &std::time::Duration, dbus_ctrl: &Sender<DbusControl>) {
let meta = Self::build_metadata(item, Some(duration)); let meta = Self::build_metadata(item, Some(duration));
dbus_ctrl.send(DbusControl::SetMetadata(meta)).unwrap_or(()); dbus_ctrl.send(DbusControl::SetMetadata(meta)).unwrap_or(());
dbus_ctrl
.send(DbusControl::SetPlaybackMode(PlaybackStatus::Playing))
.unwrap_or(());
} }
fn time_update( fn time_update(
@ -300,6 +313,9 @@ impl SystemControlWrapper {
dbus_ctrl dbus_ctrl
.send(DbusControl::SetPosition(new_time * 1_000_000)) .send(DbusControl::SetPosition(new_time * 1_000_000))
.unwrap_or(()); .unwrap_or(());
dbus_ctrl
.send(DbusControl::SetPlaybackMode(PlaybackStatus::Playing))
.unwrap_or(());
} }
} }
} }
@ -344,6 +360,10 @@ impl super::EventTap for SystemControlWrapper {
state.duration_cache.get(item), state.duration_cache.get(item),
self.dbus_ctrl.as_ref().unwrap(), self.dbus_ctrl.as_ref().unwrap(),
); );
},
PlaybackAction::Paused => {
self.dbus_ctrl.as_ref().unwrap().send(DbusControl::SetPlaybackMode(PlaybackStatus::Paused))
.unwrap_or(());
} }
} }
None None

View file

@ -184,11 +184,15 @@ impl<I: std::iter::Iterator<Item = Result<Item, InterpreterError>>> PlayerServer
} }
} }
ControlAction::Play { .. } => self.player.resume(), ControlAction::Play { .. } => self.player.resume(),
ControlAction::Pause { .. } => self.player.pause(), ControlAction::Pause { .. } => {
self.playback.send(PlaybackAction::Paused).unwrap();
self.player.pause()
},
ControlAction::PlayPause { .. } => { ControlAction::PlayPause { .. } => {
if self.player.is_paused() { if self.player.is_paused() {
self.player.resume(); self.player.resume();
} else { } else {
self.playback.send(PlaybackAction::Paused).unwrap();
self.player.pause(); self.player.pause();
} }
} }
@ -321,6 +325,7 @@ pub enum PlaybackAction {
Enqueued(Item), Enqueued(Item),
Time(Item, std::time::Duration), Time(Item, std::time::Duration),
UpdateTick(Item, u64), // tick sent once every second UpdateTick(Item, u64), // tick sent once every second
Paused,
Exit, Exit,
} }

View file

@ -19,6 +19,7 @@ pub enum InterpreterDebugFlag {
Skip, Skip,
List, List,
Normal, Normal,
Pausing,
} }
#[derive(Clone)] #[derive(Clone)]
@ -205,6 +206,7 @@ impl EventTap for DebugEventHandler {
}, },
PlaybackAction::Time(_item, _dur) => {}, PlaybackAction::Time(_item, _dur) => {},
PlaybackAction::UpdateTick(_item, _tick) => {}, PlaybackAction::UpdateTick(_item, _tick) => {},
PlaybackAction::Paused => {},
} }
None None
} }

View file

@ -184,6 +184,9 @@ REPL-specific operations to help with writing Muss scripts: ?command
skip skip
Skip remaining items to be played. If no items are about to be played, skip all items in the next statement. This is a no-output version of ?list. Skip remaining items to be played. If no items are about to be played, skip all items in the next statement. This is a no-output version of ?list.
clear
Skip remaining items to be played, including the remainder of the current item. This is the immediate version of ?skip.
normal normal
Cancel any active ?skip or ?list operation. Cancel any active ?skip or ?list operation.
@ -196,6 +199,9 @@ REPL-specific operations to help with writing Muss scripts: ?command
pause pause
Immediate song control actions to apply to the current item. Immediate song control actions to apply to the current item.
pause-after
Pause playback after the current song completes.
volume number volume number
Set playback volume to number, in percent (starts at 100% when the cli parameter is not used). Set playback volume to number, in percent (starts at 100% when the cli parameter is not used).

View file

@ -165,6 +165,19 @@ pub fn repl(args: CliArgs) {
// NOTE: recursion occurs here // NOTE: recursion occurs here
} }
None None
},
crate::debug_state::InterpreterDebugFlag::Pausing => {
controller_debug_clone.control_tx
.lock()
.expect("Failed to get lock for control action sender")
.as_ref()
.expect("Control action sender shouldn't be None")
.send(muss_player::ControlAction::Pause { ack: false })
.expect("Failed to send control action");
if let Ok(mut d_state) = controller_debug_clone.interpreter.write() {
d_state.debug_flag = crate::debug_state::InterpreterDebugFlag::Normal;
}
item
} }
crate::debug_state::InterpreterDebugFlag::List => { crate::debug_state::InterpreterDebugFlag::List => {
if let Some(x) = item { if let Some(x) = item {
@ -665,6 +678,31 @@ fn repl_commands(command_str: &str, state: &mut ReplState, args: &CliArgs) {
debug_state.debug_flag = crate::debug_state::InterpreterDebugFlag::Skip; debug_state.debug_flag = crate::debug_state::InterpreterDebugFlag::Skip;
} }
writeln!(state.terminal, "Skipping upcoming items").expect(TERMINAL_WRITE_ERROR); writeln!(state.terminal, "Skipping upcoming items").expect(TERMINAL_WRITE_ERROR);
},
"?pause-after" => {
{
let mut debug_state = state.controller_debug.interpreter
.write()
.expect("Failed to get write lock for debug state");
debug_state.debug_flag = crate::debug_state::InterpreterDebugFlag::Pausing;
}
writeln!(state.terminal, "Pausing after current item").expect(TERMINAL_WRITE_ERROR);
},
"?clear" => {
{
let mut debug_state = state.controller_debug.interpreter
.write()
.expect("Failed to get write lock for debug state");
debug_state.debug_flag = crate::debug_state::InterpreterDebugFlag::Skip;
state.controller_debug.control_tx
.lock()
.expect("Failed to get lock for control action sender")
.as_ref()
.expect("Control action sender shouldn't be None")
.send(muss_player::ControlAction::Next { ack: false })
.expect("Failed to send control action");
}
writeln!(state.terminal, "Clearing upcoming items").expect(TERMINAL_WRITE_ERROR);
} }
"?normal" => { "?normal" => {
{ {