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

View file

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

View file

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

View file

@ -184,6 +184,9 @@ REPL-specific operations to help with writing Muss scripts: ?command
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.
clear
Skip remaining items to be played, including the remainder of the current item. This is the immediate version of ?skip.
normal
Cancel any active ?skip or ?list operation.
@ -196,6 +199,9 @@ REPL-specific operations to help with writing Muss scripts: ?command
pause
Immediate song control actions to apply to the current item.
pause-after
Pause playback after the current song completes.
volume number
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
}
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 => {
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;
}
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" => {
{