use std::cell::Cell;
#[derive(Debug, Default)]
pub struct DirtyFlags {
queue: Cell<bool>,
queue_selection: Cell<bool>,
current_song: Cell<bool>,
status: Cell<bool>,
progress: Cell<bool>,
cover_art: Cell<bool>,
library: Cell<bool>,
menu_mode: Cell<bool>,
panel_focus: Cell<bool>,
terminal_size: Cell<bool>,
force_full: Cell<bool>,
key_sequence: Cell<bool>,
last_width: Cell<u16>,
last_height: Cell<u16>,
pub status_message: Cell<bool>,
}
#[allow(dead_code)] impl DirtyFlags {
pub fn new() -> Self {
Self {
queue: Cell::new(true),
queue_selection: Cell::new(true),
current_song: Cell::new(true),
status: Cell::new(true),
progress: Cell::new(true),
cover_art: Cell::new(true),
library: Cell::new(true),
menu_mode: Cell::new(true),
panel_focus: Cell::new(true),
terminal_size: Cell::new(true),
force_full: Cell::new(true),
key_sequence: Cell::new(false),
last_width: Cell::new(0),
last_height: Cell::new(0),
status_message: Cell::new(false),
}
}
#[inline]
pub fn mark_queue(&self) {
self.queue.set(true);
}
#[inline]
pub fn mark_queue_selection(&self) {
self.queue_selection.set(true);
}
#[inline]
pub fn mark_current_song(&self) {
self.current_song.set(true);
}
#[inline]
pub fn mark_status(&self) {
self.status.set(true);
}
#[inline]
pub fn mark_progress(&self) {
self.progress.set(true);
}
#[inline]
pub fn mark_cover_art(&self) {
self.cover_art.set(true);
}
#[inline]
pub fn mark_library(&self) {
self.library.set(true);
}
#[inline]
pub fn mark_menu_mode(&self) {
self.menu_mode.set(true);
}
#[inline]
pub fn mark_panel_focus(&self) {
self.panel_focus.set(true);
}
#[inline]
pub fn mark_full_redraw(&self) {
self.force_full.set(true);
}
#[inline]
pub fn mark_key_sequence(&self) {
self.key_sequence.set(true);
}
#[inline]
pub fn mark_status_message(&self) {
self.status_message.set(true);
}
#[inline]
pub fn check_terminal_size(&self, width: u16, height: u16) {
if width != self.last_width.get() || height != self.last_height.get() {
self.terminal_size.set(true);
self.last_width.set(width);
self.last_height.set(height);
}
}
#[inline]
pub fn is_queue_dirty(&self) -> bool {
self.force_full.get() || self.terminal_size.get() || self.queue.get()
}
#[inline]
pub fn is_queue_selection_dirty(&self) -> bool {
self.force_full.get()
|| self.terminal_size.get()
|| self.queue.get()
|| self.queue_selection.get()
}
#[inline]
pub fn is_current_song_dirty(&self) -> bool {
self.force_full.get() || self.terminal_size.get() || self.current_song.get()
}
#[inline]
pub fn is_status_dirty(&self) -> bool {
self.force_full.get()
|| self.terminal_size.get()
|| self.status.get()
|| self.menu_mode.get()
}
#[inline]
pub fn is_progress_dirty(&self) -> bool {
self.force_full.get()
|| self.terminal_size.get()
|| self.progress.get()
|| self.status.get()
}
#[inline]
pub fn is_cover_art_dirty(&self) -> bool {
self.force_full.get() || self.terminal_size.get() || self.cover_art.get()
}
#[inline]
pub fn is_library_dirty(&self) -> bool {
self.force_full.get()
|| self.terminal_size.get()
|| self.library.get()
|| self.panel_focus.get()
}
#[inline]
pub fn any_dirty(&self) -> bool {
self.force_full.get()
|| self.terminal_size.get()
|| self.queue.get()
|| self.queue_selection.get()
|| self.current_song.get()
|| self.status.get()
|| self.progress.get()
|| self.cover_art.get()
|| self.library.get()
|| self.menu_mode.get()
|| self.panel_focus.get()
|| self.key_sequence.get()
|| self.status_message.get()
}
#[inline]
pub fn needs_full_redraw(&self) -> bool {
self.force_full.get() || self.terminal_size.get() || self.menu_mode.get()
}
#[inline]
pub fn clear_all(&self) {
self.queue.set(false);
self.queue_selection.set(false);
self.current_song.set(false);
self.status.set(false);
self.progress.set(false);
self.cover_art.set(false);
self.library.set(false);
self.menu_mode.set(false);
self.panel_focus.set(false);
self.terminal_size.set(false);
self.force_full.set(false);
self.key_sequence.set(false);
self.status_message.set(false);
}
#[inline]
pub fn clear_progress(&self) {
self.progress.set(false);
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_new_all_dirty() {
let flags = DirtyFlags::new();
assert!(flags.any_dirty());
assert!(flags.needs_full_redraw());
assert!(flags.is_queue_dirty());
assert!(flags.is_progress_dirty());
}
#[test]
fn test_clear_all() {
let flags = DirtyFlags::new();
flags.clear_all();
assert!(!flags.any_dirty());
assert!(!flags.needs_full_redraw());
}
#[test]
fn test_individual_marks() {
let flags = DirtyFlags::new();
flags.clear_all();
flags.mark_queue();
assert!(flags.is_queue_dirty());
assert!(!flags.is_progress_dirty());
flags.clear_all();
flags.mark_progress();
assert!(flags.is_progress_dirty());
assert!(!flags.is_queue_dirty());
}
#[test]
fn test_terminal_size_change() {
let flags = DirtyFlags::new();
flags.clear_all();
flags.check_terminal_size(80, 24);
flags.clear_all();
flags.check_terminal_size(80, 24);
assert!(!flags.needs_full_redraw());
flags.check_terminal_size(100, 30);
assert!(flags.needs_full_redraw());
}
#[test]
fn test_force_full_affects_all() {
let flags = DirtyFlags::new();
flags.clear_all();
flags.mark_full_redraw();
assert!(flags.is_queue_dirty());
assert!(flags.is_progress_dirty());
assert!(flags.is_status_dirty());
assert!(flags.is_cover_art_dirty());
}
}