From 96c5c2af12ddbffad69e02d6490576a8d792d60e Mon Sep 17 00:00:00 2001 From: Remigiusz Micielski Date: Mon, 15 Jul 2024 21:48:38 +0200 Subject: [PATCH] make files popup mutexless --- rm-main/src/ui/tabs/torrents/mod.rs | 3 + rm-main/src/ui/tabs/torrents/popups/files.rs | 70 ++++++++------------ rm-main/src/ui/tabs/torrents/popups/mod.rs | 16 ++++- rm-shared/src/action.rs | 3 +- 4 files changed, 46 insertions(+), 46 deletions(-) diff --git a/rm-main/src/ui/tabs/torrents/mod.rs b/rm-main/src/ui/tabs/torrents/mod.rs index 9de850f..551be4f 100644 --- a/rm-main/src/ui/tabs/torrents/mod.rs +++ b/rm-main/src/ui/tabs/torrents/mod.rs @@ -140,6 +140,9 @@ impl Component for TorrentsTab { self.bottom_stats .update_selected_indicator(&self.table_manager); } + UpdateAction::UpdateCurrentTorrent(_) => { + self.popup_manager.handle_update_action(action) + } _ => (), } } diff --git a/rm-main/src/ui/tabs/torrents/popups/files.rs b/rm-main/src/ui/tabs/torrents/popups/files.rs index 65a1b5d..a82dd6a 100644 --- a/rm-main/src/ui/tabs/torrents/popups/files.rs +++ b/rm-main/src/ui/tabs/torrents/popups/files.rs @@ -1,8 +1,4 @@ -use std::{ - collections::BTreeMap, - sync::{Arc, Mutex}, - time::Duration, -}; +use std::{collections::BTreeMap, time::Duration}; use ratatui::{ prelude::*, @@ -24,36 +20,32 @@ use crate::{ components::{Component, ComponentAction}, }, }; -use rm_shared::action::Action; +use rm_shared::action::{Action, UpdateAction}; pub struct FilesPopup { ctx: app::Ctx, - torrent: Arc>>, + torrent: Option, torrent_id: Id, tree_state: TreeState, - tree: Arc>, + tree: Node, current_focus: CurrentFocus, switched_after_fetched_data: bool, } -async fn fetch_new_files( - tree: Arc>, - torrent: Arc>>, - torrent_id: Id, - ctx: app::Ctx, -) { +async fn fetch_new_files(ctx: app::Ctx, torrent_id: Id) { loop { let (torrent_tx, torrent_rx) = oneshot::channel(); ctx.send_torrent_action(TorrentAction::GetTorrentsById( vec![torrent_id.clone()], torrent_tx, )); - let new_torrent = torrent_rx.await.unwrap().pop().unwrap(); + let torrent = torrent_rx + .await + .unwrap() + .pop() + .expect("1 torrent must have been returned"); - let new_tree = Node::new_from_torrent(&new_torrent); - *torrent.lock().unwrap() = Some(new_torrent); - *tree.lock().unwrap() = new_tree; - ctx.send_action(Action::Render); + ctx.send_update_action(UpdateAction::UpdateCurrentTorrent(torrent)); tokio::time::sleep(Duration::from_secs(6)).await; } } @@ -66,21 +58,11 @@ enum CurrentFocus { impl FilesPopup { pub fn new(ctx: app::Ctx, torrent_id: Id) -> Self { - let torrent = Arc::new(Mutex::new(None)); + let torrent = None; let tree_state = TreeState::default(); - let tree = Arc::new(Mutex::new(Node::new())); + let tree = Node::new(); - ctx.send_torrent_action(TorrentAction::GetTorrentInfo( - torrent_id.clone(), - Arc::clone(&torrent), - )); - - tokio::task::spawn(fetch_new_files( - Arc::clone(&tree), - Arc::clone(&torrent), - torrent_id.clone(), - ctx.clone(), - )); + tokio::task::spawn(fetch_new_files(ctx.clone(), torrent_id.clone())); Self { ctx, @@ -113,7 +95,7 @@ impl Component for FilesPopup { } (A::Confirm, CurrentFocus::CloseButton) => return ComponentAction::Quit, (A::Select | A::Confirm, CurrentFocus::Files) => { - if let Some(torrent) = &mut *self.torrent.lock().unwrap() { + if let Some(torrent) = &mut self.torrent { let wanted_ids = torrent.wanted.as_mut().unwrap(); let selected_ids: Vec<_> = self @@ -150,9 +132,7 @@ impl Component for FilesPopup { let args = { if wanted_in_selection_no > 0 { - for transmission_file in - self.tree.lock().unwrap().get_by_ids(&selected_ids) - { + for transmission_file in self.tree.get_by_ids(&selected_ids) { transmission_file.set_wanted(false); } TorrentSetArgs { @@ -160,9 +140,7 @@ impl Component for FilesPopup { ..Default::default() } } else { - for transmission_file in - self.tree.lock().unwrap().get_by_ids(&selected_ids) - { + for transmission_file in self.tree.get_by_ids(&selected_ids) { transmission_file.set_wanted(true); } TorrentSetArgs { @@ -195,6 +173,15 @@ impl Component for FilesPopup { ComponentAction::Nothing } + fn handle_update_action(&mut self, action: UpdateAction) { + if let UpdateAction::UpdateCurrentTorrent(torrent) = action { + let new_tree = Node::new_from_torrent(&torrent); + self.torrent = Some(torrent); + self.tree = new_tree; + self.ctx.send_action(Action::Render); + } + } + fn render(&mut self, f: &mut Frame, rect: Rect) { let popup_rect = centered_rect(rect, 75, 75); let block_rect = popup_rect.inner(Margin::new(1, 0)); @@ -212,7 +199,7 @@ impl Component for FilesPopup { self.tree_state.select_first(); } - if let Some(torrent) = &*self.torrent.lock().unwrap() { + if let Some(torrent) = &self.torrent { if !self.switched_after_fetched_data { self.current_focus = CurrentFocus::Files; self.switched_after_fetched_data = true; @@ -257,8 +244,7 @@ impl Component for FilesPopup { .position(Position::Bottom), ); - let tree_lock = self.tree.lock().unwrap(); - let tree_items = tree_lock.make_tree(); + let tree_items = self.tree.make_tree(); let tree_widget = Tree::new(&tree_items) .unwrap() diff --git a/rm-main/src/ui/tabs/torrents/popups/mod.rs b/rm-main/src/ui/tabs/torrents/popups/mod.rs index 23a0621..5f37bef 100644 --- a/rm-main/src/ui/tabs/torrents/popups/mod.rs +++ b/rm-main/src/ui/tabs/torrents/popups/mod.rs @@ -1,6 +1,9 @@ use self::{files::FilesPopup, stats::StatisticsPopup}; -use crate::{app, ui::components::{Component, ComponentAction}}; -use rm_shared::action::Action; +use crate::{ + app, + ui::components::{Component, ComponentAction}, +}; +use rm_shared::action::{Action, UpdateAction}; use ratatui::prelude::*; @@ -39,7 +42,6 @@ impl PopupManager { } impl Component for PopupManager { - #[must_use] fn handle_actions(&mut self, action: Action) -> ComponentAction { if let Some(current_popup) = &mut self.current_popup { match current_popup { @@ -60,6 +62,14 @@ impl Component for PopupManager { ComponentAction::Nothing } + fn handle_update_action(&mut self, action: UpdateAction) { + if let Some(current_popup) = &mut self.current_popup { + if let CurrentPopup::Files(popup) = current_popup { + popup.handle_update_action(action); + } + } + } + fn render(&mut self, f: &mut Frame, rect: Rect) { if let Some(current_popup) = &mut self.current_popup { match current_popup { diff --git a/rm-shared/src/action.rs b/rm-shared/src/action.rs index 9e2bff0..b280667 100644 --- a/rm-shared/src/action.rs +++ b/rm-shared/src/action.rs @@ -2,7 +2,7 @@ use std::{collections::HashMap, sync::Arc}; use crossterm::event::{Event, KeyCode, KeyEvent, KeyModifiers}; use magnetease::Magnet; -use transmission_rpc::types::{FreeSpace, SessionStats}; +use transmission_rpc::types::{FreeSpace, SessionStats, Torrent}; use crate::{rustmission_torrent::RustmissionTorrent, status_task::StatusTask}; @@ -47,6 +47,7 @@ pub enum UpdateAction { SessionStats(Arc), FreeSpace(Arc), UpdateTorrents(Vec), + UpdateCurrentTorrent(Torrent), SearchFilterApply(String), SearchFilterClear, // Search Tab