Add clear and pause-after REPL commands
This commit is contained in:
parent
c7d3b2582e
commit
9a3919754e
5 changed files with 72 additions and 1 deletions
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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).
|
||||||
|
|
||||||
|
|
38
src/repl.rs
38
src/repl.rs
|
@ -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" => {
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue