Handle paused/stopped/play state, version bump

Version 0.2.19.
This commit is contained in:
Stephen Seo 2022-03-23 20:56:11 +09:00
parent 12d82ba770
commit 3299764ee1
5 changed files with 126 additions and 43 deletions

2
Cargo.lock generated
View file

@ -1551,7 +1551,7 @@ dependencies = [
[[package]] [[package]]
name = "mpd_info_screen" name = "mpd_info_screen"
version = "0.2.18" version = "0.2.19"
dependencies = [ dependencies = [
"ggez", "ggez",
"image 0.24.1", "image 0.24.1",

View file

@ -1,6 +1,6 @@
[package] [package]
name = "mpd_info_screen" name = "mpd_info_screen"
version = "0.2.18" version = "0.2.19"
edition = "2018" edition = "2018"
description = "Displays info on currently playing music from an MPD daemon" description = "Displays info on currently playing music from an MPD daemon"
license = "MIT" license = "MIT"

View file

@ -13,7 +13,7 @@ counter, and the filename currently being played
# Usage # Usage
mpd_info_screen 0.2.18 mpd_info_screen 0.2.19
USAGE: USAGE:
mpd_info_screen [FLAGS] [OPTIONS] <host> [port] mpd_info_screen [FLAGS] [OPTIONS] <host> [port]

View file

@ -1,5 +1,5 @@
use crate::debug_log::{self, log}; use crate::debug_log::{self, log};
use crate::mpd_handler::{InfoFromShared, MPDHandler, MPDHandlerState}; use crate::mpd_handler::{InfoFromShared, MPDHandler, MPDHandlerState, MPDPlayState};
use crate::Opt; use crate::Opt;
use ggez::event::{self, EventHandler}; use ggez::event::{self, EventHandler};
use ggez::graphics::{ use ggez::graphics::{
@ -77,6 +77,7 @@ pub struct MPDDisplay {
text_bg_mesh: Option<Mesh>, text_bg_mesh: Option<Mesh>,
hide_text: bool, hide_text: bool,
tried_album_art_in_dir: bool, tried_album_art_in_dir: bool,
mpd_play_state: MPDPlayState,
} }
impl MPDDisplay { impl MPDDisplay {
@ -109,6 +110,7 @@ impl MPDDisplay {
text_bg_mesh: None, text_bg_mesh: None,
hide_text: false, hide_text: false,
tried_album_art_in_dir: false, tried_album_art_in_dir: false,
mpd_play_state: MPDPlayState::Playing,
} }
} }
@ -573,12 +575,24 @@ impl EventHandler for MPDDisplay {
.mpd_handler .mpd_handler
.as_ref() .as_ref()
.unwrap() .unwrap()
.get_current_song_info() .get_mpd_handler_shared_state()
.ok(); .ok();
if let Some(shared) = &self.shared { if let Some(shared) = &self.shared {
if self.notice_text.contents() != shared.error_text { if self.notice_text.contents() != shared.error_text {
self.notice_text = Text::new(TextFragment::new(shared.error_text.clone())); self.notice_text = Text::new(TextFragment::new(shared.error_text.clone()));
} }
if shared.mpd_play_state != MPDPlayState::Playing {
if shared.mpd_play_state == MPDPlayState::Stopped {
self.title_text = Text::new("");
self.artist_text = Text::new("");
self.filename_text = Text::new("");
self.timer = 0.0;
self.length = 0.0;
self.album_art = None;
}
self.mpd_play_state = shared.mpd_play_state;
} else {
self.mpd_play_state = MPDPlayState::Playing;
if !shared.title.is_empty() { if !shared.title.is_empty() {
self.title_text = Text::new(shared.title.clone()); self.title_text = Text::new(shared.title.clone());
} else { } else {
@ -610,6 +624,7 @@ impl EventHandler for MPDDisplay {
self.timer = shared.pos; self.timer = shared.pos;
self.length = shared.length; self.length = shared.length;
self.refresh_text_transforms(ctx)?; self.refresh_text_transforms(ctx)?;
}
} else { } else {
log( log(
"Failed to acquire read lock for getting shared data", "Failed to acquire read lock for getting shared data",
@ -648,7 +663,10 @@ impl EventHandler for MPDDisplay {
fn draw(&mut self, ctx: &mut ggez::Context) -> Result<(), GameError> { fn draw(&mut self, ctx: &mut ggez::Context) -> Result<(), GameError> {
graphics::clear(ctx, Color::BLACK); graphics::clear(ctx, Color::BLACK);
if self.album_art.is_some() && self.album_art_draw_transform.is_some() { if self.mpd_play_state != MPDPlayState::Stopped
&& self.album_art.is_some()
&& self.album_art_draw_transform.is_some()
{
self.album_art.as_ref().unwrap().draw( self.album_art.as_ref().unwrap().draw(
ctx, ctx,
DrawParam { DrawParam {
@ -661,7 +679,8 @@ impl EventHandler for MPDDisplay {
if !self.hide_text { if !self.hide_text {
self.notice_text.draw(ctx, DrawParam::default())?; self.notice_text.draw(ctx, DrawParam::default())?;
if self.is_valid && self.is_initialized { if self.mpd_play_state != MPDPlayState::Stopped && self.is_valid && self.is_initialized
{
if let Some(mesh) = &self.text_bg_mesh { if let Some(mesh) = &self.text_bg_mesh {
mesh.draw(ctx, DrawParam::default())?; mesh.draw(ctx, DrawParam::default())?;
} }
@ -696,6 +715,7 @@ impl EventHandler for MPDDisplay {
)?; )?;
} }
if self.mpd_play_state == MPDPlayState::Playing {
self.timer_text.draw( self.timer_text.draw(
ctx, ctx,
DrawParam { DrawParam {
@ -705,6 +725,7 @@ impl EventHandler for MPDDisplay {
)?; )?;
} }
} }
}
graphics::present(ctx) graphics::present(ctx)
} }

View file

@ -11,7 +11,7 @@ const SLEEP_DURATION: Duration = Duration::from_millis(100);
const POLL_DURATION: Duration = Duration::from_secs(5); const POLL_DURATION: Duration = Duration::from_secs(5);
const BUF_SIZE: usize = 1024 * 4; const BUF_SIZE: usize = 1024 * 4;
#[derive(Debug, PartialEq, Copy, Clone)] #[derive(Debug, PartialEq, Eq, Copy, Clone)]
enum PollState { enum PollState {
None, None,
Password, Password,
@ -21,6 +21,13 @@ enum PollState {
ReadPictureInDir, ReadPictureInDir,
} }
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum MPDPlayState {
Playing,
Paused,
Stopped,
}
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct InfoFromShared { pub struct InfoFromShared {
pub filename: String, pub filename: String,
@ -29,6 +36,7 @@ pub struct InfoFromShared {
pub length: f64, pub length: f64,
pub pos: f64, pub pos: f64,
pub error_text: String, pub error_text: String,
pub mpd_play_state: MPDPlayState,
} }
#[derive(Clone)] #[derive(Clone)]
@ -66,6 +74,7 @@ pub struct MPDHandlerState {
dirty_flag: Arc<AtomicBool>, dirty_flag: Arc<AtomicBool>,
pub stop_flag: Arc<AtomicBool>, pub stop_flag: Arc<AtomicBool>,
log_level: LogLevel, log_level: LogLevel,
mpd_play_state: MPDPlayState,
} }
fn check_next_chars( fn check_next_chars(
@ -267,6 +276,7 @@ impl MPDHandler {
dirty_flag: Arc::new(AtomicBool::new(true)), dirty_flag: Arc::new(AtomicBool::new(true)),
stop_flag: Arc::new(AtomicBool::new(false)), stop_flag: Arc::new(AtomicBool::new(false)),
log_level, log_level,
mpd_play_state: MPDPlayState::Stopped,
})), })),
}; };
@ -285,7 +295,7 @@ impl MPDHandler {
Ok(s) Ok(s)
} }
pub fn get_current_song_info(&self) -> Result<InfoFromShared, ()> { pub fn get_mpd_handler_shared_state(&self) -> Result<InfoFromShared, ()> {
if let Ok(read_lock) = self.state.try_read() { if let Ok(read_lock) = self.state.try_read() {
return Ok(InfoFromShared { return Ok(InfoFromShared {
filename: read_lock.current_song_filename.clone(), filename: read_lock.current_song_filename.clone(),
@ -295,6 +305,7 @@ impl MPDHandler {
pos: read_lock.current_song_position pos: read_lock.current_song_position
+ read_lock.song_pos_get_time.elapsed().as_secs_f64(), + read_lock.song_pos_get_time.elapsed().as_secs_f64(),
error_text: read_lock.error_text.clone(), error_text: read_lock.error_text.clone(),
mpd_play_state: read_lock.mpd_play_state,
}); });
} }
@ -468,6 +479,8 @@ impl MPDHandler {
} }
let mut buf_vec: Vec<u8> = Vec::from(&buf[0..read_amount]); let mut buf_vec: Vec<u8> = Vec::from(&buf[0..read_amount]);
let mut got_mpd_state: MPDPlayState = MPDPlayState::Playing;
'handle_buf: loop { 'handle_buf: loop {
if write_handle.current_binary_size > 0 { if write_handle.current_binary_size > 0 {
if write_handle.current_binary_size <= buf_vec.len() { if write_handle.current_binary_size <= buf_vec.len() {
@ -600,6 +613,40 @@ impl MPDHandler {
_ => (), _ => (),
} }
write_handle.poll_state = PollState::None; write_handle.poll_state = PollState::None;
} else if line.starts_with("state: ") {
let remaining = line.split_off(7);
let remaining = remaining.trim();
if remaining == "stop" {
write_handle.current_song_filename.clear();
write_handle.art_data.clear();
write_handle.art_data_size = 0;
write_handle.art_data_type.clear();
write_handle.can_get_album_art = true;
write_handle.can_get_album_art_in_dir = true;
write_handle.current_song_title.clear();
write_handle.current_song_artist.clear();
write_handle.current_song_length = 0.0;
write_handle.current_song_position = 0.0;
write_handle.did_check_overtime = false;
write_handle.force_get_status = true;
}
if remaining == "stop" || remaining == "pause" {
got_mpd_state = if remaining == "stop" {
MPDPlayState::Stopped
} else {
MPDPlayState::Paused
};
write_handle.error_text.clear();
write_handle
.error_text
.push_str(&format!("MPD has {:?}", got_mpd_state));
log(
format!("MPD is {:?}", got_mpd_state),
LogState::Warning,
write_handle.log_level,
);
break 'handle_buf;
}
} else if line.starts_with("file: ") { } else if line.starts_with("file: ") {
let song_file = line.split_off(6); let song_file = line.split_off(6);
if song_file != write_handle.current_song_filename { if song_file != write_handle.current_song_filename {
@ -699,6 +746,20 @@ impl MPDHandler {
} }
} // 'handle_buf: loop } // 'handle_buf: loop
if got_mpd_state != write_handle.mpd_play_state {
write_handle.dirty_flag.store(true, Ordering::Relaxed);
if got_mpd_state == MPDPlayState::Playing {
write_handle.error_text.clear();
}
}
write_handle.mpd_play_state = got_mpd_state;
if got_mpd_state != MPDPlayState::Playing {
write_handle.poll_state = PollState::None;
write_handle.song_pos_get_time = Instant::now();
write_handle.current_song_length = 30.0;
write_handle.current_song_position = 0.0;
}
Ok(()) Ok(())
} }
@ -738,6 +799,7 @@ impl MPDHandler {
} else if write_handle.can_get_status } else if write_handle.can_get_status
&& (write_handle.song_title_get_time.elapsed() > POLL_DURATION && (write_handle.song_title_get_time.elapsed() > POLL_DURATION
|| write_handle.force_get_current_song) || write_handle.force_get_current_song)
&& write_handle.mpd_play_state == MPDPlayState::Playing
{ {
write_handle.force_get_current_song = false; write_handle.force_get_current_song = false;
let write_result = write_handle.stream.write(b"currentsong\n"); let write_result = write_handle.stream.write(b"currentsong\n");