diff --git a/Cargo.toml b/Cargo.toml index 921bb68..02186e2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,3 +18,4 @@ serde_json = "1.0" dirs = "4.0.0" tokio = { version = "1.19.2", features = ["rt", "rt-multi-thread", "macros"] } +wait_not_await = "0.2.1" diff --git a/anime-game-core b/anime-game-core index 527a8d1..8a0dd62 160000 --- a/anime-game-core +++ b/anime-game-core @@ -1 +1 @@ -Subproject commit 527a8d12e6e9fcea7bb696254657c937cb2e7f86 +Subproject commit 8a0dd62b38a0e1c0847a2665fe49961d4ed2a25d diff --git a/src/ui/components/wine_row.rs b/src/ui/components/wine_row.rs index 7253220..74f37ca 100644 --- a/src/ui/components/wine_row.rs +++ b/src/ui/components/wine_row.rs @@ -7,9 +7,17 @@ use gtk::Align; use std::path::Path; use anime_game_core::prelude::*; +use wait_not_await::Await; use crate::lib::wine::Version; +#[derive(Debug)] +pub enum DownloadingResult { + DownloadingError(std::io::Error), + UnpackingError, + Done +} + #[derive(Debug, Clone)] pub struct WineRow { pub version: Version, @@ -69,13 +77,15 @@ impl WineRow { /// Download wine /// /// This method doesn't update components states, so you need to call `update_state` method manually - pub fn download(&self, runners_folder: T) -> Result<(), std::io::Error> { + pub fn download(&self, runners_folder: T) -> Result, std::io::Error> { let (sender, receiver) = glib::MainContext::channel::(glib::PRIORITY_DEFAULT); let this = self.clone(); this.progress_bar.set_visible(true); this.button.set_visible(false); + let (downl_send, downl_recv) = std::sync::mpsc::channel(); + receiver.attach(None, move |state| { match state { InstallerUpdate::DownloadingStarted(_) => (), @@ -99,11 +109,17 @@ impl WineRow { InstallerUpdate::UnpackingFinished => { this.progress_bar.set_visible(false); this.button.set_visible(true); + + downl_send.send(DownloadingResult::Done); }, - // TODO: proper handling - InstallerUpdate::DownloadingError(err) => panic!("Failed to download wine: {}", err), - InstallerUpdate::UnpackingError => panic!("Failed to unpack wine") + InstallerUpdate::DownloadingError(err) => { + downl_send.send(DownloadingResult::DownloadingError(err.into())); + }, + + InstallerUpdate::UnpackingError => { + downl_send.send(DownloadingResult::UnpackingError); + } } glib::Continue(true) @@ -124,6 +140,11 @@ impl WineRow { }); }); - Ok(()) + Ok(Await::new(move || { + downl_recv.recv().unwrap() + })) } } + +unsafe impl Send for WineRow {} +unsafe impl Sync for WineRow {} diff --git a/src/ui/preferences/general_page.rs b/src/ui/preferences/general_page.rs index 375261b..4cfa207 100644 --- a/src/ui/preferences/general_page.rs +++ b/src/ui/preferences/general_page.rs @@ -241,12 +241,14 @@ impl App { Actions::DownloadWine(version) => { let config = config::get().expect("Failed to load config"); - let component = &this.widgets + let component = this.widgets .wine_components[version.0] - .version_components[version.1]; + .version_components[version.1].clone(); - if let Ok(_) = component.download(&config.game.wine.builds) { - component.update_state(&config.game.wine.builds); + if let Ok(awaiter) = component.download(&config.game.wine.builds) { + awaiter.then(move |_| { + component.update_state(&config.game.wine.builds); + }); } } }