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