Skip to content

Commit

Permalink
Only refresh outdated players when media collection changes
Browse files Browse the repository at this point in the history
  • Loading branch information
mtkennerly committed Dec 6, 2024
1 parent b626345 commit dd513f1
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 20 deletions.
20 changes: 9 additions & 11 deletions src/gui/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ impl App {
if sources.is_empty() {
modals.push(Modal::new_sources(sources.clone(), text_histories.clone()));
} else {
commands.push(Self::find_media(sources, true))
commands.push(Self::find_media(sources, media::RefreshContext::Launch))
}

if !errors.is_empty() {
Expand Down Expand Up @@ -188,7 +188,7 @@ impl App {
self.grid.all_muted()
}

fn find_media(sources: Vec<media::Source>, refresh: bool) -> Task<Message> {
fn find_media(sources: Vec<media::Source>, context: media::RefreshContext) -> Task<Message> {
if sources.is_empty() {
return Task::none();
}
Expand All @@ -197,7 +197,7 @@ impl App {
match tokio::task::spawn_blocking(move || media::Collection::find(&sources)).await {
Ok(media) => {
log::debug!("Found media: {media:?}");
Message::MediaFound { refresh, media }
Message::MediaFound { context, media }
}
Err(e) => {
log::error!("Unable to find media: {e:?}");
Expand Down Expand Up @@ -536,7 +536,7 @@ impl App {
self.modals.pop();
self.text_histories = histories;
self.grid.set_sources(sources.clone());
return Self::find_media(sources, true);
return Self::find_media(sources, media::RefreshContext::Edit);
}
modal::Update::Task(task) => {
return task;
Expand All @@ -557,14 +557,12 @@ impl App {
));
Task::none()
}
Message::FindMedia => Self::find_media(self.grid.sources().to_vec(), false),
Message::MediaFound { refresh, media } => {
Message::FindMedia => Self::find_media(self.grid.sources().to_vec(), media::RefreshContext::Automatic),
Message::MediaFound { context, media } => {
self.media.replace(media);
if refresh {
self.refresh()
} else {
Task::none()
}
self.grid
.refresh_on_media_collection_changed(context, &mut self.media, &self.config.playback);
Task::none()
}
Message::FileDragDrop(path) => match self.modals.last_mut() {
Some(Modal::Sources { sources, histories }) => {
Expand Down
38 changes: 29 additions & 9 deletions src/gui/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,27 @@ pub enum Message {
Tick(Instant),
Save,
CloseModal,
Config { event: config::Event },
Config {
event: config::Event,
},
CheckAppRelease,
AppReleaseChecked(Result<crate::metadata::Release, String>),
BrowseDir(BrowseSubject),
BrowseFile(BrowseFileSubject),
OpenDir { path: StrictPath },
OpenDir {
path: StrictPath,
},
OpenDirSubject(BrowseSubject),
OpenFile { path: StrictPath },
OpenFile {
path: StrictPath,
},
OpenFileSubject(BrowseFileSubject),
OpenDirFailure { path: StrictPath },
OpenUrlFailure { url: String },
OpenDirFailure {
path: StrictPath,
},
OpenUrlFailure {
url: String,
},
KeyboardEvent(iced::keyboard::Event),
UndoRedo(crate::gui::undoable::Action, UndoSubject),
OpenUrl(String),
Expand All @@ -39,13 +49,23 @@ pub enum Message {
AddPlayer,
SetPause(bool),
SetMute(bool),
Player { pane: player::Id, event: player::Event },
AllPlayers { event: player::Event },
Modal { event: modal::Event },
Player {
pane: player::Id,
event: player::Event,
},
AllPlayers {
event: player::Event,
},
Modal {
event: modal::Event,
},
ShowSettings,
ShowSources,
FindMedia,
MediaFound { refresh: bool, media: media::SourceMap },
MediaFound {
context: media::RefreshContext,
media: media::SourceMap,
},
FileDragDrop(StrictPath),
WindowFocused,
WindowUnfocused,
Expand Down
51 changes: 51 additions & 0 deletions src/gui/grid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,57 @@ impl Grid {
}
}

fn refresh_outdated(&mut self, collection: &mut media::Collection, playback: &Playback) {
let mut remove = vec![];
let mut active: HashSet<_> = self.active_media().into_iter().cloned().collect();

for (index, player) in self.players.iter_mut().enumerate() {
if let Some(old_media) = player.media() {
if collection.is_outdated(old_media, &self.sources) {
active.remove(old_media);
match collection.one_new(&self.sources, active.iter().collect()) {
Some(new_media) => {
if player.swap_media(&new_media, playback).is_err() {
collection.mark_error(&new_media);
}
active.insert(new_media);
}
None => {
remove.push(player::Id(index));
}
}
}
}
}

for id in remove.into_iter().rev() {
self.players.remove(id.0);
}
}

pub fn refresh_on_media_collection_changed(
&mut self,
context: media::RefreshContext,
collection: &mut media::Collection,
playback: &Playback,
) {
match context {
media::RefreshContext::Launch => {
self.refresh(collection, playback);
}
media::RefreshContext::Edit => {
if self.is_idle() {
self.refresh(collection, playback);
} else {
self.refresh_outdated(collection, playback);
}
}
media::RefreshContext::Automatic => {
self.refresh_outdated(collection, playback);
}
}
}

pub fn add_player(&mut self, collection: &mut media::Collection, playback: &Playback) -> Result<(), Error> {
let Some(media) = collection.one_new(&self.sources, self.active_media()) else {
return Err(Error::NoMediaAvailable);
Expand Down
14 changes: 14 additions & 0 deletions src/media.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ use itertools::Itertools;

use crate::{lang, path::StrictPath};

#[derive(Debug, Clone, Copy)]
pub enum RefreshContext {
Launch,
Edit,
Automatic,
}

#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum Source {
Path { path: StrictPath },
Expand Down Expand Up @@ -174,6 +181,13 @@ impl Collection {
self.errored.insert(media.clone());
}

pub fn is_outdated(&self, media: &Media, sources: &[Source]) -> bool {
sources
.iter()
.filter_map(|source| self.media.get(source))
.all(|known| !known.contains(media))
}

pub fn find(sources: &[Source]) -> SourceMap {
let mut media = SourceMap::new();

Expand Down

0 comments on commit dd513f1

Please sign in to comment.