EpisodeWidget: Use refference counting intead of unnecessary clones.

Pass owenership of EpisodeWidgetQuery and use Atomic Ref counting
to pass to the callbacks. This should avoid extra allocations.
This commit is contained in:
Jordan Petridis 2018-02-07 18:40:22 +02:00
parent 07c1a9a0e9
commit e2a1762af4
No known key found for this signature in database
GPG Key ID: CEABAD9F5683B9A6
3 changed files with 54 additions and 40 deletions

View File

@ -77,13 +77,14 @@ impl Default for EpisodesView {
impl EpisodesView { impl EpisodesView {
pub fn new(sender: Sender<Action>) -> Result<EpisodesView, Error> { pub fn new(sender: Sender<Action>) -> Result<EpisodesView, Error> {
let view = EpisodesView::default(); let view = EpisodesView::default();
let mut episodes = dbqueries::get_episodes_widgets_with_limit(50)?; let episodes = dbqueries::get_episodes_widgets_with_limit(50)?;
let now_utc = Utc::now(); let now_utc = Utc::now();
episodes.iter_mut().for_each(|ep| { episodes.into_iter().for_each(|ep| {
let epoch = ep.epoch();
let viewep = EpisodesViewWidget::new(ep, sender.clone()); let viewep = EpisodesViewWidget::new(ep, sender.clone());
let t = split(&now_utc, i64::from(ep.epoch())); let t = split(&now_utc, i64::from(epoch));
match t { match t {
ListSplit::Today => { ListSplit::Today => {
view.today_list.add(&viewep.container); view.today_list.add(&viewep.container);
@ -198,11 +199,12 @@ impl Default for EpisodesViewWidget {
} }
impl EpisodesViewWidget { impl EpisodesViewWidget {
fn new(episode: &mut EpisodeWidgetQuery, sender: Sender<Action>) -> EpisodesViewWidget { fn new(episode: EpisodeWidgetQuery, sender: Sender<Action>) -> EpisodesViewWidget {
let builder = let builder =
gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/episodes_view_widget.ui"); gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/episodes_view_widget.ui");
let container: gtk::Box = builder.get_object("container").unwrap(); let container: gtk::Box = builder.get_object("container").unwrap();
let image: gtk::Image = builder.get_object("cover").unwrap(); let image: gtk::Image = builder.get_object("cover").unwrap();
let pid = episode.podcast_id();
let ep = EpisodeWidget::new(episode, sender.clone()); let ep = EpisodeWidget::new(episode, sender.clone());
let view = EpisodesViewWidget { let view = EpisodesViewWidget {
@ -211,20 +213,20 @@ impl EpisodesViewWidget {
episode: ep.container, episode: ep.container,
}; };
view.init(episode); view.init(pid);
view view
} }
fn init(&self, episode: &mut EpisodeWidgetQuery) { fn init(&self, podcast_id: i32) {
if let Err(err) = self.set_cover(episode) { if let Err(err) = self.set_cover(podcast_id) {
error!("Failed to set a cover: {}", err) error!("Failed to set a cover: {}", err)
} }
self.container.pack_start(&self.episode, true, true, 6); self.container.pack_start(&self.episode, true, true, 6);
} }
fn set_cover(&self, episode: &mut EpisodeWidgetQuery) -> Result<(), Error> { fn set_cover(&self, podcast_id: i32) -> Result<(), Error> {
let pd = dbqueries::get_podcast_cover_from_id(episode.podcast_id())?; let pd = dbqueries::get_podcast_cover_from_id(podcast_id)?;
let img = get_pixbuf_from_path(&pd, 64)?; let img = get_pixbuf_from_path(&pd, 64)?;
self.image.set_from_pixbuf(&img); self.image.set_from_pixbuf(&img);
Ok(()) Ok(())

View File

@ -98,17 +98,17 @@ lazy_static! {
} }
impl EpisodeWidget { impl EpisodeWidget {
pub fn new(episode: &mut EpisodeWidgetQuery, sender: Sender<Action>) -> EpisodeWidget { pub fn new(episode: EpisodeWidgetQuery, sender: Sender<Action>) -> EpisodeWidget {
let widget = EpisodeWidget::default(); let widget = EpisodeWidget::default();
widget.init(episode, sender); widget.init(episode, sender);
widget widget
} }
fn init(&self, episode: &mut EpisodeWidgetQuery, sender: Sender<Action>) { fn init(&self, episode: EpisodeWidgetQuery, sender: Sender<Action>) {
WidgetExt::set_name(&self.container, &episode.rowid().to_string()); WidgetExt::set_name(&self.container, &episode.rowid().to_string());
// Set the title label state. // Set the title label state.
self.set_title(episode); self.set_title(&episode);
// Set the size label. // Set the size label.
self.set_total_size(episode.length()); self.set_total_size(episode.length());
@ -128,32 +128,29 @@ impl EpisodeWidget {
error!("Error: {}", err); error!("Error: {}", err);
} }
let title = &self.title; let episode = Arc::new(Mutex::new(episode));
self.play
.connect_clicked(clone!(episode, title, sender => move |_| {
let mut episode = episode.clone();
if let Err(err) = on_play_bttn_clicked(episode.rowid()) { let title = self.title.clone();
self.play
.connect_clicked(clone!(episode, sender => move |_| {
if let Ok(mut ep) = episode.lock() {
if let Err(err) = on_play_bttn_clicked(&mut ep, &title, sender.clone()){
error!("Error: {}", err); error!("Error: {}", err);
}; };
}
if episode.set_played_now().is_ok() {
title
.get_style_context()
.map(|c| c.add_class("dim-label"));
sender.send(Action::RefreshEpisodesViewBGR).unwrap();
};
})); }));
self.download self.download
.connect_clicked(clone!(episode, sender => move |dl| { .connect_clicked(clone!(episode, sender => move |dl| {
dl.set_sensitive(false); dl.set_sensitive(false);
if let Err(err) = on_download_clicked(&episode, sender.clone()) { if let Ok(ep) = episode.lock() {
if let Err(err) = on_download_clicked(&ep, sender.clone()) {
error!("Download failed to start."); error!("Download failed to start.");
error!("Error: {}", err); error!("Error: {}", err);
} else { } else {
info!("Donwload started succesfully."); info!("Donwload started succesfully.");
} }
}
})); }));
} }
@ -278,8 +275,23 @@ fn on_download_clicked(ep: &EpisodeWidgetQuery, sender: Sender<Action>) -> Resul
Ok(()) Ok(())
} }
fn on_play_bttn_clicked(episode_id: i32) -> Result<(), Error> { fn on_play_bttn_clicked(
let uri = dbqueries::get_episode_local_uri_from_id(episode_id)? episode: &mut EpisodeWidgetQuery,
title: &gtk::Label,
sender: Sender<Action>,
) -> Result<(), Error> {
open_uri(episode.rowid())?;
if episode.set_played_now().is_ok() {
title.get_style_context().map(|c| c.add_class("dim-label"));
sender.send(Action::RefreshEpisodesViewBGR).unwrap();
};
Ok(())
}
fn open_uri(rowid: i32) -> Result<(), Error> {
let uri = dbqueries::get_episode_local_uri_from_id(rowid)?
.ok_or_else(|| format_err!("Expected Some found None."))?; .ok_or_else(|| format_err!("Expected Some found None."))?;
if Path::new(&uri).exists() { if Path::new(&uri).exists() {
@ -396,11 +408,11 @@ fn total_size_helper(
// } // }
pub fn episodes_listbox(pd: &Podcast, sender: Sender<Action>) -> Result<gtk::ListBox, Error> { pub fn episodes_listbox(pd: &Podcast, sender: Sender<Action>) -> Result<gtk::ListBox, Error> {
let mut episodes = dbqueries::get_pd_episodeswidgets(pd)?; let episodes = dbqueries::get_pd_episodeswidgets(pd)?;
let list = gtk::ListBox::new(); let list = gtk::ListBox::new();
episodes.iter_mut().for_each(|ep| { episodes.into_iter().for_each(|ep| {
let widget = EpisodeWidget::new(ep, sender.clone()); let widget = EpisodeWidget::new(ep, sender.clone());
list.add(&widget.container); list.add(&widget.container);
}); });

View File

@ -72,7 +72,7 @@ impl ShowWidget {
} }
})); }));
self.setup_listbox(pd.clone(), sender.clone()); self.setup_listbox(&pd, 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()) {
@ -91,8 +91,8 @@ impl ShowWidget {
} }
/// Populate the listbox with the shows episodes. /// Populate the listbox with the shows episodes.
fn setup_listbox(&self, pd: Arc<Podcast>, sender: Sender<Action>) { fn setup_listbox(&self, pd: &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));
} }
@ -142,8 +142,8 @@ fn on_unsub_button_clicked(
} }
#[allow(dead_code)] #[allow(dead_code)]
fn on_played_button_clicked(pd: Arc<Podcast>, sender: Sender<Action>) -> Result<(), Error> { fn on_played_button_clicked(pd: &Podcast, sender: Sender<Action>) -> Result<(), Error> {
dbqueries::update_none_to_played_now(&pd)?; dbqueries::update_none_to_played_now(pd)?;
sender.send(Action::RefreshWidget)?; sender.send(Action::RefreshWidget)?;
Ok(()) Ok(())
} }