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]]
name = "mpd_info_screen"
version = "0.2.18"
version = "0.2.19"
dependencies = [
"ggez",
"image 0.24.1",

View file

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

View file

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

View file

@ -1,5 +1,5 @@
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 ggez::event::{self, EventHandler};
use ggez::graphics::{
@ -77,6 +77,7 @@ pub struct MPDDisplay {
text_bg_mesh: Option<Mesh>,
hide_text: bool,
tried_album_art_in_dir: bool,
mpd_play_state: MPDPlayState,
}
impl MPDDisplay {
@ -109,6 +110,7 @@ impl MPDDisplay {
text_bg_mesh: None,
hide_text: false,
tried_album_art_in_dir: false,
mpd_play_state: MPDPlayState::Playing,
}
}
@ -573,43 +575,56 @@ impl EventHandler for MPDDisplay {
.mpd_handler
.as_ref()
.unwrap()
.get_current_song_info()
.get_mpd_handler_shared_state()
.ok();
if let Some(shared) = &self.shared {
if self.notice_text.contents() != shared.error_text {
self.notice_text = Text::new(TextFragment::new(shared.error_text.clone()));
}
if !shared.title.is_empty() {
self.title_text = Text::new(shared.title.clone());
} else {
self.dirty_flag
.as_ref()
.unwrap()
.store(true, Ordering::Relaxed);
}
if !shared.artist.is_empty() {
self.artist_text = Text::new(shared.artist.clone());
} else {
self.dirty_flag
.as_ref()
.unwrap()
.store(true, Ordering::Relaxed);
}
if !shared.filename.is_empty() {
if self.filename_text.contents() != shared.filename {
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.tried_album_art_in_dir = false;
}
self.filename_text = Text::new(shared.filename.clone());
self.mpd_play_state = shared.mpd_play_state;
} else {
self.dirty_flag
.as_ref()
.unwrap()
.store(true, Ordering::Relaxed);
self.mpd_play_state = MPDPlayState::Playing;
if !shared.title.is_empty() {
self.title_text = Text::new(shared.title.clone());
} else {
self.dirty_flag
.as_ref()
.unwrap()
.store(true, Ordering::Relaxed);
}
if !shared.artist.is_empty() {
self.artist_text = Text::new(shared.artist.clone());
} else {
self.dirty_flag
.as_ref()
.unwrap()
.store(true, Ordering::Relaxed);
}
if !shared.filename.is_empty() {
if self.filename_text.contents() != shared.filename {
self.album_art = None;
self.tried_album_art_in_dir = false;
}
self.filename_text = Text::new(shared.filename.clone());
} else {
self.dirty_flag
.as_ref()
.unwrap()
.store(true, Ordering::Relaxed);
}
self.timer = shared.pos;
self.length = shared.length;
self.refresh_text_transforms(ctx)?;
}
self.timer = shared.pos;
self.length = shared.length;
self.refresh_text_transforms(ctx)?;
} else {
log(
"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> {
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(
ctx,
DrawParam {
@ -661,7 +679,8 @@ impl EventHandler for MPDDisplay {
if !self.hide_text {
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 {
mesh.draw(ctx, DrawParam::default())?;
}
@ -696,13 +715,15 @@ impl EventHandler for MPDDisplay {
)?;
}
self.timer_text.draw(
ctx,
DrawParam {
trans: self.timer_transform,
..Default::default()
},
)?;
if self.mpd_play_state == MPDPlayState::Playing {
self.timer_text.draw(
ctx,
DrawParam {
trans: self.timer_transform,
..Default::default()
},
)?;
}
}
}

View file

@ -11,7 +11,7 @@ const SLEEP_DURATION: Duration = Duration::from_millis(100);
const POLL_DURATION: Duration = Duration::from_secs(5);
const BUF_SIZE: usize = 1024 * 4;
#[derive(Debug, PartialEq, Copy, Clone)]
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
enum PollState {
None,
Password,
@ -21,6 +21,13 @@ enum PollState {
ReadPictureInDir,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum MPDPlayState {
Playing,
Paused,
Stopped,
}
#[derive(Debug, Clone)]
pub struct InfoFromShared {
pub filename: String,
@ -29,6 +36,7 @@ pub struct InfoFromShared {
pub length: f64,
pub pos: f64,
pub error_text: String,
pub mpd_play_state: MPDPlayState,
}
#[derive(Clone)]
@ -66,6 +74,7 @@ pub struct MPDHandlerState {
dirty_flag: Arc<AtomicBool>,
pub stop_flag: Arc<AtomicBool>,
log_level: LogLevel,
mpd_play_state: MPDPlayState,
}
fn check_next_chars(
@ -267,6 +276,7 @@ impl MPDHandler {
dirty_flag: Arc::new(AtomicBool::new(true)),
stop_flag: Arc::new(AtomicBool::new(false)),
log_level,
mpd_play_state: MPDPlayState::Stopped,
})),
};
@ -285,7 +295,7 @@ impl MPDHandler {
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() {
return Ok(InfoFromShared {
filename: read_lock.current_song_filename.clone(),
@ -295,6 +305,7 @@ impl MPDHandler {
pos: read_lock.current_song_position
+ read_lock.song_pos_get_time.elapsed().as_secs_f64(),
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 got_mpd_state: MPDPlayState = MPDPlayState::Playing;
'handle_buf: loop {
if write_handle.current_binary_size > 0 {
if write_handle.current_binary_size <= buf_vec.len() {
@ -600,6 +613,40 @@ impl MPDHandler {
_ => (),
}
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: ") {
let song_file = line.split_off(6);
if song_file != write_handle.current_song_filename {
@ -699,6 +746,20 @@ impl MPDHandler {
}
} // '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(())
}
@ -738,6 +799,7 @@ impl MPDHandler {
} else if write_handle.can_get_status
&& (write_handle.song_title_get_time.elapsed() > POLL_DURATION
|| write_handle.force_get_current_song)
&& write_handle.mpd_play_state == MPDPlayState::Playing
{
write_handle.force_get_current_song = false;
let write_result = write_handle.stream.write(b"currentsong\n");