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:
parent
07c1a9a0e9
commit
e2a1762af4
@ -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(())
|
||||||
|
|||||||
@ -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: >k::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);
|
||||||
});
|
});
|
||||||
|
|||||||
@ -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(())
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user