ShowWidget: Initial Lazier evaluation of the widgets.

This commit is contained in:
Jordan Petridis 2018-04-05 20:41:31 +03:00
parent d332636dd4
commit 0c00ee1320
3 changed files with 46 additions and 9 deletions

View File

@ -175,6 +175,16 @@ pub fn get_pd_episodes(parent: &Podcast) -> Result<Vec<Episode>, DataError> {
.map_err(From::from) .map_err(From::from)
} }
pub fn get_pd_episodes_count(parent: &Podcast) -> Result<i64, DataError> {
let db = connection();
let con = db.get()?;
Episode::belonging_to(parent)
.count()
.get_result(&con)
.map_err(From::from)
}
pub fn get_pd_episodeswidgets(parent: &Podcast) -> Result<Vec<EpisodeWidgetQuery>, DataError> { pub fn get_pd_episodeswidgets(parent: &Podcast) -> Result<Vec<EpisodeWidgetQuery>, DataError> {
use schema::episode::dsl::*; use schema::episode::dsl::*;
let db = connection(); let db = connection();

View File

@ -5,6 +5,7 @@ use gtk::prelude::*;
use failure::Error; use failure::Error;
use humansize::FileSize; use humansize::FileSize;
use open; use open;
use rayon;
use take_mut; use take_mut;
use hammond_data::{EpisodeWidgetQuery, Podcast}; use hammond_data::{EpisodeWidgetQuery, Podcast};
@ -20,7 +21,7 @@ use std::ops::DerefMut;
use std::path::Path; use std::path::Path;
use std::rc::Rc; use std::rc::Rc;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use std::sync::mpsc::Sender; use std::sync::mpsc::{channel, Sender};
#[derive(Debug)] #[derive(Debug)]
pub struct EpisodeWidget { pub struct EpisodeWidget {
@ -350,23 +351,49 @@ fn total_size_helper(
// delete_local_content(&mut ep).map_err(From::from).map(|_| ()) // delete_local_content(&mut ep).map_err(From::from).map(|_| ())
// } // }
pub fn episodes_listbox(pd: &Podcast, sender: Sender<Action>) -> Result<gtk::ListBox, Error> { pub fn episodes_listbox(pd: Arc<Podcast>, sender: Sender<Action>) -> Result<gtk::ListBox, Error> {
let episodes = dbqueries::get_pd_episodeswidgets(pd)?; let count = dbqueries::get_pd_episodes_count(&pd)?;
let (sender_, receiver) = channel();
rayon::spawn(move || {
let episodes = dbqueries::get_pd_episodeswidgets(&pd).unwrap();
sender_
.send(episodes)
.expect("Something terrible happened to the channnel");
});
let list = gtk::ListBox::new(); let list = gtk::ListBox::new();
list.set_visible(true); list.set_visible(true);
list.set_selection_mode(gtk::SelectionMode::None); list.set_selection_mode(gtk::SelectionMode::None);
if episodes.is_empty() { if count == 0 {
let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/empty_show.ui"); let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/empty_show.ui");
let container: gtk::Box = builder.get_object("empty_show").unwrap(); let container: gtk::Box = builder.get_object("empty_show").unwrap();
list.add(&container); list.add(&container);
return Ok(list); return Ok(list);
} }
episodes.into_iter().for_each(|ep| { let widgets: Vec<_> = (0..count)
let widget = EpisodeWidget::new(ep, sender.clone()); .into_iter()
list.add(&widget.container); .map(|_| {
let widget = EpisodeWidget::default();
list.add(&widget.container);
widget
})
.collect();
let (s3, r3) = channel();
s3.send(widgets).unwrap();
gtk::idle_add(move || {
let episodes = receiver.recv().unwrap();
let widgets = r3.recv().unwrap();
episodes
.into_iter()
.zip(widgets)
.for_each(|(ep, mut widget)| widget.init(ep, sender.clone()));
glib::Continue(false)
}); });
Ok(list) Ok(list)
} }

View File

@ -73,7 +73,7 @@ impl ShowWidget {
} }
})); }));
self.setup_listbox(&pd, sender.clone()); self.setup_listbox(pd.clone(), sender.clone());
self.set_description(pd.description()); self.set_description(pd.description());
if let Err(err) = self.set_cover(pd.clone()) { if let Err(err) = self.set_cover(pd.clone()) {
@ -105,7 +105,7 @@ impl ShowWidget {
} }
/// Populate the listbox with the shows episodes. /// Populate the listbox with the shows episodes.
fn setup_listbox(&self, pd: &Podcast, sender: Sender<Action>) { fn setup_listbox(&self, pd: Arc<Podcast>, sender: Sender<Action>) {
let listbox = episodes_listbox(pd, sender.clone()); let listbox = episodes_listbox(pd, sender.clone());
listbox.ok().map(|l| self.episodes.add(&l)); listbox.ok().map(|l| self.episodes.add(&l));
} }