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

View File

@ -98,17 +98,17 @@ lazy_static! {
}
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();
widget.init(episode, sender);
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());
// Set the title label state.
self.set_title(episode);
self.set_title(&episode);
// Set the size label.
self.set_total_size(episode.length());
@ -128,31 +128,28 @@ impl EpisodeWidget {
error!("Error: {}", err);
}
let title = &self.title;
let episode = Arc::new(Mutex::new(episode));
let title = self.title.clone();
self.play
.connect_clicked(clone!(episode, title, sender => move |_| {
let mut episode = episode.clone();
if let Err(err) = on_play_bttn_clicked(episode.rowid()) {
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();
};
.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);
};
}
}));
self.download
.connect_clicked(clone!(episode, sender => move |dl| {
dl.set_sensitive(false);
if let Err(err) = on_download_clicked(&episode, sender.clone()) {
error!("Download failed to start.");
error!("Error: {}", err);
} else {
info!("Donwload started succesfully.");
if let Ok(ep) = episode.lock() {
if let Err(err) = on_download_clicked(&ep, sender.clone()) {
error!("Download failed to start.");
error!("Error: {}", err);
} else {
info!("Donwload started succesfully.");
}
}
}));
}
@ -278,8 +275,23 @@ fn on_download_clicked(ep: &EpisodeWidgetQuery, sender: Sender<Action>) -> Resul
Ok(())
}
fn on_play_bttn_clicked(episode_id: i32) -> Result<(), Error> {
let uri = dbqueries::get_episode_local_uri_from_id(episode_id)?
fn on_play_bttn_clicked(
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."))?;
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> {
let mut episodes = dbqueries::get_pd_episodeswidgets(pd)?;
let episodes = dbqueries::get_pd_episodeswidgets(pd)?;
let list = gtk::ListBox::new();
episodes.iter_mut().for_each(|ep| {
episodes.into_iter().for_each(|ep| {
let widget = EpisodeWidget::new(ep, sender.clone());
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());
if let Err(err) = self.set_cover(pd.clone()) {
@ -91,8 +91,8 @@ impl ShowWidget {
}
/// Populate the listbox with the shows episodes.
fn setup_listbox(&self, pd: Arc<Podcast>, sender: Sender<Action>) {
let listbox = episodes_listbox(&pd, sender.clone());
fn setup_listbox(&self, pd: &Podcast, sender: Sender<Action>) {
let listbox = episodes_listbox(pd, sender.clone());
listbox.ok().map(|l| self.episodes.add(&l));
}
@ -142,8 +142,8 @@ fn on_unsub_button_clicked(
}
#[allow(dead_code)]
fn on_played_button_clicked(pd: Arc<Podcast>, sender: Sender<Action>) -> Result<(), Error> {
dbqueries::update_none_to_played_now(&pd)?;
fn on_played_button_clicked(pd: &Podcast, sender: Sender<Action>) -> Result<(), Error> {
dbqueries::update_none_to_played_now(pd)?;
sender.send(Action::RefreshWidget)?;
Ok(())
}