mirror of
https://github.com/StarCitizenToolBox/app.git
synced 2026-02-06 15:10:20 +00:00
feat: downloader update
This commit is contained in:
@@ -27,6 +27,7 @@ static TORRENT_HANDLES: once_cell::sync::Lazy<RwLock<HashMap<usize, ManagedTorre
|
||||
once_cell::sync::Lazy::new(|| RwLock::new(HashMap::new()));
|
||||
|
||||
// Store completed tasks info (in-memory cache, cleared on restart)
|
||||
// Task IDs in cache are >= 10000 and are assigned sequentially (10000 + cache_index)
|
||||
static COMPLETED_TASKS_CACHE: once_cell::sync::Lazy<RwLock<Vec<DownloadTaskInfo>>> =
|
||||
once_cell::sync::Lazy::new(|| RwLock::new(Vec::new()));
|
||||
|
||||
@@ -369,7 +370,20 @@ pub async fn downloader_resume(task_id: usize) -> Result<()> {
|
||||
}
|
||||
|
||||
/// Remove a download task
|
||||
/// Handles both active tasks (task_id < 10000) and cached completed tasks (task_id >= 10000)
|
||||
pub async fn downloader_remove(task_id: usize, delete_files: bool) -> Result<()> {
|
||||
// Check if this is a cached completed task (ID >= 10000)
|
||||
if task_id >= 10000 {
|
||||
// Remove from completed tasks cache by index (10000 + index)
|
||||
let cache_index = task_id - 10000;
|
||||
let mut cache = COMPLETED_TASKS_CACHE.write();
|
||||
if cache_index < cache.len() {
|
||||
cache.remove(cache_index);
|
||||
}
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// Otherwise, it's an active task
|
||||
let session = get_session()?;
|
||||
|
||||
session
|
||||
@@ -454,12 +468,15 @@ fn get_task_status(stats: &TorrentStats) -> DownloadTaskStatus {
|
||||
}
|
||||
}
|
||||
|
||||
/// Get all tasks
|
||||
/// Get all tasks (includes both active and completed tasks from cache)
|
||||
pub async fn downloader_get_all_tasks() -> Result<Vec<DownloadTaskInfo>> {
|
||||
let session_guard = SESSION.read();
|
||||
let session = match session_guard.as_ref() {
|
||||
Some(s) => s.clone(),
|
||||
None => return Ok(vec![]),
|
||||
None => {
|
||||
// If session is not initialized, return only cached completed tasks
|
||||
return Ok(COMPLETED_TASKS_CACHE.read().clone());
|
||||
}
|
||||
};
|
||||
drop(session_guard);
|
||||
|
||||
@@ -516,7 +533,18 @@ pub async fn downloader_get_all_tasks() -> Result<Vec<DownloadTaskInfo>> {
|
||||
}
|
||||
});
|
||||
|
||||
Ok(tasks.into_inner())
|
||||
// Merge cached completed tasks with IDs based on cache index (10000 + index)
|
||||
let mut result = tasks.into_inner();
|
||||
let completed_tasks_cache = COMPLETED_TASKS_CACHE.read();
|
||||
|
||||
for (cache_index, task) in completed_tasks_cache.iter().enumerate() {
|
||||
let mut task_with_id = task.clone();
|
||||
// Assign ID based on cache index: 10000, 10001, 10002, etc.
|
||||
task_with_id.id = 10000 + cache_index;
|
||||
result.push(task_with_id);
|
||||
}
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
/// Get global statistics
|
||||
@@ -540,9 +568,20 @@ pub async fn downloader_get_global_stats() -> Result<DownloadGlobalStat> {
|
||||
}
|
||||
|
||||
/// Check if a task with given name exists
|
||||
pub async fn downloader_is_name_in_task(name: String) -> bool {
|
||||
///
|
||||
/// Parameters:
|
||||
/// - name: Task name to search for
|
||||
/// - downloading_only: If true, only search in active/waiting tasks. If false, include completed tasks (default: true)
|
||||
pub async fn downloader_is_name_in_task(name: String, downloading_only: Option<bool>) -> bool {
|
||||
let downloading_only = downloading_only.unwrap_or(true);
|
||||
|
||||
if let Ok(tasks) = downloader_get_all_tasks().await {
|
||||
for task in tasks {
|
||||
// If downloading_only is true, skip finished and error tasks
|
||||
if downloading_only && (task.status == DownloadTaskStatus::Finished || task.status == DownloadTaskStatus::Error) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if task.name.contains(&name) {
|
||||
return true;
|
||||
}
|
||||
@@ -640,16 +679,17 @@ pub async fn downloader_remove_completed_tasks() -> Result<u32> {
|
||||
|
||||
for task in tasks {
|
||||
if task.status == DownloadTaskStatus::Finished {
|
||||
// Check if handle exists (drop lock before await)
|
||||
let has_handle = TORRENT_HANDLES.read().contains_key(&task.id);
|
||||
if has_handle {
|
||||
// Use TorrentIdOrHash::Id for deletion (TorrentId is just usize)
|
||||
if session.delete(TorrentIdOrHash::Id(task.id), false).await.is_ok() {
|
||||
// Save task info to cache before removing
|
||||
COMPLETED_TASKS_CACHE.write().push(task.clone());
|
||||
|
||||
TORRENT_HANDLES.write().remove(&task.id);
|
||||
removed_count += 1;
|
||||
// Only process active tasks (id < 10000)
|
||||
if task.id < 10000 {
|
||||
let has_handle = TORRENT_HANDLES.read().contains_key(&task.id);
|
||||
if has_handle {
|
||||
// Use TorrentIdOrHash::Id for deletion
|
||||
if session.delete(TorrentIdOrHash::Id(task.id), false).await.is_ok() {
|
||||
// Cache the task - it will get ID based on cache length
|
||||
COMPLETED_TASKS_CACHE.write().push(task.clone());
|
||||
TORRENT_HANDLES.write().remove(&task.id);
|
||||
removed_count += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -514,6 +514,7 @@ fn wire__crate__api__downloader_api__downloader_is_initialized_impl(
|
||||
fn wire__crate__api__downloader_api__downloader_is_name_in_task_impl(
|
||||
port_: flutter_rust_bridge::for_generated::MessagePort,
|
||||
name: impl CstDecode<String>,
|
||||
downloading_only: impl CstDecode<Option<bool>>,
|
||||
) {
|
||||
FLUTTER_RUST_BRIDGE_HANDLER.wrap_async::<flutter_rust_bridge::for_generated::DcoCodec, _, _, _>(
|
||||
flutter_rust_bridge::for_generated::TaskInfo {
|
||||
@@ -523,11 +524,16 @@ fn wire__crate__api__downloader_api__downloader_is_name_in_task_impl(
|
||||
},
|
||||
move || {
|
||||
let api_name = name.cst_decode();
|
||||
let api_downloading_only = downloading_only.cst_decode();
|
||||
move |context| async move {
|
||||
transform_result_dco::<_, _, ()>(
|
||||
(move || async move {
|
||||
let output_ok = Result::<_, ()>::Ok(
|
||||
crate::api::downloader_api::downloader_is_name_in_task(api_name).await,
|
||||
crate::api::downloader_api::downloader_is_name_in_task(
|
||||
api_name,
|
||||
api_downloading_only,
|
||||
)
|
||||
.await,
|
||||
)?;
|
||||
Ok(output_ok)
|
||||
})()
|
||||
@@ -4200,8 +4206,13 @@ mod io {
|
||||
pub extern "C" fn frbgen_starcitizen_doctor_wire__crate__api__downloader_api__downloader_is_name_in_task(
|
||||
port_: i64,
|
||||
name: *mut wire_cst_list_prim_u_8_strict,
|
||||
downloading_only: *mut bool,
|
||||
) {
|
||||
wire__crate__api__downloader_api__downloader_is_name_in_task_impl(port_, name)
|
||||
wire__crate__api__downloader_api__downloader_is_name_in_task_impl(
|
||||
port_,
|
||||
name,
|
||||
downloading_only,
|
||||
)
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
|
||||
Reference in New Issue
Block a user