Hammond-gtk: Use Atomic Refference counting to reduce cloning of Podcast.
This commit is contained in:
parent
df02054b29
commit
67af85e347
@ -5,6 +5,8 @@ use errors::DataError;
|
||||
use models::{Save, Source};
|
||||
use schema::podcast;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
#[derive(Queryable, Identifiable, AsChangeset, Associations, PartialEq)]
|
||||
#[belongs_to(Source, foreign_key = "source_id")]
|
||||
#[changeset_options(treat_none_as_null = "true")]
|
||||
@ -138,6 +140,16 @@ impl From<Podcast> for PodcastCoverQuery {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Arc<Podcast>> for PodcastCoverQuery {
|
||||
fn from(p: Arc<Podcast>) -> PodcastCoverQuery {
|
||||
PodcastCoverQuery {
|
||||
id: p.id(),
|
||||
title: p.title.clone(),
|
||||
image_uri: p.image_uri.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PodcastCoverQuery {
|
||||
/// Get the Feed `id`.
|
||||
pub fn id(&self) -> i32 {
|
||||
|
||||
@ -135,8 +135,8 @@ impl App {
|
||||
Ok(Action::RefreshWidgetIfSame(id)) => content.update_widget_if_same(id),
|
||||
Ok(Action::RefreshEpisodesView) => content.update_episode_view(),
|
||||
Ok(Action::RefreshEpisodesViewBGR) => content.update_episode_view_if_baground(),
|
||||
Ok(Action::ReplaceWidget(ref pd)) => {
|
||||
if let Err(err) = content.get_shows().replace_widget(pd) {
|
||||
Ok(Action::ReplaceWidget(pd)) => {
|
||||
if let Err(err) = content.get_shows().replace_widget(Arc::new(pd)) {
|
||||
error!("Something went wrong while trying to update the ShowWidget.");
|
||||
error!("Error: {}", err);
|
||||
}
|
||||
|
||||
@ -12,6 +12,7 @@ use views::{EmptyView, ShowsPopulated};
|
||||
use app::Action;
|
||||
use widgets::ShowWidget;
|
||||
|
||||
use std::sync::Arc;
|
||||
use std::sync::mpsc::Sender;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
@ -93,7 +94,7 @@ impl ShowStack {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn replace_widget(&self, pd: &Podcast) -> Result<(), Error> {
|
||||
pub fn replace_widget(&self, pd: Arc<Podcast>) -> Result<(), Error> {
|
||||
let old = self.stack
|
||||
.get_child_by_name("widget")
|
||||
.ok_or_else(|| format_err!("Faild to get \"widget\" child from the stack."))?
|
||||
@ -144,7 +145,7 @@ impl ShowStack {
|
||||
|
||||
let id = id.ok_or_else(|| format_err!("Failed to get widget's name."))?;
|
||||
let pd = dbqueries::get_podcast_from_id(id.parse::<i32>()?)?;
|
||||
self.replace_widget(&pd)?;
|
||||
self.replace_widget(Arc::new(pd))?;
|
||||
self.stack.set_visible_child_name(&vis);
|
||||
old.destroy();
|
||||
Ok(())
|
||||
|
||||
@ -8,6 +8,7 @@ use hammond_data::dbqueries;
|
||||
use app::Action;
|
||||
use utils::get_pixbuf_from_path;
|
||||
|
||||
use std::sync::Arc;
|
||||
use std::sync::mpsc::Sender;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
@ -55,10 +56,13 @@ impl ShowsPopulated {
|
||||
fn populate_flowbox(&self) -> Result<(), Error> {
|
||||
let podcasts = dbqueries::get_podcasts()?;
|
||||
|
||||
podcasts.iter().for_each(|parent| {
|
||||
let flowbox_child = ShowsChild::new(parent);
|
||||
self.flowbox.add(&flowbox_child.child);
|
||||
});
|
||||
podcasts
|
||||
.into_iter()
|
||||
.map(|pd| Arc::new(pd))
|
||||
.for_each(|parent| {
|
||||
let flowbox_child = ShowsChild::new(parent);
|
||||
self.flowbox.add(&flowbox_child.child);
|
||||
});
|
||||
self.flowbox.show_all();
|
||||
Ok(())
|
||||
}
|
||||
@ -114,23 +118,23 @@ impl Default for ShowsChild {
|
||||
}
|
||||
|
||||
impl ShowsChild {
|
||||
pub fn new(pd: &Podcast) -> ShowsChild {
|
||||
pub fn new(pd: Arc<Podcast>) -> ShowsChild {
|
||||
let child = ShowsChild::default();
|
||||
child.init(pd);
|
||||
child
|
||||
}
|
||||
|
||||
fn init(&self, pd: &Podcast) {
|
||||
fn init(&self, pd: Arc<Podcast>) {
|
||||
self.container.set_tooltip_text(pd.title());
|
||||
|
||||
if let Err(err) = self.set_cover(pd) {
|
||||
if let Err(err) = self.set_cover(pd.clone()) {
|
||||
error!("Failed to set a cover: {}", err)
|
||||
}
|
||||
|
||||
WidgetExt::set_name(&self.child, &pd.id().to_string());
|
||||
}
|
||||
|
||||
fn set_cover(&self, pd: &Podcast) -> Result<(), Error> {
|
||||
fn set_cover(&self, pd: Arc<Podcast>) -> Result<(), Error> {
|
||||
let image = get_pixbuf_from_path(&pd.clone().into(), 256)?;
|
||||
self.cover.set_from_pixbuf(&image);
|
||||
Ok(())
|
||||
|
||||
@ -12,6 +12,7 @@ use app::Action;
|
||||
use utils::get_pixbuf_from_path;
|
||||
use widgets::episode::episodes_listbox;
|
||||
|
||||
use std::sync::Arc;
|
||||
use std::sync::mpsc::Sender;
|
||||
use std::thread;
|
||||
|
||||
@ -54,27 +55,27 @@ impl Default for ShowWidget {
|
||||
}
|
||||
|
||||
impl ShowWidget {
|
||||
pub fn new(pd: &Podcast, sender: Sender<Action>) -> ShowWidget {
|
||||
pub fn new(pd: Arc<Podcast>, sender: Sender<Action>) -> ShowWidget {
|
||||
let pdw = ShowWidget::default();
|
||||
pdw.init(pd, sender);
|
||||
pdw
|
||||
}
|
||||
|
||||
pub fn init(&self, pd: &Podcast, sender: Sender<Action>) {
|
||||
pub fn init(&self, pd: Arc<Podcast>, sender: Sender<Action>) {
|
||||
// Hacky workaround so the pd.id() can be retrieved from the `ShowStack`.
|
||||
WidgetExt::set_name(&self.container, &pd.id().to_string());
|
||||
|
||||
self.unsub
|
||||
.connect_clicked(clone!(pd, sender => move |bttn| {
|
||||
if let Err(err) = on_unsub_button_clicked(&pd, bttn, sender.clone()) {
|
||||
if let Err(err) = on_unsub_button_clicked(pd.clone(), bttn, sender.clone()) {
|
||||
error!("Error: {}", err);
|
||||
}
|
||||
}));
|
||||
|
||||
self.setup_listbox(pd, sender.clone());
|
||||
self.setup_listbox(pd.clone(), sender.clone());
|
||||
self.set_description(pd.description());
|
||||
|
||||
if let Err(err) = self.set_cover(pd) {
|
||||
if let Err(err) = self.set_cover(pd.clone()) {
|
||||
error!("Failed to set a cover: {}", err)
|
||||
}
|
||||
|
||||
@ -90,13 +91,14 @@ impl ShowWidget {
|
||||
}
|
||||
|
||||
/// Populate the listbox with the shows episodes.
|
||||
fn setup_listbox(&self, pd: &Podcast, sender: Sender<Action>) {
|
||||
let listbox = episodes_listbox(pd, sender.clone());
|
||||
fn setup_listbox(&self, pd: Arc<Podcast>, sender: Sender<Action>) {
|
||||
let listbox = episodes_listbox(&pd, sender.clone());
|
||||
listbox.ok().map(|l| self.episodes.add(&l));
|
||||
}
|
||||
|
||||
/// Set the show cover.
|
||||
fn set_cover(&self, pd: &Podcast) -> Result<(), Error> {
|
||||
let image = get_pixbuf_from_path(&pd.clone().into(), 128)?;
|
||||
fn set_cover(&self, pd: Arc<Podcast>) -> Result<(), Error> {
|
||||
let image = get_pixbuf_from_path(&pd.into(), 128)?;
|
||||
self.cover.set_from_pixbuf(&image);
|
||||
Ok(())
|
||||
}
|
||||
@ -115,7 +117,7 @@ impl ShowWidget {
|
||||
}
|
||||
|
||||
fn on_unsub_button_clicked(
|
||||
pd: &Podcast,
|
||||
pd: Arc<Podcast>,
|
||||
unsub_button: >k::Button,
|
||||
sender: Sender<Action>,
|
||||
) -> Result<(), Error> {
|
||||
@ -123,12 +125,12 @@ fn on_unsub_button_clicked(
|
||||
// if pressed twice would panic.
|
||||
unsub_button.hide();
|
||||
// Spawn a thread so it won't block the ui.
|
||||
thread::spawn(clone!(pd => move || {
|
||||
thread::spawn(move || {
|
||||
if let Err(err) = delete_show(&pd) {
|
||||
error!("Something went wrong trying to remove {}", pd.title());
|
||||
error!("Error: {}", err);
|
||||
}
|
||||
}));
|
||||
});
|
||||
|
||||
sender.send(Action::HeaderBarNormal)?;
|
||||
sender.send(Action::ShowShowsAnimated)?;
|
||||
@ -140,8 +142,8 @@ fn on_unsub_button_clicked(
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn on_played_button_clicked(pd: &Podcast, sender: Sender<Action>) -> Result<(), Error> {
|
||||
dbqueries::update_none_to_played_now(pd)?;
|
||||
fn on_played_button_clicked(pd: Arc<Podcast>, sender: Sender<Action>) -> Result<(), Error> {
|
||||
dbqueries::update_none_to_played_now(&pd)?;
|
||||
sender.send(Action::RefreshWidget)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user