diff --git a/lib/common/rust/api/downloader_api.dart b/lib/common/rust/api/downloader_api.dart index 87a346e..a1a6cfd 100644 --- a/lib/common/rust/api/downloader_api.dart +++ b/lib/common/rust/api/downloader_api.dart @@ -16,7 +16,7 @@ import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart'; /// - default_download_dir: The default directory to store downloads /// - upload_limit_bps: Upload speed limit in bytes per second (0 = unlimited) /// - download_limit_bps: Download speed limit in bytes per second (0 = unlimited) -void downloaderInit({ +Future downloaderInit({ required String workingDir, required String defaultDownloadDir, int? uploadLimitBps, diff --git a/lib/common/rust/frb_generated.dart b/lib/common/rust/frb_generated.dart index 69295d4..6531c50 100644 --- a/lib/common/rust/frb_generated.dart +++ b/lib/common/rust/frb_generated.dart @@ -128,7 +128,7 @@ abstract class RustLibApi extends BaseApi { Future crateApiDownloaderApiDownloaderHasActiveTasks(); - void crateApiDownloaderApiDownloaderInit({ + Future crateApiDownloaderApiDownloaderInit({ required String workingDir, required String defaultDownloadDir, int? uploadLimitBps, @@ -743,20 +743,21 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { ); @override - void crateApiDownloaderApiDownloaderInit({ + Future crateApiDownloaderApiDownloaderInit({ required String workingDir, required String defaultDownloadDir, int? uploadLimitBps, int? downloadLimitBps, }) { - return handler.executeSync( - SyncTask( - callFfi: () { + return handler.executeNormal( + NormalTask( + callFfi: (port_) { var arg0 = cst_encode_String(workingDir); var arg1 = cst_encode_String(defaultDownloadDir); var arg2 = cst_encode_opt_box_autoadd_u_32(uploadLimitBps); var arg3 = cst_encode_opt_box_autoadd_u_32(downloadLimitBps); return wire.wire__crate__api__downloader_api__downloader_init( + port_, arg0, arg1, arg2, diff --git a/lib/common/rust/frb_generated.io.dart b/lib/common/rust/frb_generated.io.dart index 5ee8b65..5d4e1ae 100644 --- a/lib/common/rust/frb_generated.io.dart +++ b/lib/common/rust/frb_generated.io.dart @@ -1383,13 +1383,15 @@ class RustLibWire implements BaseWire { _wire__crate__api__downloader_api__downloader_has_active_tasksPtr .asFunction(); - WireSyncRust2DartDco wire__crate__api__downloader_api__downloader_init( + void wire__crate__api__downloader_api__downloader_init( + int port_, ffi.Pointer working_dir, ffi.Pointer default_download_dir, ffi.Pointer upload_limit_bps, ffi.Pointer download_limit_bps, ) { return _wire__crate__api__downloader_api__downloader_init( + port_, working_dir, default_download_dir, upload_limit_bps, @@ -1400,7 +1402,8 @@ class RustLibWire implements BaseWire { late final _wire__crate__api__downloader_api__downloader_initPtr = _lookup< ffi.NativeFunction< - WireSyncRust2DartDco Function( + ffi.Void Function( + ffi.Int64, ffi.Pointer, ffi.Pointer, ffi.Pointer, @@ -1413,7 +1416,8 @@ class RustLibWire implements BaseWire { late final _wire__crate__api__downloader_api__downloader_init = _wire__crate__api__downloader_api__downloader_initPtr .asFunction< - WireSyncRust2DartDco Function( + void Function( + int, ffi.Pointer, ffi.Pointer, ffi.Pointer, diff --git a/lib/provider/download_manager.dart b/lib/provider/download_manager.dart index 25ca104..df060ba 100644 --- a/lib/provider/download_manager.dart +++ b/lib/provider/download_manager.dart @@ -86,7 +86,7 @@ class DownloadManager extends _$DownloadManager { } // Initialize the Rust downloader with optional speed limits - downloader_api.downloaderInit( + await downloader_api.downloaderInit( workingDir: state.workingDir, defaultDownloadDir: state.downloadDir, uploadLimitBps: uploadLimitBps, diff --git a/lib/provider/download_manager.g.dart b/lib/provider/download_manager.g.dart index e729429..a27c706 100644 --- a/lib/provider/download_manager.g.dart +++ b/lib/provider/download_manager.g.dart @@ -41,7 +41,7 @@ final class DownloadManagerProvider } } -String _$downloadManagerHash() => r'f0fd818851be0d1c9e6774803aae465c33843cde'; +String _$downloadManagerHash() => r'95a8105bb544c8a1996f321e1d0258c41e18effa'; abstract class _$DownloadManager extends $Notifier { DownloadManagerState build(); diff --git a/lib/ui/home/downloader/home_downloader_ui_model.g.dart b/lib/ui/home/downloader/home_downloader_ui_model.g.dart index 062c554..65a31d9 100644 --- a/lib/ui/home/downloader/home_downloader_ui_model.g.dart +++ b/lib/ui/home/downloader/home_downloader_ui_model.g.dart @@ -42,7 +42,7 @@ final class HomeDownloaderUIModelProvider } String _$homeDownloaderUIModelHash() => - r'3dd2ca0b1c03113d577c322de81078faa378230b'; + r'567cf106d69ed24a5adb8d7f4ad9c422cf33dc1e'; abstract class _$HomeDownloaderUIModel extends $Notifier { diff --git a/rust/src/api/downloader_api.rs b/rust/src/api/downloader_api.rs index e8099d0..a25fe72 100644 --- a/rust/src/api/downloader_api.rs +++ b/rust/src/api/downloader_api.rs @@ -76,8 +76,7 @@ pub struct DownloadGlobalStat { /// - default_download_dir: The default directory to store downloads /// - upload_limit_bps: Upload speed limit in bytes per second (0 = unlimited) /// - download_limit_bps: Download speed limit in bytes per second (0 = unlimited) -#[frb(sync)] -pub fn downloader_init( +pub async fn downloader_init( working_dir: String, default_download_dir: String, upload_limit_bps: Option, @@ -88,60 +87,57 @@ pub fn downloader_init( return Ok(()); } - let rt = tokio::runtime::Handle::current(); - rt.block_on(async { - let _lock = SESSION_INIT_LOCK.lock().await; - - // Double check after acquiring lock - if SESSION.read().is_some() { - return Ok(()); - } + let _lock = SESSION_INIT_LOCK.lock().await; + + // Double check after acquiring lock + if SESSION.read().is_some() { + return Ok(()); + } - // Working directory for persistence and session data - let working_folder = PathBuf::from(&working_dir); - std::fs::create_dir_all(&working_folder)?; - - // Default download folder - let output_folder = PathBuf::from(&default_download_dir); - std::fs::create_dir_all(&output_folder)?; - - // Create persistence folder for session state in working directory - let persistence_folder = working_folder.join("rqbit-session"); - std::fs::create_dir_all(&persistence_folder)?; - - // DHT persistence file in working directory - let dht_persistence_file = working_folder.join("dht.json"); + // Working directory for persistence and session data + let working_folder = PathBuf::from(&working_dir); + std::fs::create_dir_all(&working_folder)?; + + // Default download folder + let output_folder = PathBuf::from(&default_download_dir); + std::fs::create_dir_all(&output_folder)?; + + // Create persistence folder for session state in working directory + let persistence_folder = working_folder.join("rqbit-session"); + std::fs::create_dir_all(&persistence_folder)?; + + // DHT persistence file in working directory + let dht_persistence_file = working_folder.join("dht.json"); - let session = Session::new_with_opts( - output_folder, - SessionOptions { - disable_dht: false, - disable_dht_persistence: false, - // Configure DHT persistence to use working directory - dht_config: Some(PersistentDhtConfig { - config_filename: Some(dht_persistence_file), - ..Default::default() - }), - // Enable JSON-based session persistence for task recovery - persistence: Some(SessionPersistenceConfig::Json { - folder: Some(persistence_folder), - }), - fastresume: false, - // Configure rate limits - ratelimits: LimitsConfig { - upload_bps: upload_limit_bps.and_then(NonZeroU32::new), - download_bps: download_limit_bps.and_then(NonZeroU32::new), - }, + let session = Session::new_with_opts( + output_folder, + SessionOptions { + disable_dht: false, + disable_dht_persistence: false, + // Configure DHT persistence to use working directory + dht_config: Some(PersistentDhtConfig { + config_filename: Some(dht_persistence_file), ..Default::default() + }), + // Enable JSON-based session persistence for task recovery + persistence: Some(SessionPersistenceConfig::Json { + folder: Some(persistence_folder), + }), + fastresume: false, + // Configure rate limits + ratelimits: LimitsConfig { + upload_bps: upload_limit_bps.and_then(NonZeroU32::new), + download_bps: download_limit_bps.and_then(NonZeroU32::new), }, - ) - .await - .context("Failed to create rqbit session")?; + ..Default::default() + }, + ) + .await + .context("Failed to create rqbit session")?; - *SESSION.write() = Some(session); + *SESSION.write() = Some(session); - Ok(()) - }) + Ok(()) } /// Check if the downloader is initialized diff --git a/rust/src/frb_generated.rs b/rust/src/frb_generated.rs index ffb0151..079bb9e 100644 --- a/rust/src/frb_generated.rs +++ b/rust/src/frb_generated.rs @@ -401,33 +401,38 @@ fn wire__crate__api__downloader_api__downloader_has_active_tasks_impl( ) } fn wire__crate__api__downloader_api__downloader_init_impl( + port_: flutter_rust_bridge::for_generated::MessagePort, working_dir: impl CstDecode, default_download_dir: impl CstDecode, upload_limit_bps: impl CstDecode>, download_limit_bps: impl CstDecode>, -) -> flutter_rust_bridge::for_generated::WireSyncRust2DartDco { - FLUTTER_RUST_BRIDGE_HANDLER.wrap_sync::( +) { + FLUTTER_RUST_BRIDGE_HANDLER.wrap_async::( flutter_rust_bridge::for_generated::TaskInfo { debug_name: "downloader_init", - port: None, - mode: flutter_rust_bridge::for_generated::FfiCallMode::Sync, + port: Some(port_), + mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal, }, move || { let api_working_dir = working_dir.cst_decode(); let api_default_download_dir = default_download_dir.cst_decode(); let api_upload_limit_bps = upload_limit_bps.cst_decode(); let api_download_limit_bps = download_limit_bps.cst_decode(); - transform_result_dco::<_, _, flutter_rust_bridge::for_generated::anyhow::Error>( - (move || { - let output_ok = crate::api::downloader_api::downloader_init( - api_working_dir, - api_default_download_dir, - api_upload_limit_bps, - api_download_limit_bps, - )?; - Ok(output_ok) - })(), - ) + move |context| async move { + transform_result_dco::<_, _, flutter_rust_bridge::for_generated::anyhow::Error>( + (move || async move { + let output_ok = crate::api::downloader_api::downloader_init( + api_working_dir, + api_default_download_dir, + api_upload_limit_bps, + api_download_limit_bps, + ) + .await?; + Ok(output_ok) + })() + .await, + ) + } }, ) } @@ -4093,12 +4098,14 @@ mod io { #[unsafe(no_mangle)] pub extern "C" fn frbgen_starcitizen_doctor_wire__crate__api__downloader_api__downloader_init( + port_: i64, working_dir: *mut wire_cst_list_prim_u_8_strict, default_download_dir: *mut wire_cst_list_prim_u_8_strict, upload_limit_bps: *mut u32, download_limit_bps: *mut u32, - ) -> flutter_rust_bridge::for_generated::WireSyncRust2DartDco { + ) { wire__crate__api__downloader_api__downloader_init_impl( + port_, working_dir, default_download_dir, upload_limit_bps,